Permalink
Browse files

move body-fetched-yet test to outer state from reqdata

also change record name so as to be able to make all modules
using the reqstate record recompile to see the new record def.
  • Loading branch information...
1 parent 5a68ac5 commit a9cdc3691ad6465bf3c9a95bf0c26640e71df9b6 justin@basho.com committed Dec 21, 2009
Showing with 106 additions and 101 deletions.
  1. +2 −1 include/wm_reqstate.hrl
  2. +6 −5 src/webmachine.erl
  3. +93 −90 src/webmachine_request.erl
  4. +5 −5 src/webmachine_resource.erl
View
3 include/wm_reqstate.hrl
@@ -1,9 +1,10 @@
--record(reqstate, {socket=undefined,
+-record(wm_reqstate, {socket=undefined,
metadata=dict:new(),
range=undefined,
peer=undefined,
reqdata=undefined,
bodyfetch=undefined,
+ reqbody=undefined,
log_data=undefined
}).
View
11 src/webmachine.erl
@@ -42,21 +42,22 @@ new_request(mochiweb, Request) ->
RawPath = Request:get(raw_path),
Version = Request:get(version),
Headers = Request:get(headers),
- InitState = #reqstate{socket=Socket,
+ InitState = #wm_reqstate{socket=Socket,
reqdata=wrq:create(Method,Version,RawPath,Headers)},
+
InitReq = {webmachine_request,InitState},
{Peer, ReqState} = InitReq:get_peer(),
- PeerState = ReqState#reqstate{reqdata=wrq:set_peer(Peer,
- ReqState#reqstate.reqdata)},
+ PeerState = ReqState#wm_reqstate{reqdata=wrq:set_peer(Peer,
+ ReqState#wm_reqstate.reqdata)},
LogData = #wm_log_data{start_time=now(),
method=Method,
headers=Headers,
- peer=PeerState#reqstate.peer,
+ peer=PeerState#wm_reqstate.peer,
path=RawPath,
version=Version,
response_code=404,
response_length=0},
- webmachine_request:new(PeerState#reqstate{log_data=LogData}).
+ webmachine_request:new(PeerState#wm_reqstate{log_data=LogData}).
View
183 src/webmachine_request.erl
@@ -79,18 +79,18 @@
-include_lib("include/wm_reqstate.hrl").
-include_lib("include/wm_reqdata.hrl").
--define(WMVSN, "1.5.1").
+-define(WMVSN, "1.5.2").
-define(QUIP, "that tip is the fix").
-define(IDLE_TIMEOUT, infinity).
trim_state() ->
- TrimData = (ReqState#reqstate.reqdata)#wm_reqdata{wm_state='WMSTATE'},
- webmachine_request:new(ReqState#reqstate{reqdata=TrimData}).
+ TrimData = (ReqState#wm_reqstate.reqdata)#wm_reqdata{wm_state='WMSTATE'},
+ webmachine_request:new(ReqState#wm_reqstate{reqdata=TrimData}).
get_peer() ->
- case ReqState#reqstate.peer of
+ case ReqState#wm_reqstate.peer of
undefined ->
- Socket = ReqState#reqstate.socket,
+ Socket = ReqState#wm_reqstate.socket,
Peer = case inet:peername(Socket) of
{ok, {Addr={10, _, _, _}, _Port}} ->
case get_header_value("x-forwarded-for") of
@@ -109,88 +109,88 @@ get_peer() ->
{ok, {Addr, _Port}} ->
inet_parse:ntoa(Addr)
end,
- NewReqState = ReqState#reqstate{peer=Peer},
+ NewReqState = ReqState#wm_reqstate{peer=Peer},
{Peer, NewReqState};
_ ->
- {ReqState#reqstate.peer, ReqState}
+ {ReqState#wm_reqstate.peer, ReqState}
end.
-call(socket) -> {ReqState#reqstate.socket,ReqState};
-call(get_reqdata) -> {ReqState#reqstate.reqdata, ReqState};
-call({set_reqdata, RD}) -> {ok, ReqState#reqstate{reqdata=RD}};
-call(method) -> {wrq:method(ReqState#reqstate.reqdata), ReqState};
-call(version) -> {wrq:version(ReqState#reqstate.reqdata), ReqState};
-call(raw_path) -> {wrq:raw_path(ReqState#reqstate.reqdata), ReqState};
-call(req_headers) -> {wrq:req_headers(ReqState#reqstate.reqdata), ReqState};
+call(socket) -> {ReqState#wm_reqstate.socket,ReqState};
+call(get_reqdata) -> {ReqState#wm_reqstate.reqdata, ReqState};
+call({set_reqdata, RD}) -> {ok, ReqState#wm_reqstate{reqdata=RD}};
+call(method) -> {wrq:method(ReqState#wm_reqstate.reqdata), ReqState};
+call(version) -> {wrq:version(ReqState#wm_reqstate.reqdata), ReqState};
+call(raw_path) -> {wrq:raw_path(ReqState#wm_reqstate.reqdata), ReqState};
+call(req_headers) -> {wrq:req_headers(ReqState#wm_reqstate.reqdata), ReqState};
call({req_body, MaxRecvBody}) ->
- case ReqState#reqstate.bodyfetch of
+ case ReqState#wm_reqstate.bodyfetch of
stream ->
{stream_conflict, ReqState};
- _ ->
- RD=(ReqState#reqstate.reqdata)#wm_reqdata{
+ standard ->
+ {ReqState#wm_reqstate.reqbody, ReqState};
+ undefined ->
+ RD=(ReqState#wm_reqstate.reqdata)#wm_reqdata{
max_recv_body=MaxRecvBody},
- NewReqState=ReqState#reqstate{reqdata=RD},
- case RD#wm_reqdata.req_body of
- not_fetched_yet ->
- NewBody = do_recv_body(NewReqState),
- NewRD = RD#wm_reqdata{req_body=NewBody},
- {NewBody, NewReqState#reqstate{
- bodyfetch=standard,reqdata=NewRD}};
- X ->
- {X, ReqState#reqstate{bodyfetch=standard}}
- end
+ NewReqState=ReqState#wm_reqstate{reqdata=RD},
+ NewBody = do_recv_body(NewReqState),
+ NewRD = RD#wm_reqdata{req_body=NewBody},
+ {NewBody, NewReqState#wm_reqstate{
+ bodyfetch=standard,reqdata=NewRD,reqbody=NewBody}}
end;
call({stream_req_body, MaxHunk}) ->
- case ReqState#reqstate.bodyfetch of
+ case ReqState#wm_reqstate.bodyfetch of
standard ->
{stream_conflict, ReqState};
_ ->
{recv_stream_body(ReqState, MaxHunk),
- ReqState#reqstate{bodyfetch=stream}}
+ ReqState#wm_reqstate{bodyfetch=stream}}
end;
-call(resp_headers) -> {wrq:resp_headers(ReqState#reqstate.reqdata), ReqState};
-call(resp_redirect) -> {wrq:resp_redirect(ReqState#reqstate.reqdata), ReqState};
+call(resp_headers) ->
+ {wrq:resp_headers(ReqState#wm_reqstate.reqdata), ReqState};
+call(resp_redirect) ->
+ {wrq:resp_redirect(ReqState#wm_reqstate.reqdata), ReqState};
call({get_resp_header, HdrName}) ->
Reply = mochiweb_headers:get_value(HdrName,
- wrq:resp_headers(ReqState#reqstate.reqdata)),
+ wrq:resp_headers(ReqState#wm_reqstate.reqdata)),
{Reply, ReqState};
call(get_path_info) ->
- PropList = dict:to_list(wrq:path_info(ReqState#reqstate.reqdata)),
+ PropList = dict:to_list(wrq:path_info(ReqState#wm_reqstate.reqdata)),
{PropList, ReqState};
call({get_path_info, Key}) ->
- {wrq:path_info(Key, ReqState#reqstate.reqdata), ReqState};
+ {wrq:path_info(Key, ReqState#wm_reqstate.reqdata), ReqState};
call(peer) -> get_peer();
call(range) -> get_range();
-call(response_code) -> {wrq:response_code(ReqState#reqstate.reqdata), ReqState};
-call(app_root) -> {wrq:app_root(ReqState#reqstate.reqdata), ReqState};
-call(disp_path) -> {wrq:disp_path(ReqState#reqstate.reqdata), ReqState};
-call(path) -> {wrq:path(ReqState#reqstate.reqdata), ReqState};
+call(response_code) ->
+ {wrq:response_code(ReqState#wm_reqstate.reqdata), ReqState};
+call(app_root) -> {wrq:app_root(ReqState#wm_reqstate.reqdata), ReqState};
+call(disp_path) -> {wrq:disp_path(ReqState#wm_reqstate.reqdata), ReqState};
+call(path) -> {wrq:path(ReqState#wm_reqstate.reqdata), ReqState};
call({get_req_header, K}) ->
- {wrq:get_req_header(K, ReqState#reqstate.reqdata), ReqState};
+ {wrq:get_req_header(K, ReqState#wm_reqstate.reqdata), ReqState};
call({set_response_code, Code}) ->
- {ok, ReqState#reqstate{reqdata=wrq:set_response_code(
- Code, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:set_response_code(
+ Code, ReqState#wm_reqstate.reqdata)}};
call({set_resp_header, K, V}) ->
- {ok, ReqState#reqstate{reqdata=wrq:set_resp_header(
- K, V, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_header(
+ K, V, ReqState#wm_reqstate.reqdata)}};
call({set_resp_headers, Hdrs}) ->
- {ok, ReqState#reqstate{reqdata=wrq:set_resp_headers(
- Hdrs, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_headers(
+ Hdrs, ReqState#wm_reqstate.reqdata)}};
call({remove_resp_header, K}) ->
- {ok, ReqState#reqstate{reqdata=wrq:remove_resp_header(
- K, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:remove_resp_header(
+ K, ReqState#wm_reqstate.reqdata)}};
call({merge_resp_headers, Hdrs}) ->
- {ok, ReqState#reqstate{reqdata=wrq:merge_resp_headers(
- Hdrs, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:merge_resp_headers(
+ Hdrs, ReqState#wm_reqstate.reqdata)}};
call({append_to_response_body, Data}) ->
- {ok, ReqState#reqstate{reqdata=wrq:append_to_response_body(
- Data, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:append_to_response_body(
+ Data, ReqState#wm_reqstate.reqdata)}};
call({set_disp_path, P}) ->
- {ok, ReqState#reqstate{reqdata=wrq:set_disp_path(
- P, ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:set_disp_path(
+ P, ReqState#wm_reqstate.reqdata)}};
call(do_redirect) ->
- {ok, ReqState#reqstate{reqdata=wrq:do_redirect(true,
- ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{
+ reqdata=wrq:do_redirect(true, ReqState#wm_reqstate.reqdata)}};
call({send_response, Code}) ->
{Reply, NewState} =
case Code of
@@ -199,48 +199,48 @@ call({send_response, Code}) ->
_ ->
send_response(Code)
end,
- LogData = NewState#reqstate.log_data,
+ LogData = NewState#wm_reqstate.log_data,
NewLogData = LogData#wm_log_data{finish_time=now()},
- {Reply, NewState#reqstate{log_data=NewLogData}};
-call(resp_body) -> {wrq:resp_body(ReqState#reqstate.reqdata), ReqState};
+ {Reply, NewState#wm_reqstate{log_data=NewLogData}};
+call(resp_body) -> {wrq:resp_body(ReqState#wm_reqstate.reqdata), ReqState};
call({set_resp_body, Body}) ->
- {ok, ReqState#reqstate{reqdata=wrq:set_resp_body(Body,
- ReqState#reqstate.reqdata)}};
+ {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_body(Body,
+ ReqState#wm_reqstate.reqdata)}};
call(has_resp_body) ->
- Reply = case wrq:resp_body(ReqState#reqstate.reqdata) of
+ Reply = case wrq:resp_body(ReqState#wm_reqstate.reqdata) of
undefined -> false;
<<>> -> false;
[] -> false;
_ -> true
end,
{Reply, ReqState};
call({get_metadata, Key}) ->
- Reply = case dict:find(Key, ReqState#reqstate.metadata) of
+ Reply = case dict:find(Key, ReqState#wm_reqstate.metadata) of
{ok, Value} -> Value;
error -> undefined
end,
{Reply, ReqState};
call({set_metadata, Key, Value}) ->
- NewDict = dict:store(Key, Value, ReqState#reqstate.metadata),
- {ok, ReqState#reqstate{metadata=NewDict}};
-call(path_tokens) -> {wrq:path_tokens(ReqState#reqstate.reqdata), ReqState};
-call(req_cookie) -> {wrq:req_cookie(ReqState#reqstate.reqdata), ReqState};
-call(req_qs) -> {wrq:req_qs(ReqState#reqstate.reqdata), ReqState};
+ NewDict = dict:store(Key, Value, ReqState#wm_reqstate.metadata),
+ {ok, ReqState#wm_reqstate{metadata=NewDict}};
+call(path_tokens) -> {wrq:path_tokens(ReqState#wm_reqstate.reqdata), ReqState};
+call(req_cookie) -> {wrq:req_cookie(ReqState#wm_reqstate.reqdata), ReqState};
+call(req_qs) -> {wrq:req_qs(ReqState#wm_reqstate.reqdata), ReqState};
call({load_dispatch_data, PathProps, HostTokens, Port,
PathTokens, AppRoot, DispPath}) ->
PathInfo = dict:from_list(PathProps),
- NewState = ReqState#reqstate{reqdata=wrq:load_dispatch_data(
+ NewState = ReqState#wm_reqstate{reqdata=wrq:load_dispatch_data(
PathInfo,HostTokens,Port,PathTokens,AppRoot,
- DispPath,ReqState#reqstate.reqdata)},
+ DispPath,ReqState#wm_reqstate.reqdata)},
{ok, NewState};
-call(log_data) -> {ReqState#reqstate.log_data, ReqState}.
+call(log_data) -> {ReqState#wm_reqstate.log_data, ReqState}.
get_header_value(K) ->
- {wrq:get_req_header(K, ReqState#reqstate.reqdata), ReqState}.
+ {wrq:get_req_header(K, ReqState#wm_reqstate.reqdata), ReqState}.
get_outheader_value(K) ->
{mochiweb_headers:get_value(K,
- wrq:resp_headers(ReqState#reqstate.reqdata)), ReqState}.
+ wrq:resp_headers(ReqState#wm_reqstate.reqdata)), ReqState}.
send(Socket, Data) ->
case gen_tcp:send(Socket, iolist_to_binary(Data)) of
@@ -285,7 +285,7 @@ send_chunk(Socket, Data) ->
Size.
send_ok_response() ->
- RD0 = ReqState#reqstate.reqdata,
+ RD0 = ReqState#wm_reqstate.reqdata,
{Range, State} = get_range(),
case Range of
X when X =:= undefined; X =:= fail ->
@@ -302,20 +302,20 @@ send_ok_response() ->
[{"Accept-Ranges", "bytes"} | RangeHeaders], RD0),
RespBodyRD = wrq:set_resp_body(
RangeBody, RespHdrsRD),
- NewState = State#reqstate{reqdata=RespBodyRD},
+ NewState = State#wm_reqstate{reqdata=RespBodyRD},
send_response(206, NewState)
end
end.
send_response(Code) -> send_response(Code,ReqState).
-send_response(Code, PassedState=#reqstate{reqdata=RD}) ->
+send_response(Code, PassedState=#wm_reqstate{reqdata=RD}) ->
Body0 = wrq:resp_body(RD),
{Body,Length} = case Body0 of
{stream, StreamBody} -> {{stream, StreamBody}, chunked};
{writer, WriteBody} -> {{writer, WriteBody}, chunked};
_ -> {Body0, iolist_size([Body0])}
end,
- send(PassedState#reqstate.socket,
+ send(PassedState#wm_reqstate.socket,
[make_version(wrq:version(RD)),
make_code(Code), <<"\r\n">> |
make_headers(Code, Length, RD)]),
@@ -324,18 +324,18 @@ send_response(Code, PassedState=#reqstate{reqdata=RD}) ->
_ ->
case Body of
{stream, Body2} ->
- send_stream_body(PassedState#reqstate.socket, Body2);
+ send_stream_body(PassedState#wm_reqstate.socket, Body2);
{writer, Body2} ->
- send_writer_body(PassedState#reqstate.socket, Body2);
+ send_writer_body(PassedState#wm_reqstate.socket, Body2);
_ ->
- send(PassedState#reqstate.socket, Body),
+ send(PassedState#wm_reqstate.socket, Body),
Length
end
end,
- InitLogData = PassedState#reqstate.log_data,
+ InitLogData = PassedState#wm_reqstate.log_data,
FinalLogData = InitLogData#wm_log_data{response_code=Code,
response_length=FinalLength},
- {ok, PassedState#reqstate{reqdata=wrq:set_response_code(Code, RD),
+ {ok, PassedState#wm_reqstate{reqdata=wrq:set_response_code(Code, RD),
log_data=FinalLogData}}.
%% @doc Infer body length from transfer-encoding and content-length headers.
@@ -352,7 +352,7 @@ body_length() ->
%% @doc Receive the body of the HTTP request (defined by Content-Length).
%% Will only receive up to the default max-body length
-do_recv_body(PassedState=#reqstate{reqdata=RD}) ->
+do_recv_body(PassedState=#wm_reqstate{reqdata=RD}) ->
MRB = RD#wm_reqdata.max_recv_body,
read_whole_stream(recv_stream_body(PassedState, MRB), [], MRB, 0).
@@ -372,10 +372,10 @@ read_whole_stream({Hunk,Next}, Acc0, MaxRecvBody, SizeAcc) ->
end
end.
-recv_stream_body(PassedState=#reqstate{reqdata=RD}, MaxHunkSize) ->
+recv_stream_body(PassedState=#wm_reqstate{reqdata=RD}, MaxHunkSize) ->
case get_header_value("expect") of
{"100-continue", _} ->
- send(PassedState#reqstate.socket,
+ send(PassedState#wm_reqstate.socket,
[make_version(wrq:version(RD)),
make_code(100), <<"\r\n">>]);
_Else ->
@@ -385,9 +385,10 @@ recv_stream_body(PassedState=#reqstate{reqdata=RD}, MaxHunkSize) ->
{unknown_transfer_encoding, X} -> exit({unknown_transfer_encoding, X});
undefined -> {<<>>, done};
0 -> {<<>>, done};
- chunked -> recv_chunked_body(PassedState#reqstate.socket, MaxHunkSize);
- Length -> recv_unchunked_body(PassedState#reqstate.socket,
- MaxHunkSize, Length)
+ chunked -> recv_chunked_body(PassedState#wm_reqstate.socket,
+ MaxHunkSize);
+ Length -> recv_unchunked_body(PassedState#wm_reqstate.socket,
+ MaxHunkSize, Length)
end.
recv_unchunked_body(Socket, MaxHunk, DataLeft) ->
@@ -442,10 +443,10 @@ read_chunk_length(Socket) ->
get_range() ->
case get_header_value("range") of
{undefined, _} ->
- {undefined, ReqState#reqstate{range=undefined}};
+ {undefined, ReqState#wm_reqstate{range=undefined}};
{RawRange, _} ->
Range = parse_range_request(RawRange),
- {Range, ReqState#reqstate{range=Range}}
+ {Range, ReqState#wm_reqstate{range=Range}}
end.
range_parts(_RD=#wm_reqdata{resp_body={file, IoDevice}}, Ranges) ->
@@ -479,7 +480,9 @@ range_parts(_RD=#wm_reqdata{resp_body=Body0}, Ranges) ->
invalid_range ->
Acc;
{Skip, Length} ->
- <<_:Skip/binary, PartialBody:Length/binary, _/binary>> = Body,
+ <<_:Skip/binary,
+ PartialBody:Length/binary,
+ _/binary>> = Body,
[{Skip, Skip + Length - 1, PartialBody} | Acc]
end
end,
View
10 src/webmachine_resource.erl
@@ -121,14 +121,14 @@ do(Fun, ReqProps) when is_atom(Fun) andalso is_list(ReqProps) ->
RState0 = proplists:get_value(reqstate, ReqProps),
put(tmp_reqstate, empty),
{Reply, ReqData, NewModState} = handle_wm_call(Fun,
- (RState0#reqstate.reqdata)#wm_reqdata{wm_state=RState0}),
+ (RState0#wm_reqstate.reqdata)#wm_reqdata{wm_state=RState0}),
ReqState = case get(tmp_reqstate) of
empty -> RState0;
X -> X
end,
{Reply,
webmachine_resource:new(R_Mod, NewModState, R_ModExports, R_Trace),
- ReqState#reqstate{reqdata=ReqData}}.
+ ReqState#wm_reqstate{reqdata=ReqData}}.
handle_wm_call(Fun, ReqData) ->
case default(Fun) of
@@ -150,7 +150,7 @@ handle_wm_call(Fun, ReqData) ->
end.
trim_trace([{M,F,[RD = #wm_reqdata{},S]}|STRest]) ->
- TrimState = (RD#wm_reqdata.wm_state)#reqstate{reqdata='REQDATA'},
+ TrimState = (RD#wm_reqdata.wm_state)#wm_reqstate{reqdata='REQDATA'},
TrimRD = RD#wm_reqdata{wm_state=TrimState},
[{M,F,[TrimRD,S]}|STRest];
trim_trace(X) -> X.
@@ -197,10 +197,10 @@ escape_trace_data(Port) when is_port(Port) ->
{'WMTRACE_ESCAPED_PORT', erlang:port_to_list(Port)};
escape_trace_data(List) when is_list(List) ->
escape_trace_list(List, []);
-escape_trace_data(R=#reqstate{}) ->
+escape_trace_data(R=#wm_reqstate{}) ->
list_to_tuple(
escape_trace_data(
- tuple_to_list(R#reqstate{reqdata='WMTRACE_NESTED_REQDATA'})));
+ tuple_to_list(R#wm_reqstate{reqdata='WMTRACE_NESTED_REQDATA'})));
escape_trace_data(Tuple) when is_tuple(Tuple) ->
list_to_tuple(escape_trace_data(tuple_to_list(Tuple)));
escape_trace_data(Other) ->

0 comments on commit a9cdc36

Please sign in to comment.