Permalink
Browse files

Manage all 'special' headers of #headers{} and #outh{} records

Some headers, like 'Content-Encoding' or 'Transfer-Encoding' were
not correctly handled. These changes can be useful for everyone who
writes yaws scripts or appmods. In particular, the next version of
the reverse proxy depends on it.
  • Loading branch information...
1 parent 54acbb6 commit e61b0e36de05f6fed631fbfda95531354ad63b8b @capflam capflam committed Feb 21, 2012
Showing with 138 additions and 8 deletions.
  1. +46 −6 man/yaws_api.5
  2. +82 −2 src/yaws.erl
  3. +10 −0 src/yaws_api.erl
View
52 man/yaws_api.5
@@ -652,10 +652,15 @@ The following list of headers are given special treatment.
\fI{connection, What}\fR
-This sets the connection header. If \fIWhat\fR is the special value
+This sets the Connection: header. If \fIWhat\fR is the special value
\fI"close"\fR, the connection will be closed once the yaws page is delivered
to the client.
+\fI{server, What}\fR
+
+Sets the Server: header. By setting this header, the server's signature will be
+dynamically overloaded.
+
\fI{location, Url}\fR
Sets the Location: header. This header is typically combined with
@@ -665,14 +670,43 @@ the \fI{status, 302}\fR return value.
Sets the Cache-Control: header.
+\fI{expires, What}\fR
+
+Sets the Expires: header.
+
+\fI{date, What}\fR
+
+Sets the Date: header.
+
+\fI{allow, What}\fR
+
+Sets the Allow: header.
+
+\fI{last_modified, What}\fR
+
+Sets the Last-Modified: header.
+
+\fI{etag, What}\fR
+
+Sets the Etag: header.
+
\fI{set_cookie, Cookie}\fR
-Prepends a a Set-Cookie: header to the list of previously
+Prepends a Set-Cookie: header to the list of previously
set Set-Cookie: headers.
+\fI{content_range, What}\fR
+
+Sets the Content-Range: header.
+
\fI{content_type, MimeType}\fR
-Sets the Content-Type header.
+Sets the Content-Type: header.
+
+\fI{content_encoding, What}\fR
+
+Sets the Content-Encoding: header. If this header is defined, no deflate is
+performed by Yaws. So you can compress data by yourself.
\fI{content_length, Len}\fR
@@ -682,13 +716,19 @@ some reason want to force a Content-Length: header (and we actually do
know the length of the content, we can force yaws to not ship the
page chunked.
+\fI{transfer_encoding, What}\fR
-All other headers must be added using the normal HTTP syntax.
-Example:
+Sets the Transfer-Encoding: header.
+
+\fI{www_authenticate, What}\fR
+
+Sets the WWW-Authenticate: header.
-{header, "My-X-Header: gadong"}
+All other headers must be added using the normal HTTP syntax.
+Example:
+\fI{header, {"My-X-Header", "gadong"}}\fR of \fI{header, "My-X-Header: gadong"}\fR
.TP
View
84 src/yaws.erl
@@ -1623,6 +1623,11 @@ accumulate_header({connection, What}) ->
accumulate_header({"Connection", What}) ->
accumulate_header({connection, What});
+accumulate_header({server, What}) ->
+ put(outh, (get(outh))#outh{server = ["Server: " , What, "\r\n"]});
+accumulate_header({"Server", What}) ->
+ accumulate_header({server, What});
+
accumulate_header({location, What}) ->
put(outh, (get(outh))#outh{location = ["Location: " , What, "\r\n"]});
accumulate_header({"Location", What}) ->
@@ -1634,6 +1639,32 @@ accumulate_header({cache_control, What}) ->
accumulate_header({"Cache-Control", What}) ->
accumulate_header({cache_control, What});
+accumulate_header({expires, What}) ->
+ put(outh, (get(outh))#outh{expires = ["Expires: " , What, "\r\n"]});
+accumulate_header({"Expires", What}) ->
+ accumulate_header({expires, What});
+
+accumulate_header({date, What}) ->
+ put(outh, (get(outh))#outh{date = ["Date: " , What, "\r\n"]});
+accumulate_header({"Date", What}) ->
+ accumulate_header({date, What});
+
+accumulate_header({allow, What}) ->
+ put(outh, (get(outh))#outh{date = ["Allow: " , What, "\r\n"]});
+accumulate_header({"Allow", What}) ->
+ accumulate_header({allow, What});
+
+accumulate_header({last_modified, What}) ->
+ put(outh, (get(outh))#outh{last_modified =
+ ["Last-Modified: " , What, "\r\n"]});
+accumulate_header({"Last-Modified", What}) ->
+ accumulate_header({last_modified, What});
+
+accumulate_header({etag, What}) ->
+ put(outh, (get(outh))#outh{etag = ["Etag: " , What, "\r\n"]});
+accumulate_header({"Etag", What}) ->
+ accumulate_header({etag, What});
+
accumulate_header({set_cookie, What}) ->
O = get(outh),
Old = case O#outh.set_cookie of
@@ -1644,14 +1675,21 @@ accumulate_header({set_cookie, What}) ->
accumulate_header({"Set-Cookie", What}) ->
accumulate_header({set_cookie, What});
+accumulate_header({content_range, What}) ->
+ put(outh, (get(outh))#outh{content_range =
+ ["Content-Range: " , What, "\r\n"]});
+accumulate_header({"Content-Range", What}) ->
+ accumulate_header({content_range, What});
+
accumulate_header({content_type, What}) ->
put(outh, (get(outh))#outh{content_type = ["Content-Type: " ,
What, "\r\n"]});
accumulate_header({"Content-Type", What}) ->
accumulate_header({content_type, What});
accumulate_header({content_encoding, What}) ->
- put(outh, (get(outh))#outh{content_encoding =
+ put(outh, (get(outh))#outh{encoding = deflate,
+ content_encoding =
["Content-Encoding: " , What, "\r\n"]});
accumulate_header({"Content-Encoding", What}) ->
accumulate_header({content_encoding, What});
@@ -1662,6 +1700,7 @@ accumulate_header({content_length, Len}) when is_integer(Len) ->
chunked = false,
transfer_encoding = undefined,
contlen = Len,
+ act_contlen = 0,
content_length = make_content_length_header(Len)});
accumulate_header({"Content-Length", Len}) ->
case Len of
@@ -1671,6 +1710,20 @@ accumulate_header({"Content-Length", Len}) ->
accumulate_header({content_length, list_to_integer(L)})
end;
+accumulate_header({transfer_encoding, What}) ->
+ put(outh, (get(outh))#outh{chunked = true,
+ contlen = 0,
+ transfer_encoding =
+ ["Transfer-Encoding: " , What, "\r\n"]});
+accumulate_header({"Transfer-Encoding", What}) ->
+ accumulate_header({transfer_encoding, What});
+
+accumulate_header({www_authenticate, What}) ->
+ put(outh, (get(outh))#outh{www_authenticate =
+ ["WWW-Authenticate: " , What, "\r\n"]});
+accumulate_header({"WWW-Authenticate", What}) ->
+ accumulate_header({"WWW-Authenticate", What});
+
%% non-special headers (which may be special in a future Yaws version)
accumulate_header({Name, What}) when is_list(Name) ->
@@ -1705,14 +1758,38 @@ split_header([C|S], A) ->
erase_header(connection) ->
put(outh, (get(outh))#outh{connection = undefined, doclose = false});
+erase_header(server) ->
+ put(outh, (get(outh))#outh{server = undefined});
erase_header(cache_control) ->
put(outh, (get(outh))#outh{cache_control = undefined});
+erase_header(expires) ->
+ put(outh, (get(outh))#outh{expires = undefined});
+erase_header(date) ->
+ put(outh, (get(outh))#outh{date = undefined});
+erase_header(allow) ->
+ put(outh, (get(outh))#outh{allow = undefined});
+erase_header(last_modified) ->
+ put(outh, (get(outh))#outh{last_modified = undefined});
+erase_header(etag) ->
+ put(outh, (get(outh))#outh{etag = undefined});
erase_header(set_cookie) ->
put(outh, (get(outh))#outh{set_cookie = undefined});
+erase_header(content_range) ->
+ put(outh, (get(outh))#outh{content_range = undefined});
+erase_header(content_length) ->
+ put(outh, (get(outh))#outh{contlen = 0,
+ content_length = undefined});
erase_header(content_type) ->
put(outh, (get(outh))#outh{content_type = undefined});
erase_header(content_encoding) ->
- put(outh, (get(outh))#outh{content_encoding = undefined});
+ put(outh, (get(outh))#outh{encoding = identity,
+ content_encoding = undefined});
+erase_header(transfer_encoding) ->
+ put(outh, (get(outh))#outh{chunked = false,
+ act_contlen = 0,
+ transfer_encoding = undefined});
+erase_header(www_authenticate) ->
+ put(outh, (get(outh))#outh{www_authenticate = undefined});
erase_header(location) ->
put(outh, (get(outh))#outh{location = undefined}).
@@ -1988,6 +2065,9 @@ http_collect_headers(CliSock, Req, H, SSL, Count) when Count < 1000 ->
{ok, {http_header, _Num, 'Content-Type', _, X}} ->
http_collect_headers(CliSock, Req,
H#headers{content_type = X},SSL, Count+1);
+ {ok, {http_header, _Num, 'Content-Encoding', _, X}} ->
+ http_collect_headers(CliSock, Req,
+ H#headers{content_encoding = X},SSL, Count+1);
{ok, {http_header, _Num, 'Transfer-Encoding', _, X}} ->
http_collect_headers(CliSock, Req,
H#headers{transfer_encoding=X},SSL, Count+1);
View
10 src/yaws_api.erl
@@ -1148,6 +1148,11 @@ reformat_header(H) ->
true ->
{"Content-Type", H#headers.content_type}
end,
+ if H#headers.content_encoding == undefined ->
+ undefined;
+ true ->
+ {"Content-Encoding", H#headers.content_encoding}
+ end,
if H#headers.authorization == undefined ->
undefined;
@@ -1163,6 +1168,11 @@ reformat_header(H) ->
undefined;
true ->
{"Location", H#headers.location}
+ end,
+ if H#headers.x_forwarded_for == undefined ->
+ undefined;
+ true ->
+ {"X-Forwarded-For", H#headers.x_forwarded_for}
end
]

0 comments on commit e61b0e3

Please sign in to comment.