exit when setopts result is {error,closed} #152
diff --git a/.travis.yml b/.travis.yml
index d9c6fd8..5052773 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
notifications:
email: false
otp_release:
- - 17.1
- - 17.0
+ - 17.4
+ - 17.3
- R16B03-1
- R15B03
diff --git a/CHANGES.md b/CHANGES.md
index 6856381..88846b0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,8 @@
+Version 2.12.2 released 2015-02-21
+
+* Close connections quietly when setopts fails with a closed socket.
+ https://github.com/mochi/mochiweb/pull/152
+
Version 2.12.1 released 2015-02-01
* Fix active_socket accounting
diff --git a/src/mochiweb.app.src b/src/mochiweb.app.src
index 0ebef8f..7431224 100644
--- a/src/mochiweb.app.src
+++ b/src/mochiweb.app.src
@@ -1,7 +1,7 @@
%% This is generated from src/mochiweb.app.src
{application, mochiweb,
[{description, "MochiMedia Web Server"},
- {vsn, "2.12.1"},
+ {vsn, "2.12.2"},
{modules, []},
{registered, []},
{env, []},
diff --git a/src/mochiweb_http.erl b/src/mochiweb_http.erl
index 897d625..cfbe0b9 100644
--- a/src/mochiweb_http.erl
+++ b/src/mochiweb_http.erl
@@ -71,14 +71,14 @@
mochiweb_socket_server:start_link(parse_options(Options)).
loop(Socket, Opts, Body) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, http}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, http}])),
request(Socket, Opts, Body).
request(Socket, Opts, Body) ->
- ok = mochiweb_socket:setopts(Socket, [{active, once}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{active, once}])),
receive
{Protocol, _, {http_request, Method, Path, Version}} when Protocol == http orelse Protocol == ssl ->
- ok = mochiweb_socket:setopts(Socket, [{packet, httph}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, httph}])),
headers(Socket, Opts, {Method, Path, Version}, [], Body, 0);
{Protocol, _, {http_error, "\r\n"}} when Protocol == http orelse Protocol == ssl ->
request(Socket, Opts, Body);
@@ -104,10 +104,10 @@
headers(Socket, Opts, Request, Headers, _Body, ?MAX_HEADERS) ->
%% Too many headers sent, bad request.
- ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
handle_invalid_request(Socket, Opts, Request, Headers);
headers(Socket, Opts, Request, Headers, Body, HeaderCount) ->
- ok = mochiweb_socket:setopts(Socket, [{active, once}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{active, once}])),
receive
{Protocol, _, http_eoh} when Protocol == http orelse Protocol == ssl ->
Req = new_request(Socket, Opts, Request, Headers),
@@ -156,7 +156,7 @@
exit(normal).
new_request(Socket, Opts, Request, RevHeaders) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
mochiweb:new_request({Socket, Opts, Request, lists:reverse(RevHeaders)}).
after_response(Body, Req) ->
diff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl
index 3866876..3559395 100644
--- a/src/mochiweb_request.erl
+++ b/src/mochiweb_request.erl
@@ -562,10 +562,10 @@
%% @spec read_chunk_length(request()) -> integer()
%% @doc Read the length of the next HTTP chunk.
read_chunk_length({?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, line}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, line}])),
case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
{ok, Header} ->
- ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
Splitter = fun (C) ->
C =/= $\r andalso C =/= $\n andalso C =/= $
end,
@@ -579,7 +579,7 @@
%% @doc Read in a HTTP chunk of the given length. If Length is 0, then read the
%% HTTP footers (as a list of binaries, since they're nominal).
read_chunk(0, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, line}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, line}])),
F = fun (F1, Acc) ->
case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
{ok, <<"\r\n">>} ->
@@ -591,7 +591,7 @@
end
end,
Footers = F(F, []),
- ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, raw}])),
put(?SAVE_RECV, true),
Footers;
read_chunk(Length, {?MODULE, [Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) ->
diff --git a/src/mochiweb_socket.erl b/src/mochiweb_socket.erl
index 1e35e15..1756b8e 100644
--- a/src/mochiweb_socket.erl
+++ b/src/mochiweb_socket.erl
@@ -7,7 +7,7 @@
-export([listen/4,
accept/1, transport_accept/1, finish_accept/1,
recv/3, send/2, close/1, port/1, peername/1,
- setopts/2, getopts/2, type/1]).
+ setopts/2, getopts/2, type/1, exit_if_closed/1]).
-define(ACCEPT_TIMEOUT, 2000).
-define(SSL_TIMEOUT, 10000).
@@ -142,3 +142,7 @@
type(_) ->
plain.
+exit_if_closed({error, closed}) ->
+ exit(normal);
+exit_if_closed(Res) ->
+ Res.
diff --git a/src/mochiweb_websocket.erl b/src/mochiweb_websocket.erl
index 2768a3e..ceb6bd6 100644
--- a/src/mochiweb_websocket.erl
+++ b/src/mochiweb_websocket.erl
@@ -32,7 +32,7 @@
-endif.
loop(Socket, Body, State, WsVersion, ReplyChannel) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}])),
proc_lib:hibernate(?MODULE, request,
[Socket, Body, State, WsVersion, ReplyChannel]).
@@ -206,7 +206,7 @@
_MaskKey:4/binary,
_/binary-unit:8>> = PartFrame,
Acc) ->
- ok = mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}]),
+ ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [{packet, 0}, {active, once}])),
receive
{tcp_closed, _} ->
mochiweb_socket:close(Socket),