diff options
author | Stavros Aronis <[email protected]> | 2011-04-02 18:57:42 +0300 |
---|---|---|
committer | Henrik Nord <[email protected]> | 2011-05-04 15:06:15 +0200 |
commit | ca4633fd683527097451ca1398c90c87bb5c14fc (patch) | |
tree | 3d8e18c9becd4feb7d3ceb1eed24bdce2ef69dd6 /lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl | |
parent | bc619f0cbf9555df6dfc44a499f0cd9cee8bd1be (diff) | |
download | otp-ca4633fd683527097451ca1398c90c87bb5c14fc.tar.gz otp-ca4633fd683527097451ca1398c90c87bb5c14fc.tar.bz2 otp-ca4633fd683527097451ca1398c90c87bb5c14fc.zip |
Rename suite data directories
Diffstat (limited to 'lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl')
-rw-r--r-- | lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl | 724 |
1 files changed, 0 insertions, 724 deletions
diff --git a/lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl b/lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl deleted file mode 100644 index 5076a12aaa..0000000000 --- a/lib/dialyzer/test/r9c_tests_SUITE_data/src/inets/httpc_handler.erl +++ /dev/null @@ -1,724 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Mobile Arts AB -%% Portions created by Mobile Arts are Copyright 2002, Mobile Arts AB -%% All Rights Reserved.'' -%% -%% - -%%% TODO: -%%% - If an error is returned when sending a request, don't use this -%%% session anymore. -%%% - Closing of sessions not properly implemented for some cases - -%%% File : httpc_handler.erl -%%% Author : Johan Blom <[email protected]> -%%% Description : Handles HTTP client responses, for a single TCP session -%%% Created : 4 Mar 2002 by Johan Blom - --module(httpc_handler). - --include("http.hrl"). --include("jnets_httpd.hrl"). - --export([init_connection/2,http_request/2]). - -%%% ========================================================================== -%%% "Main" function in the spawned process for the session. -init_connection(Req,Session) when record(Req,request) -> - case catch http_lib:connect(Req) of - {ok,Socket} -> - case catch http_request(Req,Socket) of - ok -> - case Session#session.clientclose of - true -> - ok; - false -> - httpc_manager:register_socket(Req#request.address, - Session#session.id, - Socket) - end, - next_response_with_request(Req, - Session#session{socket=Socket}); - {error,Reason} -> % Not possible to use new session - gen_server:cast(Req#request.from, - {Req#request.ref,Req#request.id,{error,Reason}}), - exit_session_ok(Req#request.address, - Session#session{socket=Socket}) - end; - {error,Reason} -> % Not possible to set up new session - gen_server:cast(Req#request.from, - {Req#request.ref,Req#request.id,{error,Reason}}), - exit_session_ok2(Req#request.address, - Session#session.clientclose,Session#session.id) - end. - -next_response_with_request(Req,Session) -> - Timeout=(Req#request.settings)#client_settings.timeout, - case catch read(Timeout,Session#session.scheme,Session#session.socket) of - {Status,Headers,Body} -> - NewReq=handle_response({Status,Headers,Body},Timeout,Req,Session), - next_response_with_request(NewReq,Session); - {error,Reason} -> - gen_server:cast(Req#request.from, - {Req#request.ref,Req#request.id,{error,Reason}}), - exit_session(Req#request.address,Session,aborted_request); - {'EXIT',Reason} -> - gen_server:cast(Req#request.from, - {Req#request.ref,Req#request.id,{error,Reason}}), - exit_session(Req#request.address,Session,aborted_request) - end. - -handle_response(Response,Timeout,Req,Session) -> - case http_response(Response,Req,Session) of - ok -> - next_response(Timeout,Req#request.address,Session); - stop -> - exit(normal); - {error,Reason} -> - gen_server:cast(Req#request.from, - {Req#request.ref,Req#request.id,{error,Reason}}), - exit_session(Req#request.address,Session,aborted_request) - end. - - - -%%% Wait for the next respond until -%%% - session is closed by the other side -%%% => set up a new a session, if there are pending requests in the que -%%% - "Connection:close" header is received -%%% => close the connection (release socket) then -%%% set up a new a session, if there are pending requests in the que -%%% -%%% Note: -%%% - When invoked there are no pending responses on received requests. -%%% - Never close the session explicitly, let it timeout instead! -next_response(Timeout,Address,Session) -> - case httpc_manager:next_request(Address,Session#session.id) of - no_more_requests -> - %% There are no more pending responses, now just wait for - %% timeout or a new response. - case catch read(Timeout, - Session#session.scheme,Session#session.socket) of - {error,Reason} when Reason==session_remotely_closed; - Reason==session_local_timeout -> - exit_session_ok(Address,Session); - {error,Reason} -> - exit_session(Address,Session,aborted_request); - {'EXIT',Reason} -> - exit_session(Address,Session,aborted_request); - {Status2,Headers2,Body2} -> - case httpc_manager:next_request(Address, - Session#session.id) of - no_more_requests -> % Should not happen! - exit_session(Address,Session,aborted_request); - {error,Reason} -> % Should not happen! - exit_session(Address,Session,aborted_request); - NewReq -> - handle_response({Status2,Headers2,Body2}, - Timeout,NewReq,Session) - end - end; - {error,Reason} -> % The connection has been closed by httpc_manager - exit_session(Address,Session,aborted_request); - NewReq -> - NewReq - end. - -%% =========================================================================== -%% Internals - -%%% Read in and parse response data from the socket -read(Timeout,SockType,Socket) -> - Info=#response{scheme=SockType,socket=Socket}, - http_lib:setopts(SockType,Socket,[{packet, http}]), - Info1=read_response(SockType,Socket,Info,Timeout), - http_lib:setopts(SockType,Socket,[binary,{packet, raw}]), - case (Info1#response.headers)#res_headers.content_type of - "multipart/byteranges"++Param -> - range_response_body(Info1,Timeout,Param); - _ -> - #response{status=Status2,headers=Headers2,body=Body2}= - http_lib:read_client_body(Info1,Timeout), - {Status2,Headers2,Body2} - end. - - -%%% From RFC 2616: -%%% Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF -%%% HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT -%%% Status-Code = 3DIGIT -%%% Reason-Phrase = *<TEXT, excluding CR, LF> -read_response(SockType,Socket,Info,Timeout) -> - case http_lib:recv0(SockType,Socket,Timeout) of - {ok,{http_response,{1,VerMin}, Status, _Phrase}} when VerMin==0; - VerMin==1 -> - Info1=Info#response{status=Status,http_version=VerMin}, - http_lib:read_client_headers(Info1,Timeout); - {ok,{http_response,_Version, _Status, _Phrase}} -> - throw({error,bad_status_line}); - {error, timeout} -> - throw({error,session_local_timeout}); - {error, Reason} when Reason==closed;Reason==enotconn -> - throw({error,session_remotely_closed}); - {error, Reason} -> - throw({error,Reason}) - end. - -%%% From RFC 2616, Section 4.4, Page 34 -%% 4.If the message uses the media type "multipart/byteranges", and the -%% transfer-length is not otherwise specified, then this self- -%% delimiting media type defines the transfer-length. This media type -%% MUST NOT be used unless the sender knows that the recipient can parse -%% it; the presence in a request of a Range header with multiple byte- -%% range specifiers from a 1.1 client implies that the client can parse -%% multipart/byteranges responses. -%%% FIXME !! -range_response_body(Info,Timeout,Param) -> - Headers=Info#response.headers, - case {Headers#res_headers.content_length, - Headers#res_headers.transfer_encoding} of - {undefined,undefined} -> - #response{status=Status2,headers=Headers2,body=Body2}= - http_lib:read_client_multipartrange_body(Info,Param,Timeout), - {Status2,Headers2,Body2}; - _ -> - #response{status=Status2,headers=Headers2,body=Body2}= - http_lib:read_client_body(Info,Timeout), - {Status2,Headers2,Body2} - end. - - -%%% ---------------------------------------------------------------------------- -%%% Host: field is required when addressing multi-homed sites ... -%%% It must not be present when the request is being made to a proxy. -http_request(#request{method=Method,id=Id, - scheme=Scheme,address={Host,Port},pathquery=PathQuery, - headers=Headers, content={ContentType,Body}, - settings=Settings}, - Socket) -> - PostData= - if - Method==post;Method==put -> - case Headers#req_headers.expect of - "100-continue" -> - content_type_header(ContentType) ++ - content_length_header(length(Body)) ++ - "\r\n"; - _ -> - content_type_header(ContentType) ++ - content_length_header(length(Body)) ++ - "\r\n" ++ Body - end; - true -> - "\r\n" - end, - Message= - case useProxy(Settings#client_settings.useproxy, - {Scheme,Host,Port,PathQuery}) of - false -> - method(Method)++" "++PathQuery++" HTTP/1.1\r\n"++ - host_header(Host)++te_header()++ - headers(Headers) ++ PostData; - AbsURI -> - method(Method)++" "++AbsURI++" HTTP/1.1\r\n"++ - te_header()++ - headers(Headers)++PostData - end, - http_lib:send(Scheme,Socket,Message). - -useProxy(false,_) -> - false; -useProxy(true,{Scheme,Host,Port,PathQuery}) -> - [atom_to_list(Scheme),"://",Host,":",integer_to_list(Port),PathQuery]. - - - -headers(#req_headers{expect=Expect, - other=Other}) -> - H1=case Expect of - undefined ->[]; - _ -> "Expect: "++Expect++"\r\n" - end, - H1++headers_other(Other). - - -headers_other([]) -> - []; -headers_other([{Key,Value}|Rest]) when atom(Key) -> - Head = atom_to_list(Key)++": "++Value++"\r\n", - Head ++ headers_other(Rest); -headers_other([{Key,Value}|Rest]) -> - Head = Key++": "++Value++"\r\n", - Head ++ headers_other(Rest). - -host_header(Host) -> - "Host: "++lists:concat([Host])++"\r\n". -content_type_header(ContentType) -> - "Content-Type: " ++ ContentType ++ "\r\n". -content_length_header(ContentLength) -> - "Content-Length: "++integer_to_list(ContentLength) ++ "\r\n". -te_header() -> - "TE: \r\n". - -method(Method) -> - httpd_util:to_upper(atom_to_list(Method)). - - -%%% ---------------------------------------------------------------------------- -http_response({Status,Headers,Body},Req,Session) -> - case Status of - 100 -> - status_continue(Req,Session); - 200 -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {Status,Headers,Body}}), - ServerClose=http_lib:connection_close(Headers), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - 300 -> status_multiple_choices(Headers,Body,Req,Session); - 301 -> status_moved_permanently(Req#request.method, - Headers,Body,Req,Session); - 302 -> status_found(Headers,Body,Req,Session); - 303 -> status_see_other(Headers,Body,Req,Session); - 304 -> status_not_modified(Headers,Body,Req,Session); - 305 -> status_use_proxy(Headers,Body,Req,Session); - %% 306 This Status code is not used in HTTP 1.1 - 307 -> status_temporary_redirect(Headers,Body,Req,Session); - 503 -> status_service_unavailable({Status,Headers,Body},Req,Session); - Status50x when Status50x==500;Status50x==501;Status50x==502; - Status50x==504;Status50x==505 -> - status_server_error_50x({Status,Headers,Body},Req,Session); - _ -> % FIXME May want to take some action on other Status codes as well - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {Status,Headers,Body}}), - ServerClose=http_lib:connection_close(Headers), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session) - end. - - -%%% Status code dependent functions. - -%%% Received a 100 Status code ("Continue") -%%% From RFC2616 -%%% The client SHOULD continue with its request. This interim response is -%%% used to inform the client that the initial part of the request has -%%% been received and has not yet been rejected by the server. The client -%%% SHOULD continue by sending the remainder of the request or, if the -%%% request has already been completed, ignore this response. The server -%%% MUST send a final response after the request has been completed. See -%%% section 8.2.3 for detailed discussion of the use and handling of this -%%% status code. -status_continue(Req,Session) -> - {_,Body}=Req#request.content, - http_lib:send(Session#session.scheme,Session#session.socket,Body), - next_response_with_request(Req,Session). - - -%%% Received a 300 Status code ("Multiple Choices") -%%% The resource is located in any one of a set of locations -%%% - If a 'Location' header is present (preserved server choice), use that -%%% to automatically redirect to the given URL -%%% - else if the Content-Type/Body both are non-empty let the user agent make -%%% the choice and thus return a response with status 300 -%%% Note: -%%% - If response to a HEAD request, the Content-Type/Body both should be empty. -%%% - The behaviour on an empty Content-Type or Body is unspecified. -%%% However, e.g. "Apache/1.3" servers returns both empty if the header -%%% 'if-modified-since: Date' was sent in the request and the content is -%%% "not modified" (instead of 304). Thus implicitly giving the cache as the -%%% only choice. -status_multiple_choices(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {300,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_multiple_choices(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {300,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - -%%% Received a 301 Status code ("Moved Permanently") -%%% The resource has been assigned a new permanent URI -%%% - If a 'Location' header is present, use that to automatically redirect to -%%% the given URL if GET or HEAD request -%%% - else return -%%% Note: -%%% - The Body should contain a short hypertext note with a hyperlink to the -%%% new URI. Return this if Content-Type acceptable (some HTTP servers doesn't -%%% deal properly with Accept headers) -status_moved_permanently(Method,Headers,Body,Req,Session) - when (((Req#request.settings)#client_settings.autoredirect)==true) and - (Method==get) or (Method==head) -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {301,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_moved_permanently(_Method,Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {301,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - -%%% Received a 302 Status code ("Found") -%%% The requested resource resides temporarily under a different URI. -%%% Note: -%%% - Only cacheable if indicated by a Cache-Control or Expires header -status_found(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {302,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_found(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {302,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - -%%% Received a 303 Status code ("See Other") -%%% The request found under a different URI and should be retrieved using GET -%%% Note: -%%% - Must not be cached -status_see_other(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {303,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - method=get, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_see_other(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {303,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - -%%% Received a 304 Status code ("Not Modified") -%%% Note: -%%% - The response MUST NOT contain a body. -%%% - The response MUST include the following header fields: -%%% - Date, unless its omission is required -%%% - ETag and/or Content-Location, if the header would have been sent -%%% in a 200 response to the same request -%%% - Expires, Cache-Control, and/or Vary, if the field-value might -%%% differ from that sent in any previous response for the same -%%% variant -status_not_modified(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {304,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_not_modified(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {304,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - - -%%% Received a 305 Status code ("Use Proxy") -%%% The requested resource MUST be accessed through the proxy given by the -%%% Location field -status_use_proxy(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {305,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_use_proxy(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {305,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - -%%% Received a 307 Status code ("Temporary Redirect") -status_temporary_redirect(Headers,Body,Req,Session) - when ((Req#request.settings)#client_settings.autoredirect)==true -> - ServerClose=http_lib:connection_close(Headers), - case Headers#res_headers.location of - undefined -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {307,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose, - Req,Session); - RedirUrl -> - Scheme=Session#session.scheme, - case uri:parse(RedirUrl) of - {error,Reason} -> - {error,Reason}; - {Scheme,Host,Port,PathQuery} -> % Automatic redirection - NewReq=Req#request{redircount=Req#request.redircount+1, - address={Host,Port},pathquery=PathQuery}, - handle_redirect(Session#session.clientclose,ServerClose, - NewReq,Session) - end - end; -status_temporary_redirect(Headers,Body,Req,Session) -> - ServerClose=http_lib:connection_close(Headers), - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {307,Headers,Body}}), - handle_connection(Session#session.clientclose,ServerClose,Req,Session). - - - -%%% Received a 503 Status code ("Service Unavailable") -%%% The server is currently unable to handle the request due to a -%%% temporary overloading or maintenance of the server. The implication -%%% is that this is a temporary condition which will be alleviated after -%%% some delay. If known, the length of the delay MAY be indicated in a -%%% Retry-After header. If no Retry-After is given, the client SHOULD -%%% handle the response as it would for a 500 response. -%% Note: -%% - This session is now considered busy, thus cancel any requests in the -%% pipeline and close the session. -%% FIXME! Implement a user option to automatically retry if the 'Retry-After' -%% header is given. -status_service_unavailable(Resp,Req,Session) -> -% RetryAfter=Headers#res_headers.retry_after, - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id,Resp}), - close_session(server_connection_close,Req,Session). - - -%%% Received a 50x Status code (~ "Service Error") -%%% Response status codes beginning with the digit "5" indicate cases in -%%% which the server is aware that it has erred or is incapable of -%%% performing the request. -status_server_error_50x(Resp,Req,Session) -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id,Resp}), - close_session(server_connection_close,Req,Session). - - -%%% Handles requests for redirects -%%% The redirected request might be: -%%% - FIXME! on another TCP session, another scheme -%%% - on the same TCP session, same scheme -%%% - on another TCP session , same scheme -%%% However, in all cases treat it as a new request, with redircount updated. -%%% -%%% The redirect may fail, but this not a reason to close this session. -%%% Instead return a error for this request, and continue as ok. -handle_redirect(ClientClose,ServerClose,Req,Session) -> - case httpc_manager:request(Req) of - {ok,_ReqId} -> % FIXME Should I perhaps reuse the Reqid? - handle_connection(ClientClose,ServerClose,Req,Session); - {error,Reason} -> - gen_server:cast(Req#request.from,{Req#request.ref,Req#request.id, - {error,Reason}}), - handle_connection(ClientClose,ServerClose,Req,Session) - end. - -%%% Check if the persistent connection flag is false (ie client request -%%% non-persistive connection), or if the server requires a closed connection -%%% (by sending a "Connection: close" header). If the connection required -%%% non-persistent, we may close the connection immediately. -handle_connection(ClientClose,ServerClose,Req,Session) -> - case {ClientClose,ServerClose} of - {false,false} -> - ok; - {false,true} -> % The server requests this session to be closed. - close_session(server_connection_close,Req,Session); - {true,_} -> % The client requested a non-persistent connection - close_session(client_connection_close,Req,Session) - end. - - -%%% Close the session. -%%% We now have three cases: -%%% - Client request a non-persistent connection when initiating the request. -%%% Session info not stored in httpc_manager -%%% - Server requests a non-persistent connection when answering a request. -%%% No need to resend request, but there might be a pipeline. -%%% - Some kind of error -%%% Close the session, we may then try resending all requests in the pipeline -%%% including the current depending on the error. -%%% FIXME! Should not always abort the session (see close_session in -%%% httpc_manager for more details) -close_session(client_connection_close,_Req,Session) -> - http_lib:close(Session#session.scheme,Session#session.socket), - stop; -close_session(server_connection_close,Req,Session) -> - http_lib:close(Session#session.scheme,Session#session.socket), - httpc_manager:abort_session(Req#request.address,Session#session.id, - aborted_request), - stop. - -exit_session(Address,Session,Reason) -> - http_lib:close(Session#session.scheme,Session#session.socket), - httpc_manager:abort_session(Address,Session#session.id,Reason), - exit(normal). - -%%% This is the "normal" case to close a persistent connection. I.e., there are -%%% no more requests waiting and the session was closed by the client, or -%%% server because of a timeout or user request. -exit_session_ok(Address,Session) -> - http_lib:close(Session#session.scheme,Session#session.socket), - exit_session_ok2(Address,Session#session.clientclose,Session#session.id). - -exit_session_ok2(Address,ClientClose,Sid) -> - case ClientClose of - false -> - httpc_manager:close_session(Address,Sid); - true -> - ok - end, - exit(normal). - -%%% ============================================================================ -%%% This is deprecated code, to be removed - -format_time() -> - {_,_,MicroSecs}=TS=now(), - {{Y,Mon,D},{H,M,S}}=calendar:now_to_universal_time(TS), - lists:flatten(io_lib:format("~4.4.0w-~2.2.0w-~2.2.0w,~2.2.0w:~2.2.0w:~6.3.0f", - [Y,Mon,D,H,M,S+(MicroSecs/1000000)])). - -%%% Read more data from the open socket. -%%% Two different read functions is used because for the {active, once} socket -%%% option is (currently) not available for SSL... -%%% FIXME -% read_more_data(http,Socket,Timeout) -> -% io:format("read_more_data(ip_comm) -> " -% "~n set active = 'once' and " -% "await a chunk data", []), -% http_lib:setopts(Socket, [{active,once}]), -% read_more_data_ipcomm(Socket,Timeout); -% read_more_data(https,Socket,Timeout) -> -% case ssl:recv(Socket,0,Timeout) of -% {ok,MoreData} -> -% MoreData; -% {error,closed} -> -% throw({error, session_remotely_closed}); -% {error,etimedout} -> -% throw({error, session_local_timeout}); -% {error,Reason} -> -% throw({error, Reason}); -% Other -> -% throw({error, Other}) -% end. - -% %%% Send any incoming requests on the open session immediately -% read_more_data_ipcomm(Socket,Timeout) -> -% receive -% {tcp,Socket,MoreData} -> -% % ?vtrace("read_more_data(ip_comm) -> got some data:~p", -% % [MoreData]), -% MoreData; -% {tcp_closed,Socket} -> -% % ?vtrace("read_more_data(ip_comm) -> socket closed",[]), -% throw({error,session_remotely_closed}); -% {tcp_error,Socket,Reason} -> -% % ?vtrace("read_more_data(ip_comm) -> ~p socket error: ~p", -% % [self(),Reason]), -% throw({error, Reason}); -% stop -> -% throw({error, user_req}) -% after Timeout -> -% throw({error, session_local_timeout}) -% end. |