http.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 397 行 · 第 1/2 页

ERL
397
字号
% ``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 Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%% This module is very loosely based on code initially developed by %% Johan Blom at Mobile Arts AB%% Description:%%% This version of the HTTP/1.1 client supports:%%%      - RFC 2616 HTTP 1.1 client part%%%      - RFC 2818 HTTP Over TLS-module(http).%% API-export([request/1, request/4, cancel_request/1, set_options/1, 	 verify_cookies/2, cookie_header/1]).-include("http_internal.hrl").-include("httpc_internal.hrl").%%%=========================================================================%%%  API%%%=========================================================================%%--------------------------------------------------------------------------%% request(Method, Request, HTTPOptions, Options) ->%%           {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |%%           {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}%%%%	Method - atom() = head | get | put | post | trace | options| delete %%	Request - {Url, Headers} | {Url, Headers, ContentType, Body} %%	Url - string() %%	HTTPOptions - [HttpOption]%%	HTTPOption - {timeout, Time} | {ssl, SSLOptions} | %%                   {proxy_auth, {User, Password}}%%	Ssloptions = [SSLOption]%%	SSLOption =  {verify, code()} | {depth, depth()} | {certfile, path()} |%%	{keyfile, path()} | {password, string()} | {cacertfile, path()} |%%	{ciphers, string()} %%	Options - [Option]%%	Option - {sync, Boolean} | {body_format, BodyFormat} | %%	{full_result, Boolean} | {stream, To} |%%      {headers_as_is, Boolean}  %%	StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>%%	HTTPVersion = string()%%	StatusCode = integer()%%	ReasonPhrase = string()%%	Headers = [Header]%%      Header = {Field, Value}%%	Field = string()%%	Value = string()%%	Body = string() | binary() - HTLM-code%%%% Description: Sends a HTTP-request. The function can be both%% syncronus and asynchronous in the later case the function will%% return {ok, RequestId} and later on a message will be sent to the%% calling process on the format {http, {RequestId, {StatusLine,%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}%% %%--------------------------------------------------------------------------request(Url) ->    request(get, {Url, []}, [], []).request(Method, {Url, Headers}, HTTPOptions, Options)   when Method==options;Method==get;Method==head;Method==delete;Method==trace ->    case http_uri:parse(Url) of	{error,Reason} ->	    {error,Reason};	ParsedUrl ->	    handle_request(Method, Url, {ParsedUrl, Headers, [], []}, 			   HTTPOptions, Options)    end;     request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options)   when Method==post;Method==put ->    case http_uri:parse(Url) of	{error,Reason} ->	    {error,Reason};	ParsedUrl ->	    handle_request(Method, Url, 			   {ParsedUrl, Headers, ContentType, Body}, 			   HTTPOptions, Options)    end.%%--------------------------------------------------------------------------%% request(RequestId) -> ok%%   RequestId - As returned by request/4  %%                                 %% Description: Cancels a HTTP-request.%%-------------------------------------------------------------------------cancel_request(RequestId) ->    ok = httpc_manager:cancel_request(RequestId),     receive  	%% If the request was allready fullfilled throw away the 	%% answer as the request has been canceled.	{http, {RequestId, _}} ->	    ok     after 0 ->	    ok    end.%%--------------------------------------------------------------------------%% set_options(Options) ->%%   Options - [Option]%%   Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} | %%            {max_pipeline_length, MaxPipeline} | %%            {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode}%%            | {ipv6, Ipv6Mode}%%   Proxy - {Host, Port}%%   NoProxy - [Domain | HostName | IPAddress]   %%   MaxSessions, MaxPipeline, PipelineTimeout = integer()   %%   CookieMode - enabled | disabled | verify%%   Ipv6Mode - enabled | disabled%% Description: Informs the httpc_manager of the new settings. %%-------------------------------------------------------------------------set_options(Options) ->    ensure_started(no_scheme),    httpc_manager:set_options(Options).verify_cookies(SetCookieHeaders, Url) ->    {_, _, Host, Port, Path, _} = http_uri:parse(Url),    Cookies = http_cookie:cookies(SetCookieHeaders, Path, Host),    httpc_manager:store_cookies(Cookies, {Host, Port}),    ok.cookie_header(Url) ->    httpc_manager:cookies(Url).%%%========================================================================%%% Internal functions%%%========================================================================handle_request(Method, Url, {{Scheme, UserInfo, Host, Port, Path, Query},			Headers, ContentType, Body}, HTTPOptions, Options) ->    HTTPRecordOptions = http_options(HTTPOptions, #http_options{}),        Sync = http_util:key1search(Options, sync, true),    NewHeaders = lists:map(fun({Key, Val}) -> 				   {http_util:to_lower(Key), Val} end,			   Headers),    Stream = http_util:key1search(Options, stream, none),    case {Sync, Stream} of	{true, self} ->	    {error, streaming_error};	_ ->	    RecordHeaders = header_record(NewHeaders, #http_request_h{}, Host),	    Request = #request{from = self(),			       scheme = Scheme, address = {Host,Port},			       path = Path, pquery = Query, method = Method,			       headers = RecordHeaders, 			       content = {ContentType,Body},			       settings = HTTPRecordOptions,			       abs_uri = Url, userinfo = UserInfo, 			       stream = Stream, 			       headers_as_is = 			       headers_as_is(Headers, Options)},	    	    ensure_started(Scheme),	    	    case httpc_manager:request(Request) of		{ok, RequestId} ->		    handle_answer(RequestId, Sync, Options);		{error, Reason} ->		    {error, Reason}	    end    end.handle_answer(RequestId, false, _) ->    {ok, RequestId};handle_answer(RequestId, true, Options) ->    receive	{http, {RequestId, saved_to_file}} ->	    {ok, saved_to_file};	{http, {RequestId, Result = {_,_,_}}} ->	    return_answer(Options, Result);	{http, {RequestId, {error, Reason}}} ->	    {error, Reason}    end. return_answer(Options, {StatusLine, Headers, BinBody}) ->    Body = 	case http_util:key1search(Options, body_format, string) of	    string ->		binary_to_list(BinBody);	    _ ->		BinBody	end,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?