PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/misultin_socket.erl

http://github.com/ostinelli/misultin
Erlang | 129 lines | 65 code | 17 blank | 47 comment | 0 complexity | e26c85c29dfd56f61dc062e6bc65d0d6 MD5 | raw file
  1. % ==========================================================================================================
  2. % MISULTIN - Socket
  3. %
  4. % >-|-|-(°>
  5. %
  6. % Copyright (C) 2011, Roberto Ostinelli <roberto@ostinelli.net>, Sean Hinde.
  7. % All rights reserved.
  8. %
  9. % Code portions from Sean Hinde have been originally taken under BSD license from Trapexit at the address:
  10. % <http://www.trapexit.org/A_fast_web_server_demonstrating_some_undocumented_Erlang_features>
  11. %
  12. % BSD License
  13. %
  14. % Redistribution and use in source and binary forms, with or without modification, are permitted provided
  15. % that the following conditions are met:
  16. %
  17. % * Redistributions of source code must retain the above copyright notice, this list of conditions and the
  18. % following disclaimer.
  19. % * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
  20. % the following disclaimer in the documentation and/or other materials provided with the distribution.
  21. % * Neither the name of the authors nor the names of its contributors may be used to endorse or promote
  22. % products derived from this software without specific prior written permission.
  23. %
  24. % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
  25. % WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. % PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. % ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  28. % TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29. % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. % NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. % POSSIBILITY OF SUCH DAMAGE.
  32. % ==========================================================================================================
  33. -module(misultin_socket).
  34. -vsn("0.9").
  35. % API
  36. -export([listen/3, accept/2, controlling_process/3, peername/2, peercert/2, setopts/3, recv/4, send/3, close/2]).
  37. % includes
  38. -include("../include/misultin.hrl").
  39. % ============================ \/ API ======================================================================
  40. % socket listen
  41. -spec listen(Port::non_neg_integer(), Options::gen_proplist(), socketmode()) -> {ok, ListenSock::socket()} | {error, Reason::term()}.
  42. listen(Port, Options, http) -> gen_tcp:listen(Port, Options);
  43. listen(Port, Options, ssl) -> ssl:listen(Port, Options).
  44. % socket accept
  45. -spec accept(ListenSocket::socket(), socketmode()) -> {ok, ListenSock::socket()} | {error, Reason::term()}.
  46. accept(ListenSocket, http) -> gen_tcp:accept(ListenSocket);
  47. accept(ListenSocket, ssl) ->
  48. try ssl:transport_accept(ListenSocket)
  49. catch
  50. error:{badmatch, {error, Reason}} ->
  51. {error, Reason}
  52. end.
  53. % socket controlling process
  54. -spec controlling_process(Sock::socket(), Pid::pid(), socketmode()) -> ok | {error, Reason::term()}.
  55. controlling_process(Sock, Pid, http) -> gen_tcp:controlling_process(Sock, Pid);
  56. controlling_process(Sock, Pid, ssl) -> ssl:controlling_process(Sock, Pid).
  57. % Get socket peername
  58. -spec peername(Sock::socket(), socketmode() | function()) -> {inet:ip_address(), non_neg_integer()}.
  59. peername(Sock, http) -> peername(Sock, fun inet:peername/1);
  60. peername(Sock, ssl) -> peername(Sock, fun ssl:peername/1);
  61. peername(Sock, F) ->
  62. case F(Sock) of
  63. {ok, {Addr, Port}} ->
  64. {Addr, Port};
  65. {error, _Reason} ->
  66. {undefined, undefined}
  67. end.
  68. % Get socket certificate
  69. -spec peercert(Sock::socket(), socketmode()) -> Cert::term() | undefined.
  70. peercert(_Sock, http) -> undefined;
  71. peercert(Sock, ssl) ->
  72. case ssl:peercert(Sock) of
  73. {ok, Cert} -> Cert;
  74. {error, _Reason} -> undefined
  75. end.
  76. % socket set options
  77. -spec setopts(Sock::socket(), Options::gen_proplist_options(), socketmode()) -> ok | {error, Reason::term()}.
  78. setopts(Sock, Options, http) -> inet:setopts(Sock, Options);
  79. setopts(Sock, Options, ssl) -> ssl:setopts(Sock, Options).
  80. % socket receive
  81. -spec recv(Sock::socket(), Len::non_neg_integer(), RecvTimeout::non_neg_integer(), socketmode()) -> {ok, Data::list() | binary()} | {error, Reason::term()}.
  82. recv(Sock, Len, RecvTimeout, http) -> gen_tcp:recv(Sock, Len, RecvTimeout);
  83. recv(Sock, Len, RecvTimeout, ssl) -> ssl:recv(Sock, Len, RecvTimeout).
  84. % socket send
  85. -spec send(Sock::socket(), Data::binary() | iolist() | list(), socketmode() | function()) -> ok.
  86. send(Sock, Data, http) -> send(Sock, Data, fun gen_tcp:send/2);
  87. send(Sock, Data, ssl) -> send(Sock, Data, fun ssl:send/2);
  88. send(Sock, Data, F) ->
  89. ?LOG_DEBUG("sending data: ~p", [Data]),
  90. case F(Sock, Data) of
  91. ok ->
  92. ok;
  93. {error, _Reason} ->
  94. ?LOG_ERROR("error sending data: ~p", [_Reason]),
  95. exit(kill)
  96. end.
  97. % TCP close
  98. -spec close(Sock::socket(), socketmode() | function()) -> ok.
  99. close(Sock, http) -> close(Sock, fun gen_tcp:close/1);
  100. close(Sock, ssl) -> close(Sock, fun ssl:close/1);
  101. close(Sock, F) ->
  102. ?LOG_DEBUG("closing socket", []),
  103. case catch F(Sock) of
  104. ok ->
  105. ok;
  106. _Else ->
  107. ?LOG_WARNING("could not close socket: ~p", [_Else]),
  108. exit(kill)
  109. end.
  110. % ============================ /\ API ======================================================================
  111. % ============================ \/ INTERNAL FUNCTIONS =======================================================
  112. % ============================ /\ INTERNAL FUNCTIONS =======================================================