summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2011-09-08 11:13:21 +0000
committerRobert Newson <rnewson@apache.org>2011-09-08 11:13:21 +0000
commit9d0a0a52379f019deb2e479d9d5d87fe72cc98f5 (patch)
treef484578928031af2cd348b0a033a8990df8ba3a2
parent860be768c957b0f6954921cd25a9b8465da8617b (diff)
COUCHDB-1274 - Use text/javascript content-type for jsonp responses.
Backported from trunk @1166618 git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1166627 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 12efc0b3..64b4f3c1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,7 @@ Version 1.1.1
This version has not been released yet.
* ETags for views include current sequence if include_docs=true.
+* JSONP responses now send "text/javascript" for Content-Type.
Version 1.1.0
-------------
diff --git a/NEWS b/NEWS
index 4803ba24..d7dc7cf1 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Version 1.1.1
This version has not been released yet.
* ETags for views include current sequence if include_docs=true.
+* JSONP responses now send "text/javascript" for Content-Type.
Version 1.1.0
-------------
diff --git a/share/www/script/test/jsonp.js b/share/www/script/test/jsonp.js
index 9aba7189..d1bca94a 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 e472d094..15b85df8 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -627,25 +627,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,
@@ -655,7 +655,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
@@ -668,14 +668,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 ->
@@ -684,6 +679,13 @@ start_jsonp(Req) ->
end
end.
+start_jsonp() ->
+ case get(jsonp) of
+ no_jsonp -> [];
+ [] -> [];
+ CallBack -> CallBack ++ "("
+ end.
+
end_jsonp() ->
Resp = case get(jsonp) of
no_jsonp -> [];
@@ -844,7 +846,14 @@ send_redirect(Req, Path) ->
Headers = [{"Location", couch_httpd:absolute_uri(Req, Path)}],
send_response(Req, 301, Headers, <<>>).
-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