~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to lib/webrick/httprequest.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
require 'webrick/cookie'
16
16
 
17
17
module WEBrick
 
18
 
 
19
  ##
 
20
  # An HTTP request.
18
21
  class HTTPRequest
 
22
 
19
23
    BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ]
20
24
 
21
 
    # Request line
 
25
    # :section: Request line
22
26
    attr_reader :request_line
23
27
    attr_reader :request_method, :unparsed_uri, :http_version
24
28
 
25
 
    # Request-URI
 
29
    # :section: Request-URI
26
30
    attr_reader :request_uri, :path
27
31
    attr_accessor :script_name, :path_info, :query_string
28
32
 
29
 
    # Header and entity body
 
33
    # :section: Header and entity body
30
34
    attr_reader :raw_header, :header, :cookies
31
35
    attr_reader :accept, :accept_charset
32
36
    attr_reader :accept_encoding, :accept_language
33
37
 
34
 
    # Misc
 
38
    # :section:
35
39
    attr_accessor :user
36
40
    attr_reader :addr, :peeraddr
37
41
    attr_reader :attributes
122
126
      end
123
127
    end
124
128
 
 
129
    # Generate HTTP/1.1 100 continue response if the client expects it,
 
130
    # otherwise does nothing.
 
131
    def continue
 
132
      if self['expect'] == '100-continue' && @config[:HTTPVersion] >= "1.1"
 
133
        @socket << "HTTP/#{@config[:HTTPVersion]} 100 continue#{CRLF}#{CRLF}"
 
134
        @header.delete('expect')
 
135
      end
 
136
    end
 
137
 
125
138
    def body(&block)
126
139
      block ||= Proc.new{|chunk| @body << chunk }
127
140
      read_body(@socket, block)
128
141
      @body.empty? ? nil : @body
129
142
    end
130
143
 
 
144
    ##
 
145
    # Request query as a Hash
 
146
 
131
147
    def query
132
148
      unless @query
133
149
        parse_query()
135
151
      @query
136
152
    end
137
153
 
 
154
    ##
 
155
    # The content-length header
 
156
 
138
157
    def content_length
139
158
      return Integer(self['content-length'])
140
159
    end
141
160
 
 
161
    ##
 
162
    # The content-type header
 
163
 
142
164
    def content_type
143
165
      return self['content-type']
144
166
    end
145
167
 
 
168
    ##
 
169
    # Retrieves +header_name+
 
170
 
146
171
    def [](header_name)
147
172
      if @header
148
173
        value = @header[header_name.downcase]
150
175
      end
151
176
    end
152
177
 
 
178
    ##
 
179
    # Iterates over the request headers
 
180
 
153
181
    def each
154
 
      @header.each{|k, v|
155
 
        value = @header[k]
156
 
        yield(k, value.empty? ? nil : value.join(", "))
157
 
      }
 
182
      if @header
 
183
        @header.each{|k, v|
 
184
          value = @header[k]
 
185
          yield(k, value.empty? ? nil : value.join(", "))
 
186
        }
 
187
      end
158
188
    end
159
189
 
 
190
    ##
 
191
    # The host this request is for
 
192
 
160
193
    def host
161
194
      return @forwarded_host || @host
162
195
    end
163
196
 
 
197
    ##
 
198
    # The port this request is for
 
199
 
164
200
    def port
165
201
      return @forwarded_port || @port
166
202
    end
167
203
 
 
204
    ##
 
205
    # The server name this request is for
 
206
 
168
207
    def server_name
169
208
      return @forwarded_server || @config[:ServerName]
170
209
    end
171
210
 
 
211
    ##
 
212
    # The client's IP address
 
213
 
172
214
    def remote_ip
173
215
      return self["client-ip"] || @forwarded_for || @peeraddr[3]
174
216
    end
175
217
 
 
218
    ##
 
219
    # Is this an SSL request?
 
220
 
176
221
    def ssl?
177
222
      return @request_uri.scheme == "https"
178
223
    end
179
224
 
 
225
    ##
 
226
    # Should the connection this request was made on be kept alive?
 
227
 
180
228
    def keep_alive?
181
229
      @keep_alive
182
230
    end
183
231
 
184
 
    def to_s
 
232
    def to_s # :nodoc:
185
233
      ret = @request_line.dup
186
234
      @raw_header.each{|line| ret << line }
187
235
      ret << CRLF
201
249
      end
202
250
    end
203
251
 
 
252
    # This method provides the metavariables defined by the revision 3
 
253
    # of "The WWW Common Gateway Interface Version 1.1"
 
254
    # http://Web.Golux.Com/coar/cgi/
 
255
 
204
256
    def meta_vars
205
 
      # This method provides the metavariables defined by the revision 3
206
 
      # of ``The WWW Common Gateway Interface Version 1.1''.
207
 
      # (http://Web.Golux.Com/coar/cgi/)
208
 
 
209
257
      meta = Hash.new
210
258
 
211
259
      cl = self["Content-Length"]
242
290
 
243
291
    private
244
292
 
 
293
    MAX_URI_LENGTH = 2083 # :nodoc:
 
294
 
245
295
    def read_request_line(socket)
246
 
      @request_line = read_line(socket, 1024) if socket
247
 
      if @request_line.bytesize >= 1024 and @request_line[-1, 1] != LF
 
296
      @request_line = read_line(socket, MAX_URI_LENGTH) if socket
 
297
      if @request_line.bytesize >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
248
298
        raise HTTPStatus::RequestURITooLarge
249
299
      end
250
300
      @request_time = Time.now
273
323
      if @config[:Escape8bitURI]
274
324
        str = HTTPUtils::escape8bit(str)
275
325
      end
 
326
      str.sub!(%r{\A/+}o, '/')
276
327
      uri = URI::parse(str)
277
328
      return uri if uri.absolute?
278
329
      if @forwarded_host
385
436
      ^(::ffff:)?(10|172\.(1[6-9]|2[0-9]|3[01])|192\.168)\.
386
437
    /ixo
387
438
 
 
439
    # It's said that all X-Forwarded-* headers will contain more than one
 
440
    # (comma-separated) value if the original request already contained one of
 
441
    # these headers. Since we could use these values as Host header, we choose
 
442
    # the initial(first) value. (apr_table_mergen() adds new value after the
 
443
    # existing value with ", " prefix)
388
444
    def setup_forwarded_info
389
 
      @forwarded_server = self["x-forwarded-server"]
 
445
      if @forwarded_server = self["x-forwarded-server"]
 
446
        @forwarded_server = @forwarded_server.split(",", 2).first
 
447
      end
390
448
      @forwarded_proto = self["x-forwarded-proto"]
391
449
      if host_port = self["x-forwarded-host"]
 
450
        host_port = host_port.split(",", 2).first
392
451
        @forwarded_host, tmp = host_port.split(":", 2)
393
452
        @forwarded_port = (tmp || (@forwarded_proto == "https" ? 443 : 80)).to_i
394
453
      end