~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/inets/src/http_server/mod_get.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%% ``The contents of this file are subject to the Erlang Public License,
 
2
%% Version 1.1, (the "License"); you may not use this file except in
 
3
%% compliance with the License. You should have received a copy of the
 
4
%% Erlang Public License along with this software. If not, it can be
 
5
%% retrieved via the world wide web at http://www.erlang.org/.
 
6
%% 
 
7
%% Software distributed under the License is distributed on an "AS IS"
 
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
9
%% the License for the specific language governing rights and limitations
 
10
%% under the License.
 
11
%% 
 
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 
14
%% AB. All Rights Reserved.''
 
15
%% 
 
16
%%     $Id$
 
17
%%
 
18
-module(mod_get).
 
19
-export([do/1]).
 
20
-include("httpd.hrl").
 
21
 
 
22
%% do
 
23
 
 
24
do(ModData) ->
 
25
    ?DEBUG("do -> entry",[]),
 
26
    case ModData#mod.method of
 
27
        "GET" ->
 
28
            case httpd_util:key1search(ModData#mod.data,status) of
 
29
                %% A status code has been generated!
 
30
                {_StatusCode, _PhraseArgs, _Reason} ->
 
31
                    {proceed,ModData#mod.data};
 
32
                %% No status code has been generated!
 
33
                undefined ->
 
34
                    case httpd_util:key1search(ModData#mod.data,response) of
 
35
                        %% No response has been generated!
 
36
                        undefined ->
 
37
                            do_get(ModData);
 
38
                        %% A response has been generated or sent!
 
39
                        _Response ->
 
40
                            {proceed,ModData#mod.data}
 
41
                    end
 
42
            end;
 
43
        %% Not a GET method!
 
44
        _ ->
 
45
            {proceed,ModData#mod.data}
 
46
    end.
 
47
 
 
48
 
 
49
do_get(ModData) ->
 
50
    ?DEBUG("do_get -> Request URI: ~p",[ModData#mod.request_uri]),
 
51
    Path = mod_alias:path(ModData#mod.data, ModData#mod.config_db, 
 
52
                          ModData#mod.request_uri),
 
53
    {FileInfo, LastModified} = get_modification_date(Path),
 
54
 
 
55
    send_response(ModData#mod.socket,ModData#mod.socket_type, Path, ModData, 
 
56
                  FileInfo, LastModified).
 
57
 
 
58
 
 
59
%% The common case when no range is specified
 
60
send_response(_Socket, _SocketType, Path, ModData, FileInfo, LastModified)->
 
61
    %% Send the file!
 
62
    %% Find the modification date of the file
 
63
    case file:open(Path,[raw,binary]) of
 
64
        {ok, FileDescriptor} ->
 
65
            ?DEBUG("do_get -> FileDescriptor: ~p",[FileDescriptor]),
 
66
            Suffix = httpd_util:suffix(Path),
 
67
            MimeType = httpd_util:lookup_mime_default(ModData#mod.config_db,
 
68
                                                      Suffix,"text/plain"),
 
69
            %% FileInfo = file:read_file_info(Path),
 
70
            Size = integer_to_list(FileInfo#file_info.size),
 
71
            Headers = case ModData#mod.http_version of
 
72
                         "HTTP/1.1" ->
 
73
                              [{content_type, MimeType},
 
74
                               {etag, httpd_util:create_etag(FileInfo)},
 
75
                               {content_length, Size}|LastModified];
 
76
                          %% OTP-4935
 
77
                         _ ->
 
78
                             %% i.e http/1.0 and http/0.9
 
79
                              [{content_type, MimeType},
 
80
                               {content_length, Size}|LastModified]
 
81
                          end,
 
82
            send(ModData, 200, Headers, FileDescriptor),
 
83
            file:close(FileDescriptor),
 
84
            {proceed,[{response,{already_sent,200,
 
85
                                 FileInfo#file_info.size}},
 
86
                      {mime_type,MimeType}|ModData#mod.data]};
 
87
        {error, Reason} ->
 
88
            {proceed,
 
89
             [{status,open_error(Reason,ModData,Path)}|ModData#mod.data]}
 
90
    end.
 
91
 
 
92
%% send
 
93
 
 
94
send(#mod{socket = Socket, socket_type = SocketType} = ModData,
 
95
     StatusCode, Headers, FileDescriptor) ->
 
96
    ?DEBUG("send -> send header",[]),
 
97
    httpd_response:send_header(ModData, StatusCode, Headers),
 
98
    send_body(SocketType,Socket,FileDescriptor).
 
99
 
 
100
 
 
101
send_body(SocketType,Socket,FileDescriptor) ->
 
102
    case file:read(FileDescriptor,?FILE_CHUNK_SIZE) of
 
103
        {ok,Binary} ->
 
104
            ?DEBUG("send_body -> send another chunk: ~p",[size(Binary)]),
 
105
            case httpd_socket:deliver(SocketType,Socket,Binary) of
 
106
                socket_closed ->
 
107
                    ?LOG("send_body -> socket closed while sending",[]),
 
108
                    socket_close;
 
109
                _ ->
 
110
                    send_body(SocketType,Socket,FileDescriptor)
 
111
            end;
 
112
        eof ->
 
113
            ?DEBUG("send_body -> done with this file",[]),
 
114
            eof
 
115
    end.
 
116
    
 
117
 
 
118
%% open_error - Handle file open failure
 
119
%%
 
120
open_error(eacces,ModData,Path) ->
 
121
    open_error(403,ModData,Path,"");
 
122
open_error(enoent,ModData,Path) ->
 
123
    open_error(404,ModData,Path,"");
 
124
open_error(enotdir,ModData,Path) ->
 
125
    open_error(404,ModData,Path,
 
126
               ": A component of the file name is not a directory");
 
127
open_error(emfile,_ModData,Path) ->
 
128
    open_error(500,none,Path,": To many open files");
 
129
open_error({enfile,_},_ModData,Path) ->
 
130
    open_error(500,none,Path,": File table overflow");
 
131
open_error(_Reason,_ModData,Path) ->
 
132
    open_error(500,none,Path,"").
 
133
            
 
134
open_error(StatusCode,none,Path,Reason) ->
 
135
    {StatusCode,none,?NICE("Can't open "++Path++Reason)};
 
136
open_error(StatusCode,ModData,Path,Reason) ->
 
137
    {StatusCode,ModData#mod.request_uri,?NICE("Can't open "++Path++Reason)}.
 
138
 
 
139
get_modification_date(Path)->
 
140
    {ok, FileInfo0} = file:read_file_info(Path), 
 
141
    LastModified = case catch httpd_util:rfc1123_date(FileInfo0#file_info.mtime) of
 
142
                       Date when is_list(Date) -> [{last_modified, Date}];
 
143
                       _ -> []
 
144
                   end,
 
145
    {FileInfo0, LastModified}.