Skip to content

Commit 957c28a

Browse files
zp-sdZbigniew Pękala
authored andcommitted
Use lhttpc instead of httpc
* Aviod a crash in http_transport:close/2, happening when setting socket_opts in httpc in OTP 20.1. The fix for the bug is included in OTP 21 - https://bugs.erlang.org/browse/ERL-605. * Avoid crash report when httpc_handler_sup is killing its children after unsuccessful httpc:request/1 function call. It happens in some router softwares, with miniupnpd daemon installed, but UPnP/NAT-PMP functionality turned off. Then, during natupnp_v1/natupnp_v2 discovery, location is returned, but is it not responding (hence httpc:request/1 crash).
1 parent fdc7b44 commit 957c28a

File tree

6 files changed

+25
-24
lines changed

6 files changed

+25
-24
lines changed

rebar.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
rand_compat,
1010
{inet_cidr, "1.0.1", {pkg, erl_cidr}},
1111
{inet_ext, "0.4.0"},
12-
{intercept, "1.0.0"}
12+
{intercept, "1.0.0"},
13+
{lhttpc, "1.6.2"}
1314
]}.
1415

1516

rebar.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
[{<<"inet_cidr">>,{pkg,<<"erl_cidr">>,<<"1.0.1">>},0},
33
{<<"inet_ext">>,{pkg,<<"inet_ext">>,<<"0.4.0">>},0},
44
{<<"intercept">>,{pkg,<<"intercept">>,<<"1.0.0">>},0},
5+
{<<"lhttpc">>,{pkg,<<"lhttpc">>,<<"1.6.2">>},0},
56
{<<"rand_compat">>,{pkg,<<"rand_compat">>,<<"0.0.3">>},0}]}.
67
[
78
{pkg_hash,[
89
{<<"inet_cidr">>, <<"9EA93F2B885820C1C3ADEC24E7AB5B04AAD829FBF7B3F8F41F1ACD4550D8BF97">>},
910
{<<"inet_ext">>, <<"EF51FE5EA13DB6B40CBA48E66D9117BBD31E5A4347FA432B83D0C0547C7AB522">>},
1011
{<<"intercept">>, <<"1F6C725E6FC070720643BD4D97EE53B1209365C80E520E1F5A1ACB36712A7EB5">>},
12+
{<<"lhttpc">>, <<"044F16F0018C7AA7E945E9E9406C7F6035E0B8BC08BF77B00C78CE260E1071E3">>},
1113
{<<"rand_compat">>, <<"011646BC1F0B0C432FE101B816F25B9BBB74A085713CEE1DAFD2D62E9415EAD3">>}]}
1214
].

src/nat.app.src

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{vsn, "0.3.1"},
44
{modules, []},
55
{registered, []},
6-
{applications, [kernel,stdlib,inet_cidr,inet_ext,inets,xmerl,rand_compat]},
6+
{applications, [kernel,stdlib,inet_cidr,inet_ext,inets,xmerl,rand_compat,lhttpc]},
77
{maintainers, ["Benoit Chesneau"]},
88
{licenses, ["MIT"]},
99
{links, [{"Github", "https://github.com/benoitc/erlang-nat"}]},

src/nat_lib.erl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,18 @@ soap_request(Url, Function, Msg0, Options) ->
2424
Action = "\"urn:schemas-upnp-org:service:WANIPConnection:1#"
2525
++ Function ++ "\"",
2626

27-
Headers = [{"Content-Length", integer_to_list(length(Msg))},
27+
Headers = [{"Content-Type", "text/xml; charset=\"utf-8\""},
28+
{"Content-Length", integer_to_list(length(Msg))},
2829
{"User-Agent", "Darwin/10.0.0, UPnP/1.0, MiniUPnPc/1.3"},
2930
{"SOAPAction", Action},
3031
{"Connection", "close"},
3132
{"Cache-Control", "no-cache"},
3233
{"Pragma", "no-cache"}],
3334

34-
35-
Req = {Url, Headers, "text/xml; charset=\"utf-8\"", Msg},
36-
37-
case httpc:request(post, Req, [], Options) of
38-
{ok, {{_, 200, _}, _, Body}} ->
39-
{ok, Body};
40-
OK = {ok, {{_, Status, _}, _, _}} ->
35+
case lhttpc:request(Url, post, Headers, Msg, 5000, Options) of
36+
{ok, {{200, _}, _, Body}} ->
37+
{ok, binary_to_list(Body)};
38+
OK = {ok, {{Status, _}, _, _}} ->
4139
error_logger:info_msg("UPNP SOAP error: ~p~n", [OK]),
4240
{error, integer_to_list(Status)};
4341
Error ->

src/natupnp_v1.erl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ add_port_mapping1(#nat_upnp{ip=Ip, service_url=Url}, Protocol, InternalPort,
164164
"</NewLeaseDuration></u:AddPortMapping>",
165165
{ok, IAddr} = inet:parse_address(Ip),
166166
Start = nat_lib:timestamp(),
167-
case nat_lib:soap_request(Url, "AddPortMapping", Msg, [{socket_opts, [{ip, IAddr}]}]) of
167+
case nat_lib:soap_request(Url, "AddPortMapping", Msg, [{connect_options, [{ip, IAddr}]}]) of
168168
{ok, _} ->
169169
Now = nat_lib:timestamp(),
170170
MappingLifetime = Lifetime - (Now - Start),
@@ -187,7 +187,7 @@ delete_port_mapping(#nat_upnp{ip=Ip, service_url=Url}, Protocol0, _InternalPort,
187187
"<NewProtocol>" ++ Protocol ++ "</NewProtocol>"
188188
"</u:DeletePortMapping>",
189189
{ok, IAddr} = inet:parse_address(Ip),
190-
case nat_lib:soap_request(Url, "DeletePortMapping", Msg, [{socket_opts, [{ip, IAddr}]}]) of
190+
case nat_lib:soap_request(Url, "DeletePortMapping", Msg, [{connect_options, [{ip, IAddr}]}]) of
191191
{ok, _} -> ok;
192192
Error -> Error
193193
end.
@@ -207,7 +207,7 @@ get_port_mapping(#nat_upnp{ip=Ip, service_url=Url}, Protocol0, ExternalPort) ->
207207
"<NewProtocol>" ++ Protocol ++ "</NewProtocol>"
208208
"</u:GetSpecificPortMappingEntry>",
209209
{ok, IAddr} = inet:parse_address(Ip),
210-
case nat_lib:soap_request(Url, "GetSpecificPortMappingEntry", Msg, [{socket_opts, [{ip, IAddr}]}]) of
210+
case nat_lib:soap_request(Url, "GetSpecificPortMappingEntry", Msg, [{connect_options, [{ip, IAddr}]}]) of
211211
{ok, Body} ->
212212
{Xml, _} = xmerl_scan:string(Body, [{space, normalize}]),
213213
[Infos | _] = xmerl_xpath:string("//s:Envelope/s:Body/"
@@ -281,17 +281,17 @@ get_location(Raw) ->
281281
end.
282282

283283
get_service_url(RootUrl) ->
284-
case httpc:request(RootUrl) of
285-
{ok, {{_, 200, _}, _, Body}} ->
286-
{Xml, _} = xmerl_scan:string(Body, [{space, normalize}]),
284+
case lhttpc:request(RootUrl, get, [], 5000) of
285+
{ok, {{200, _}, _, Body}} ->
286+
{Xml, _} = xmerl_scan:string(binary_to_list(Body), [{space, normalize}]),
287287
[Device | _] = xmerl_xpath:string("//device", Xml),
288288
case device_type(Device) of
289289
"urn:schemas-upnp-org:device:InternetGatewayDevice:1" ->
290290
get_wan_device(Device, RootUrl);
291291
_ ->
292292
{error, no_gateway_device}
293293
end;
294-
{ok, {{_, StatusCode, _}, _, _}} ->
294+
{ok, {{StatusCode, _}, _, _}} ->
295295
{error, integer_to_list(StatusCode)};
296296
Error ->
297297
Error

src/natupnp_v2.erl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ add_port_mapping1(#nat_upnp{ip=Ip, service_url=Url}, Protocol, InternalPort,
170170
"</NewLeaseDuration></u:AddPortMapping>",
171171
{ok, IAddr} = inet:parse_address(Ip),
172172
Start = nat_lib:timestamp(),
173-
case nat_lib:soap_request(Url, "AddAnyPortMapping", Msg, [{socket_opts, [{ip, IAddr}]}]) of
173+
case nat_lib:soap_request(Url, "AddAnyPortMapping", Msg, [{connect_options, [{ip, IAddr}]}]) of
174174
{ok, Body} ->
175175
{Xml, _} = xmerl_scan:string(Body, [{space, normalize}]),
176176

@@ -203,7 +203,7 @@ delete_port_mapping(#nat_upnp{ip=Ip, service_url=Url}, Protocol0, _InternalPort,
203203
"<NewProtocol>" ++ Protocol ++ "</NewProtocol>"
204204
"</u:DeletePortMapping>",
205205
{ok, IAddr} = inet:parse_address(Ip),
206-
case nat_lib:soap_request(Url, "DeletePortMapping", Msg, [{socket_opts, [{ip, IAddr}]}]) of
206+
case nat_lib:soap_request(Url, "DeletePortMapping", Msg, [{connect_options, [{ip, IAddr}]}]) of
207207
{ok, _} -> ok;
208208
Error -> Error
209209
end.
@@ -224,7 +224,7 @@ get_port_mapping(#nat_upnp{ip=Ip, service_url=Url}, Protocol0, ExternalPort) ->
224224
"<NewProtocol>" ++ Protocol ++ "</NewProtocol>"
225225
"</u:GetSpecificPortMappingEntry>",
226226
{ok, IAddr} = inet:parse_address(Ip),
227-
case nat_lib:soap_request(Url, "GetSpecificPortMappingEntry", Msg, [{socket_opts, [{ip, IAddr}]}]) of
227+
case nat_lib:soap_request(Url, "GetSpecificPortMappingEntry", Msg, [{connect_options, [{ip, IAddr}]}]) of
228228
{ok, Body} ->
229229
{Xml, _} = xmerl_scan:string(Body, [{space, normalize}]),
230230
[Infos | _] = xmerl_xpath:string("//s:Envelope/s:Body/"
@@ -299,17 +299,17 @@ get_location(Raw) ->
299299
end.
300300

301301
get_service_url(RootUrl) ->
302-
case httpc:request(RootUrl) of
303-
{ok, {{_, 200, _}, _, Body}} ->
304-
{Xml, _} = xmerl_scan:string(Body, [{space, normalize}]),
302+
case lhttpc:request(RootUrl, get, [], 5000) of
303+
{ok, {{200, _}, _, Body}} ->
304+
{Xml, _} = xmerl_scan:string(binary_to_list(Body), [{space, normalize}]),
305305
[Device | _] = xmerl_xpath:string("//device", Xml),
306306
case device_type(Device) of
307307
"urn:schemas-upnp-org:device:InternetGatewayDevice:2" ->
308308
get_wan_device(Device, RootUrl);
309309
_ ->
310310
{error, no_gateway_device}
311311
end;
312-
{ok, {{_, StatusCode, _}, _, _}} ->
312+
{ok, {{StatusCode, _}, _, _}} ->
313313
{error, integer_to_list(StatusCode)};
314314
Error ->
315315
Error

0 commit comments

Comments
 (0)