Skip to content

Commit

Permalink
Manage all 'special' headers of #headers{} and #outh{} records
Browse files Browse the repository at this point in the history
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
Christopher Faulet committed Feb 21, 2012
1 parent 54acbb6 commit e61b0e3
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 8 deletions.
52 changes: 46 additions & 6 deletions man/yaws_api.5
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand Down
84 changes: 82 additions & 2 deletions src/yaws.erl
Expand Up @@ -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}) ->
Expand All @@ -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
Expand All @@ -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});
Expand All @@ -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
Expand All @@ -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) ->
Expand Down Expand Up @@ -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}).

Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions src/yaws_api.erl
Expand Up @@ -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;
Expand All @@ -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

]
Expand Down

0 comments on commit e61b0e3

Please sign in to comment.