-module(http_lib).
%%%=======================INCLUDE======================
%%%=======================RECORD=======================
%%%=======================DEFINE=======================
-define(HEADER_USER_AGENT, {"user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"}).
%-define(HEADER_ACCEPT_ENCODING, {"accept-encoding", "gzip, deflate"}). %% 如果对方服务器开启了gzip需要在?HEADER补充上这个字段
-define(HEADER_ACCEPT, {"accept", "application/json, text/plain, */*"}).
-define(HEADER, [?HEADER_USER_AGENT, ?HEADER_ACCEPT]).
-define(GET_CONTENT_TYPE, [{"content-type", "text/html; charset=utf-8"}]).
-define(POST_CONTENT_TYPE, "application/x-www-form-urlencoded;charset=UTF-8").
-define(TIMEOUT, 1000). %% 默认1秒超时
-define(AWAIT, {sync, false}). %% 让它异步处理,我们自己使用信箱做超时
%%%=================EXPORTED FUNCTIONS=================
-export([
test_get/0, test_post/0,
request/5, start_inets/0,
http_get/1, http_get/2, http_get/3,
http_post/2, http_post/3, http_post/4
]).
test_get() ->
%% 访问csdn
http_get("http://blog.csdn.net/ap114").
test_post() ->
%% Post 测试
Id = "1002",
Name = "admin",
Psw = "8715fa621ca7e8ff9dd403825694314a",
PostData = io_lib:format("Id=~s&Name=~s&Psw=~s", [Id, Name, Psw]),
http_post("http://124.172.234.157:8180/service.asmx", PostData).
%% ----------------------------------------------------
%% Description: get方法
%% ----------------------------------------------------
http_get(Url) ->
{_HttpCPid, ServerName} = start_inets(),
http_get(Url, ServerName).
http_get(Url, ServerName) ->
http_get(Url, [{timeout, ?TIMEOUT}], ServerName).
http_get(Url, Option, ServerName) ->
request(get, {Url, ?GET_CONTENT_TYPE}, Option, [?AWAIT], ServerName).
%% ----------------------------------------------------
%% Description: post方法
%% ----------------------------------------------------
http_post(Url, Data) ->
{_HttpCPid, ServerName} = start_inets(),
http_post(Url, Data, ServerName).
http_post(Url, Data, ServerName) ->
http_post(Url, [{timeout, ?TIMEOUT}], Data, ServerName).
http_post(Url, Option, ParaData, ServerName) ->
request(post, {Url, ?HEADER, ?POST_CONTENT_TYPE, list_to_binary(ParaData)}, Option, [?AWAIT], ServerName).
%% ----------------------------------------------------
%% Description: request请求
%% ----------------------------------------------------
request(Method, Request, HttpOption, Option, ServerName) ->
{ok, RequestId} = httpc:request(Method, Request, HttpOption, Option, ServerName),
receive
{http, {RequestId, {_Status, _Header, _Content}}} ->
stop(ServerName),
_Content
after ?TIMEOUT ->
% httpc:cancel_request(RequestId, ServerName),
stop(ServerName),
throw(timeout)
end.
%% ----------------------------------------------------
%% Description: 启动inets 创建httpc
%% ----------------------------------------------------
start_inets() ->
ssl:start(),
case inets:services_info() of
{error, inets_not_started} ->
inets:start();
{error, Other} ->
throw(Other);
_ ->
ok
end,
create_httpc_(1).
%%%===================LOCAL FUNCTIONS==================
%% ----------------------------------------------------
%% Description:创建httpc进程 如果已有atom会复用atom 如果没有就+1创建新的
%% ----------------------------------------------------
create_httpc_(ServerNum) ->
ServerName = list_to_atom("http_lib_" ++ integer_to_list(ServerNum)),
case inets:services_info() of
List when is_list(List) ->
case get_(List, ServerName) of
false ->
case inets:start(httpc, [{'profile', ServerName}]) of
{ok, Pid} ->
{Pid, ServerName};
Err ->
erlang:throw(Err)
end;
_Pid ->
create_httpc_(ServerNum + 1)
end;
Err ->
throw(Err)
end.
%% ----------------------------------------------------
%% Description:查询num号httpc进程是否存在
%% ----------------------------------------------------
get_([{_, Pid, List} | T], Name) ->
case lists:keyfind('profile', 1, List) of
false ->
get_(T, Name);
{_, Name} ->
Pid;
_ ->
get_(T, Name)
end;
get_(_, _) ->
false.
%% ----------------------------------------------------
%% Description:结束指定ServerName的httpc进程
%% ----------------------------------------------------
stop(ServerName) ->
case inets:services_info() of
List when is_list(List) ->
case get_(List, ServerName) of
false ->
ok;
Pid ->
inets:stop(httpc, Pid)
end;
Err ->
throw(Err)
end.
访问https需要证书,自行配置。