Author: rnewson Date: Thu Sep 8 11:13:21 2011 New Revision: 1166627 URL: http://svn.apache.org/viewvc?rev=1166627&view=rev Log: COUCHDB-1274 - Use text/javascript content-type for jsonp responses.
Backported from trunk @1166618 Modified: couchdb/branches/1.1.x/CHANGES couchdb/branches/1.1.x/NEWS couchdb/branches/1.1.x/share/www/script/test/jsonp.js couchdb/branches/1.1.x/src/couchdb/couch_httpd.erl Modified: couchdb/branches/1.1.x/CHANGES URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/CHANGES?rev=1166627&r1=1166626&r2=1166627&view=diff ============================================================================== --- couchdb/branches/1.1.x/CHANGES (original) +++ couchdb/branches/1.1.x/CHANGES Thu Sep 8 11:13:21 2011 @@ -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 ------------- Modified: couchdb/branches/1.1.x/NEWS URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/NEWS?rev=1166627&r1=1166626&r2=1166627&view=diff ============================================================================== --- couchdb/branches/1.1.x/NEWS (original) +++ couchdb/branches/1.1.x/NEWS Thu Sep 8 11:13:21 2011 @@ -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 ------------- Modified: couchdb/branches/1.1.x/share/www/script/test/jsonp.js URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/share/www/script/test/jsonp.js?rev=1166627&r1=1166626&r2=1166627&view=diff ============================================================================== --- couchdb/branches/1.1.x/share/www/script/test/jsonp.js (original) +++ couchdb/branches/1.1.x/share/www/script/test/jsonp.js Thu Sep 8 11:13:21 2011 @@ -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); Modified: couchdb/branches/1.1.x/src/couchdb/couch_httpd.erl URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/couch_httpd.erl?rev=1166627&r1=1166626&r2=1166627&view=diff ============================================================================== --- couchdb/branches/1.1.x/src/couchdb/couch_httpd.erl (original) +++ couchdb/branches/1.1.x/src/couchdb/couch_httpd.erl Thu Sep 8 11:13:21 2011 @@ -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