/src/mochiweb.erl

http://github.com/basho/mochiweb · Erlang · 101 lines · 55 code · 11 blank · 35 comment · 1 complexity · 7300b773552c4e1404a179f33ef1d2a8 MD5 · raw file

  1. %% @author Bob Ippolito <bob@mochimedia.com>
  2. %% @copyright 2007 Mochi Media, Inc.
  3. %%
  4. %% Permission is hereby granted, free of charge, to any person obtaining a
  5. %% copy of this software and associated documentation files (the "Software"),
  6. %% to deal in the Software without restriction, including without limitation
  7. %% the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. %% and/or sell copies of the Software, and to permit persons to whom the
  9. %% Software is furnished to do so, subject to the following conditions:
  10. %%
  11. %% The above copyright notice and this permission notice shall be included in
  12. %% all copies or substantial portions of the Software.
  13. %%
  14. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. %% DEALINGS IN THE SOFTWARE.
  21. %% @doc Start and stop the MochiWeb server.
  22. -module(mochiweb).
  23. -author('bob@mochimedia.com').
  24. -export([new_request/1, new_response/1]).
  25. -export([all_loaded/0, all_loaded/1, reload/0]).
  26. -export([ensure_started/1]).
  27. reload() ->
  28. [c:l(Module) || Module <- all_loaded()].
  29. all_loaded() ->
  30. all_loaded(filename:dirname(code:which(?MODULE))).
  31. all_loaded(Base) when is_atom(Base) ->
  32. [];
  33. all_loaded(Base) ->
  34. FullBase = Base ++ "/",
  35. F = fun ({_Module, Loaded}, Acc) when is_atom(Loaded) ->
  36. Acc;
  37. ({Module, Loaded}, Acc) ->
  38. case lists:prefix(FullBase, Loaded) of
  39. true ->
  40. [Module | Acc];
  41. false ->
  42. Acc
  43. end
  44. end,
  45. lists:foldl(F, [], code:all_loaded()).
  46. %% See the erlang:decode_packet/3 docs for the full type
  47. -spec uri(HttpUri :: term()) -> string().
  48. uri({abs_path, Uri}) ->
  49. Uri;
  50. %% TODO:
  51. %% This makes it hard to implement certain kinds of proxies with mochiweb,
  52. %% perhaps a field could be added to the mochiweb_request record to preserve
  53. %% this information in raw_path.
  54. uri({absoluteURI, _Protocol, _Host, _Port, Uri}) ->
  55. Uri;
  56. %% From http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
  57. uri('*') ->
  58. "*";
  59. %% Erlang decode_packet will return this for requests like `CONNECT host:port`
  60. uri({scheme, Hostname, Port}) ->
  61. Hostname ++ ":" ++ Port;
  62. uri(HttpString) when is_list(HttpString) ->
  63. HttpString.
  64. %% @spec new_request( {Socket, Request, Headers}
  65. %% | {Socket, Opts, Request, Headers} ) -> MochiWebRequest
  66. %% @doc Return a mochiweb_request data structure.
  67. new_request({Socket, {Method, HttpUri, Version}, Headers}) ->
  68. new_request({Socket, [], {Method, HttpUri, Version}, Headers});
  69. new_request({Socket, Opts, {Method, HttpUri, Version}, Headers}) ->
  70. mochiweb_request:new(Socket,
  71. Opts,
  72. Method,
  73. uri(HttpUri),
  74. Version,
  75. mochiweb_headers:make(Headers)).
  76. %% @spec new_response({Request, integer(), Headers}) -> MochiWebResponse
  77. %% @doc Return a mochiweb_response data structure.
  78. new_response({Request, Code, Headers}) ->
  79. mochiweb_response:new(Request,
  80. Code,
  81. mochiweb_headers:make(Headers)).
  82. %% @spec ensure_started(App::atom()) -> ok
  83. %% @doc Start the given App if it has not been started already.
  84. ensure_started(App) ->
  85. case application:start(App) of
  86. ok ->
  87. ok;
  88. {error, {already_started, App}} ->
  89. ok
  90. end.