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 + -
显示快捷键?