summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2011-09-08 10:48:00 +0000
committerRobert Newson <rnewson@apache.org>2011-09-08 10:48:00 +0000
commit66e2af457ab3f4b3c57d890d86bf240416328392 (patch)
tree15a7e7885a2c35f0e6a71f315b188bf256fa554d
parent0fc5669ff29621ad723f984aedd75ef286ac69b3 (diff)
downloadcouchdb-66e2af457ab3f4b3c57d890d86bf240416328392.tar.gz
COUCHDB-1274 - Use text/javascript content-type for jsonp responses.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1166618 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES1
-rw-r--r--NEWS1
-rw-r--r--share/www/script/test/jsonp.js2
-rw-r--r--src/couchdb/couch_httpd.erl35
4 files changed, 26 insertions, 13 deletions
diff --git a/CHANGES b/CHANGES
index 446aff374..e371008d1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -16,6 +16,7 @@ Build System:
HTTP Interface:
* Added a native JSON parser.
+ * JSONP responses now send "text/javascript" for Content-Type.
Replicator:
diff --git a/NEWS b/NEWS
index 54ad680d4..cfc26d6ed 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ This version has not been released yet.
and configuration options.
* Futon's `Status` screen (active tasks) now displays two new task
status fields: `Started on` and `Updated on`.
+ * JSONP responses now send "text/javascript" for Content-Type.
Version 1.1.1
-------------
diff --git a/share/www/script/test/jsonp.js b/share/www/script/test/jsonp.js
index 9aba7189f..d1bca94a8 100644
--- a/share/www/script/test/jsonp.js
+++ b/share/www/script/test/jsonp.js
@@ -48,6 +48,7 @@ couchTests.jsonp = function(debug) {
// Test unchunked callbacks.
var xhr = CouchDB.request("GET", "/test_suite_db/0?callback=jsonp_no_chunk");
+ TEquals("text/javascript", xhr.getResponseHeader("Content-Type"));
T(xhr.status == 200);
jsonp_flag = 0;
eval(xhr.responseText);
@@ -70,6 +71,7 @@ couchTests.jsonp = function(debug) {
var url = "/test_suite_db/_design/test/_view/all_docs?callback=jsonp_chunk";
xhr = CouchDB.request("GET", url);
+ TEquals("text/javascript", xhr.getResponseHeader("Content-Type"));
T(xhr.status == 200);
jsonp_flag = 0;
eval(xhr.responseText);
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index ba7e3b27a..3af6b1da2 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -680,25 +680,25 @@ send_json(Req, Code, Value) ->
send_json(Req, Code, [], Value).
send_json(Req, Code, Headers, Value) ->
+ initialize_jsonp(Req),
DefaultHeaders = [
{"Content-Type", negotiate_content_type(Req)},
{"Cache-Control", "must-revalidate"}
],
- Body = [start_jsonp(Req), ?JSON_ENCODE(Value), end_jsonp(), $\n],
+ Body = [start_jsonp(), ?JSON_ENCODE(Value), end_jsonp(), $\n],
send_response(Req, Code, DefaultHeaders ++ Headers, Body).
start_json_response(Req, Code) ->
start_json_response(Req, Code, []).
start_json_response(Req, Code, Headers) ->
+ initialize_jsonp(Req),
DefaultHeaders = [
{"Content-Type", negotiate_content_type(Req)},
{"Cache-Control", "must-revalidate"}
],
- start_jsonp(Req), % Validate before starting chunked.
- %start_chunked_response(Req, Code, DefaultHeaders ++ Headers).
{ok, Resp} = start_chunked_response(Req, Code, DefaultHeaders ++ Headers),
- case start_jsonp(Req) of
+ case start_jsonp() of
[] -> ok;
Start -> send_chunk(Resp, Start)
end,
@@ -708,7 +708,7 @@ end_json_response(Resp) ->
send_chunk(Resp, end_jsonp() ++ [$\n]),
last_chunk(Resp).
-start_jsonp(Req) ->
+initialize_jsonp(Req) ->
case get(jsonp) of
undefined -> put(jsonp, qs_value(Req, "callback", no_jsonp));
_ -> ok
@@ -721,14 +721,9 @@ start_jsonp(Req) ->
% make sure jsonp is configured on (default off)
case couch_config:get("httpd", "allow_jsonp", "false") of
"true" ->
- validate_callback(CallBack),
- CallBack ++ "(";
+ validate_callback(CallBack);
_Else ->
- % this could throw an error message, but instead we just ignore the
- % jsonp parameter
- % throw({bad_request, <<"JSONP must be configured before using.">>})
- put(jsonp, no_jsonp),
- []
+ put(jsonp, no_jsonp)
end
catch
Error ->
@@ -737,6 +732,13 @@ start_jsonp(Req) ->
end
end.
+start_jsonp() ->
+ case get(jsonp) of
+ no_jsonp -> [];
+ [] -> [];
+ CallBack -> CallBack ++ "("
+ end.
+
end_jsonp() ->
case erlang:erase(jsonp) of
no_jsonp -> [];
@@ -894,7 +896,14 @@ send_chunked_error(Resp, Error) ->
send_redirect(Req, Path) ->
send_response(Req, 301, [{"Location", absolute_uri(Req, Path)}], <<>>).
-negotiate_content_type(#httpd{mochi_req=MochiReq}) ->
+negotiate_content_type(Req) ->
+ case get(jsonp) of
+ no_jsonp -> negotiate_content_type1(Req);
+ [] -> negotiate_content_type1(Req);
+ _Callback -> "text/javascript"
+ end.
+
+negotiate_content_type1(#httpd{mochi_req=MochiReq}) ->
%% Determine the appropriate Content-Type header for a JSON response
%% depending on the Accept header in the request. A request that explicitly
%% lists the correct JSON MIME type will get that type, otherwise the