diff options
author | Loïc Hoguin <[email protected]> | 2012-05-01 01:59:36 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-05-04 06:24:10 +0200 |
commit | 57fda142175a7fd0340d9030e0477c16e13dc5f5 (patch) | |
tree | a83701cdedf0a21b814fd3e78538d2473926e446 /src/cowboy_http_protocol.erl | |
parent | 7ed93fcc8f3fe42cbe22e96e3352b444c2480f74 (diff) | |
download | cowboy-57fda142175a7fd0340d9030e0477c16e13dc5f5.tar.gz cowboy-57fda142175a7fd0340d9030e0477c16e13dc5f5.tar.bz2 cowboy-57fda142175a7fd0340d9030e0477c16e13dc5f5.zip |
Add an 'onresponse' hook
This new protocol option is a fun.
It expects 3 args: the Status code used in the reply (this is the
cowboy_http:status() type, it can be an integer or a binary), the
headers that will be sent in the reply, and the Req. It should
only return a possibly modified Req. This can be used for many
things like error logging or custom error pages.
If a reply is sent inside the hook, then Cowboy will discard the
reply initially sent. Extra caution must be used in the handlers
making use of inline chunked replies as they will throw an error.
This fun cannot be used as a filter, you can either observe the
reply sent or discard it to send a different one instead.
The hook will not be called for replies sent from inside the hook.
Diffstat (limited to 'src/cowboy_http_protocol.erl')
-rw-r--r-- | src/cowboy_http_protocol.erl | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl index 816c825..9fad2d0 100644 --- a/src/cowboy_http_protocol.erl +++ b/src/cowboy_http_protocol.erl @@ -48,6 +48,8 @@ dispatch :: cowboy_dispatcher:dispatch_rules(), handler :: {module(), any()}, onrequest :: undefined | fun((#http_req{}) -> #http_req{}), + onresponse = undefined :: undefined | fun((cowboy_http:status(), + cowboy_http:headers(), #http_req{}) -> #http_req{}), urldecode :: {fun((binary(), T) -> binary()), T}, req_empty_lines = 0 :: integer(), max_empty_lines :: integer(), @@ -79,6 +81,7 @@ init(ListenerPid, Socket, Transport, Opts) -> MaxKeepalive = proplists:get_value(max_keepalive, Opts, infinity), MaxLineLength = proplists:get_value(max_line_length, Opts, 4096), OnRequest = proplists:get_value(onrequest, Opts), + OnResponse = proplists:get_value(onresponse, Opts), Timeout = proplists:get_value(timeout, Opts, 5000), URLDecDefault = {fun cowboy_http:urldecode/2, crash}, URLDec = proplists:get_value(urldecode, Opts, URLDecDefault), @@ -86,7 +89,8 @@ init(ListenerPid, Socket, Transport, Opts) -> wait_request(#state{listener=ListenerPid, socket=Socket, transport=Transport, dispatch=Dispatch, max_empty_lines=MaxEmptyLines, max_keepalive=MaxKeepalive, max_line_length=MaxLineLength, - timeout=Timeout, onrequest=OnRequest, urldecode=URLDec}). + timeout=Timeout, onrequest=OnRequest, onresponse=OnResponse, + urldecode=URLDec}). %% @private -spec parse_request(#state{}) -> ok. @@ -122,7 +126,7 @@ request({http_request, Method, {absoluteURI, _Scheme, _Host, _Port, Path}, request({http_request, Method, {abs_path, AbsPath}, Version}, State=#state{socket=Socket, transport=Transport, req_keepalive=Keepalive, max_keepalive=MaxKeepalive, - urldecode={URLDecFun, URLDecArg}=URLDec}) -> + onresponse=OnResponse, urldecode={URLDecFun, URLDecArg}=URLDec}) -> URLDecode = fun(Bin) -> URLDecFun(Bin, URLDecArg) end, {Path, RawPath, Qs} = cowboy_dispatcher:split_path(AbsPath, URLDecode), ConnAtom = if Keepalive < MaxKeepalive -> version_to_connection(Version); @@ -130,16 +134,19 @@ request({http_request, Method, {abs_path, AbsPath}, Version}, end, parse_header(#http_req{socket=Socket, transport=Transport, connection=ConnAtom, pid=self(), method=Method, version=Version, - path=Path, raw_path=RawPath, raw_qs=Qs, urldecode=URLDec}, State); + path=Path, raw_path=RawPath, raw_qs=Qs, onresponse=OnResponse, + urldecode=URLDec}, State); request({http_request, Method, '*', Version}, State=#state{socket=Socket, transport=Transport, - req_keepalive=Keepalive, max_keepalive=MaxKeepalive, urldecode=URLDec}) -> + req_keepalive=Keepalive, max_keepalive=MaxKeepalive, + onresponse=OnResponse, urldecode=URLDec}) -> ConnAtom = if Keepalive < MaxKeepalive -> version_to_connection(Version); true -> close end, parse_header(#http_req{socket=Socket, transport=Transport, connection=ConnAtom, pid=self(), method=Method, version=Version, - path='*', raw_path= <<"*">>, raw_qs= <<>>, urldecode=URLDec}, State); + path='*', raw_path= <<"*">>, raw_qs= <<>>, onresponse=OnResponse, + urldecode=URLDec}, State); request({http_request, _Method, _URI, _Version}, State) -> error_terminate(501, State); request({http_error, <<"\r\n">>}, |