httpc_request.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 194 行

ERL
194
字号
%% ``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$-module(httpc_request).-include("http_internal.hrl").-include("httpc_internal.hrl").%% We will not make the change to use base64 in stdlib in inets just yet.%% it will be included in the next major release of inets. -compile({nowarn_deprecated_function, {http_base_64, encode, 1}}).%%% Internal API-export([send/3, is_idempotent/1, is_client_closing/1]).%%%=========================================================================%%%  Internal application API%%%=========================================================================%%-------------------------------------------------------------------------%% send(MaybeProxy, Request) ->%%      MaybeProxy - {Host, Port}%%      Host = string()%%      Port = integer()%%	Request - #request{}%%	Socket - socket()%%      CookieSupport - enabled | disabled | verify%%                                   %% Description: Composes and sends a HTTP-request. %%-------------------------------------------------------------------------send(SendAddr, #request{method = Method, scheme = Scheme,			path = Path, pquery = Query, headers = Headers,			content = Content, address = Address, 			abs_uri = AbsUri, headers_as_is = HeadersAsIs,			settings = HttpOptions, 			userinfo = UserInfo},     Socket) ->         TmpHeaders = handle_user_info(UserInfo, Headers),    {TmpHeaders2, Body} = post_data(Method, TmpHeaders, Content, HeadersAsIs),        {NewHeaders, Uri} = case Address of			    SendAddr ->				{TmpHeaders2, Path ++ Query};			    _Proxy ->				TmpHeaders3 =				    handle_proxy(HttpOptions, TmpHeaders2),				{TmpHeaders3, AbsUri}			end,    FinalHeaders = case NewHeaders of		       HeaderList when is_list(HeaderList) ->			   headers(HeaderList, []);		       _  ->			   http_request:http_headers(NewHeaders)		   end,        Message = 	lists:append([method(Method), " ", Uri, " HTTP/1.1", ?CRLF, 		      FinalHeaders, ?CRLF, Body]),        http_transport:send(socket_type(Scheme), Socket, Message).%%-------------------------------------------------------------------------%% is_idempotent(Method) ->%% Method = atom()%%                                   %% Description: Checks if Methode is considered idempotent.%%-------------------------------------------------------------------------%% In particular, the convention has been established that the GET and%% HEAD methods SHOULD NOT have the significance of taking an action%% other than retrieval. These methods ought to be considered "safe".is_idempotent(head) ->     true;is_idempotent(get) ->    true;%% Methods can also have the property of "idempotence" in that (aside%% from error or expiration issues) the side-effects of N > 0%% identical requests is the same as for a single request.is_idempotent(put) ->     true;is_idempotent(delete) ->    true;%% Also, the methods OPTIONS and TRACE SHOULD NOT have side effects,%% and so are inherently idempotent.is_idempotent(trace) ->    true;is_idempotent(options) ->    true;is_idempotent(_) ->    false.%%-------------------------------------------------------------------------%% is_client_closing(Headers) ->%% Headers = #http_request_h{}%%                                   %% Description: Checks if the client has supplied a "Connection: close" header.%%-------------------------------------------------------------------------is_client_closing(Headers) ->    case Headers#http_request_h.connection of	"close" ->	    true;	 _ ->	    false    end.%%%========================================================================%%% Internal functions%%%========================================================================post_data(Method, Headers, {ContentType, Body}, HeadersAsIs)   when Method == post; Method == put ->    ContentLength = body_length(Body),	          NewBody = case Headers#http_request_h.expect of		  "100-continue" ->		      "";		  _ ->		      Body	      end,        NewHeaders = case HeadersAsIs of		     [] ->			 Headers#http_request_h{'content-type' = 						ContentType, 						'content-length' = 						ContentLength};		     _ ->			 HeadersAsIs		 end,        {NewHeaders, NewBody};post_data(_, Headers, _, []) ->    {Headers, ""};post_data(_, _, _, HeadersAsIs = [_|_]) ->    {HeadersAsIs, ""}.body_length(Body) when is_binary(Body) ->   integer_to_list(size(Body));body_length(Body) when is_list(Body) ->  integer_to_list(length(Body)).method(Method) ->    http_util:to_upper(atom_to_list(Method)).socket_type(http) ->    ip_comm;socket_type(https) ->    {ssl, []}.headers([], Headers) ->    lists:flatten(Headers);headers([{Key,Value} | Rest], Headers) ->    Header = Key ++ ": " ++ Value ++ ?CRLF,    headers(Rest, [Header | Headers]).handle_proxy(_, Headers) when is_list(Headers) ->    Headers; %% Headers as is option was specifiedhandle_proxy(HttpOptions, Headers) ->    case HttpOptions#http_options.proxy_auth of	undefined ->	    Headers;	{User, Password} ->	    UserPasswd = http_base_64:encode(User ++ ":" ++ Password),	    Headers#http_request_h{'proxy-authorization' = 				   "Basic " ++ UserPasswd}    end.handle_user_info([], Headers) ->    Headers;handle_user_info(UserInfo, Headers) ->    case string:tokens(UserInfo, ":") of	[User, Passwd] ->	    UserPasswd = http_base_64:encode(User ++ ":" ++ Passwd),	    Headers#http_request_h{authorization = "Basic " ++ UserPasswd};	_ ->	    Headers    end.

⌨️ 快捷键说明

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