| %% @copyright 2010 Mochi Media, Inc. |
| |
| %% @doc MochiWeb socket - wrapper for plain and ssl sockets. |
| |
| -module(mochiweb_socket). |
| |
| -export([listen/4, accept/1, after_accept/1, recv/3, send/2, close/1, port/1, peername/1, |
| setopts/2, type/1]). |
| |
| -define(ACCEPT_TIMEOUT, 2000). |
| -define(SSL_ACCEPT_TIMEOUT, 30000). |
| |
| listen(Ssl, Port, Opts, SslOpts) -> |
| case Ssl of |
| true -> |
| case ssl:listen(Port, Opts ++ SslOpts) of |
| {ok, ListenSocket} -> |
| {ok, {ssl, ListenSocket}}; |
| {error, _} = Err -> |
| Err |
| end; |
| false -> |
| gen_tcp:listen(Port, Opts) |
| end. |
| |
| accept({ssl, ListenSocket}) -> |
| % There's a bug in ssl:transport_accept/2 at the moment, which is the |
| % reason for the try...catch block. Should be fixed in OTP R14. |
| try ssl:transport_accept(ListenSocket, ?ACCEPT_TIMEOUT) of |
| {ok, Socket} -> |
| {ok, {ssl, Socket}}; |
| {error, _} = Err -> |
| Err |
| catch |
| error:{badmatch, {error, Reason}} -> |
| {error, Reason} |
| end; |
| accept(ListenSocket) -> |
| gen_tcp:accept(ListenSocket, ?ACCEPT_TIMEOUT). |
| |
| after_accept({ssl, Socket}) -> ssl:ssl_accept(Socket, ?SSL_ACCEPT_TIMEOUT); |
| after_accept(_Socket) -> ok. |
| |
| recv({ssl, Socket}, Length, Timeout) -> |
| ssl:recv(Socket, Length, Timeout); |
| recv(Socket, Length, Timeout) -> |
| gen_tcp:recv(Socket, Length, Timeout). |
| |
| send({ssl, Socket}, Data) -> |
| ssl:send(Socket, Data); |
| send(Socket, Data) -> |
| gen_tcp:send(Socket, Data). |
| |
| close({ssl, Socket}) -> |
| ssl:close(Socket); |
| close(Socket) -> |
| gen_tcp:close(Socket). |
| |
| port({ssl, Socket}) -> |
| case ssl:sockname(Socket) of |
| {ok, {_, Port}} -> |
| {ok, Port}; |
| {error, _} = Err -> |
| Err |
| end; |
| port(Socket) -> |
| inet:port(Socket). |
| |
| peername({ssl, Socket}) -> |
| ssl:peername(Socket); |
| peername(Socket) -> |
| inet:peername(Socket). |
| |
| setopts({ssl, Socket}, Opts) -> |
| ssl:setopts(Socket, Opts); |
| setopts(Socket, Opts) -> |
| inet:setopts(Socket, Opts). |
| |
| type({ssl, _}) -> |
| ssl; |
| type(_) -> |
| plain. |
| |