Subversion Repositories SE.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12 7u83 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
 
22
%% @doc Start and stop the MochiWeb server.
23
 
24
-module(mochiweb).
25
-author('bob@mochimedia.com').
26
 
27
-export([new_request/1, new_response/1]).
28
-export([all_loaded/0, all_loaded/1, reload/0]).
29
-export([ensure_started/1]).
30
 
31
reload() ->
32
    [c:l(Module) || Module <- all_loaded()].
33
 
34
all_loaded() ->
35
    all_loaded(filename:dirname(code:which(?MODULE))).
36
 
37
all_loaded(Base) when is_atom(Base) ->
38
    [];
39
all_loaded(Base) ->
40
    FullBase = Base ++ "/",
41
    F = fun ({_Module, Loaded}, Acc) when is_atom(Loaded) ->
42
                Acc;
43
            ({Module, Loaded}, Acc) ->
44
                case lists:prefix(FullBase, Loaded) of
45
                    true ->
46
                        [Module | Acc];
47
                    false ->
48
                        Acc
49
                end
50
        end,
51
    lists:foldl(F, [], code:all_loaded()).
52
 
53
%% See the erlang:decode_packet/3 docs for the full type
54
-spec uri(HttpUri :: term()) -> string().
55
uri({abs_path, Uri}) ->
56
    Uri;
57
%% TODO:
58
%% This makes it hard to implement certain kinds of proxies with mochiweb,
59
%% perhaps a field could be added to the mochiweb_request record to preserve
60
%% this information in raw_path.
61
uri({absoluteURI, _Protocol, _Host, _Port, Uri}) ->
62
    Uri;
63
%% From http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
64
uri('*') ->
65
    "*";
66
%% Erlang decode_packet will return this for requests like `CONNECT host:port`
67
uri({scheme, Hostname, Port}) ->
68
    Hostname ++ ":" ++ Port;
69
uri(HttpString) when is_list(HttpString) ->
70
    HttpString.
71
 
72
%% @spec new_request( {Socket, Request, Headers}
73
%%                  | {Socket, Opts, Request, Headers} ) -> MochiWebRequest
74
%% @doc Return a mochiweb_request data structure.
75
new_request({Socket, {Method, HttpUri, Version}, Headers}) ->
76
    new_request({Socket, [], {Method, HttpUri, Version}, Headers});
77
 
78
new_request({Socket, Opts, {Method, HttpUri, Version}, Headers}) ->
79
    mochiweb_request:new(Socket,
80
                         Opts,
81
                         Method,
82
                         uri(HttpUri),
83
                         Version,
84
                         mochiweb_headers:make(Headers)).
85
 
86
%% @spec new_response({Request, integer(), Headers}) -> MochiWebResponse
87
%% @doc Return a mochiweb_response data structure.
88
new_response({Request, Code, Headers}) ->
89
    mochiweb_response:new(Request,
90
                          Code,
91
                          mochiweb_headers:make(Headers)).
92
 
93
%% @spec ensure_started(App::atom()) -> ok
94
%% @doc Start the given App if it has not been started already.
95
ensure_started(App) ->
96
    case application:start(App) of
97
        ok ->
98
            ok;
99
        {error, {already_started, App}} ->
100
            ok
101
    end.