Allow whitespace in Range headers While investigating basho/webmachine#186 it was noted that a small but non-zero percentage of clients embed whitespace in Range headers. It appears this is valid:
>From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) >From http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2 #rule ...separated by one or more commas (",") and OPTIONAL linear white space (LWS)... ...null elements are allowed, but do not contribute to the count of elements present. That is, "(element), , (element) " is permitted, but counts as only two elements... Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/176ddce1 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/176ddce1 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/176ddce1 Branch: refs/heads/1843-feature-bigcouch Commit: 176ddce1590f91748f84b8014966bac8acea5e13 Parents: 7a7cefa Author: Nathan Parry <[email protected]> Authored: Wed Feb 5 23:22:02 2014 -0500 Committer: Nathan Parry <[email protected]> Committed: Wed Feb 5 23:26:49 2014 -0500 ---------------------------------------------------------------------- src/mochiweb_http.erl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/176ddce1/src/mochiweb_http.erl ---------------------------------------------------------------------- diff --git a/src/mochiweb_http.erl b/src/mochiweb_http.erl index 8c814cb..38d51d4 100644 --- a/src/mochiweb_http.erl +++ b/src/mochiweb_http.erl @@ -158,7 +158,8 @@ parse_range_request("bytes=0-") -> parse_range_request(RawRange) when is_list(RawRange) -> try "bytes=" ++ RangeString = RawRange, - Ranges = string:tokens(RangeString, ","), + RangeTokens = [string:strip(R) || R <- string:tokens(RangeString, ",")], + Ranges = [R || R <- RangeTokens, string:len(R) > 0], lists:map(fun ("-" ++ V) -> {none, list_to_integer(V)}; (R) -> @@ -221,6 +222,19 @@ range_test() -> [{20, none}, {50, 100}, {none, 200}], parse_range_request("bytes=20-,50-100,-200")), + %% valid, multiple range with whitespace + ?assertEqual( + [{20, 30}, {50, 100}, {110, 200}], + parse_range_request("bytes=20-30, 50-100 , 110-200")), + + %% valid, multiple range with extra commas + ?assertEqual( + [{20, 30}, {50, 100}, {110, 200}], + parse_range_request("bytes=20-30,,50-100,110-200")), + ?assertEqual( + [{20, 30}, {50, 100}, {110, 200}], + parse_range_request("bytes=20-30, ,50-100,,,110-200")), + %% no ranges ?assertEqual([], parse_range_request("bytes=")), ok.
