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

« back to all changes in this revision

Viewing changes to lib/webrick/httpresponse.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/httpstatus'
16
16
 
17
17
module WEBrick
 
18
  ##
 
19
  # An HTTP response.
 
20
 
18
21
  class HTTPResponse
19
22
    attr_reader :http_version, :status, :header
20
23
    attr_reader :cookies
21
24
    attr_accessor :reason_phrase
 
25
 
 
26
    ##
 
27
    # Body may be a String or IO subclass.
 
28
 
22
29
    attr_accessor :body
23
30
 
24
31
    attr_accessor :request_method, :request_uri, :request_http_version
26
33
    attr_accessor :keep_alive
27
34
    attr_reader :config, :sent_size
28
35
 
 
36
    ##
 
37
    # Creates a new HTTP response object
 
38
 
29
39
    def initialize(config)
30
40
      @config = config
31
41
      @buffer_size = config[:OutputBufferSize]
45
55
      @sent_size = 0
46
56
    end
47
57
 
 
58
    ##
 
59
    # The response's HTTP status line
 
60
 
48
61
    def status_line
49
62
      "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
50
63
    end
51
64
 
 
65
    ##
 
66
    # Sets the response's status to the +status+ code
 
67
 
52
68
    def status=(status)
53
69
      @status = status
54
70
      @reason_phrase = HTTPStatus::reason_phrase(status)
55
71
    end
56
72
 
 
73
    ##
 
74
    # Retrieves the response header +field+
 
75
 
57
76
    def [](field)
58
77
      @header[field.downcase]
59
78
    end
60
79
 
 
80
    ##
 
81
    # Sets the response header +field+ to +value+
 
82
 
61
83
    def []=(field, value)
62
84
      @header[field.downcase] = value.to_s
63
85
    end
64
86
 
 
87
    ##
 
88
    # The content-length header
 
89
 
65
90
    def content_length
66
91
      if len = self['content-length']
67
92
        return Integer(len)
68
93
      end
69
94
    end
70
95
 
 
96
    ##
 
97
    # Sets the content-length header to +len+
 
98
 
71
99
    def content_length=(len)
72
100
      self['content-length'] = len.to_s
73
101
    end
74
102
 
 
103
    ##
 
104
    # The content-type header
 
105
 
75
106
    def content_type
76
107
      self['content-type']
77
108
    end
78
109
 
 
110
    ##
 
111
    # Sets the content-type header to +type+
 
112
 
79
113
    def content_type=(type)
80
114
      self['content-type'] = type
81
115
    end
82
116
 
 
117
    ##
 
118
    # Iterates over each header in the resopnse
 
119
 
83
120
    def each
84
 
      @header.each{|k, v|  yield(k, v) }
 
121
      @header.each{|field, value|  yield(field, value) }
85
122
    end
86
123
 
 
124
    ##
 
125
    # Will this response body be returned using chunked transfer-encoding?
 
126
 
87
127
    def chunked?
88
128
      @chunked
89
129
    end
90
130
 
 
131
    ##
 
132
    # Enables chunked transfer encoding.
 
133
 
91
134
    def chunked=(val)
92
135
      @chunked = val ? true : false
93
136
    end
94
137
 
 
138
    ##
 
139
    # Will this response's connection be kept alive?
 
140
 
95
141
    def keep_alive?
96
142
      @keep_alive
97
143
    end
98
144
 
 
145
    ##
 
146
    # Sends the response on +socket+
 
147
 
99
148
    def send_response(socket)
100
149
      begin
101
150
        setup_header()
110
159
      end
111
160
    end
112
161
 
 
162
    ##
 
163
    # Sets up the headers for sending
 
164
 
113
165
    def setup_header()
114
166
      @reason_phrase    ||= HTTPStatus::reason_phrase(@status)
115
167
      @header['server'] ||= @config[:ServerSoftware]
152
204
      elsif keep_alive?
153
205
        if chunked? || @header['content-length']
154
206
          @header['connection'] = "Keep-Alive"
 
207
        else
 
208
          msg = "Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true"
 
209
          @logger.warn(msg)
 
210
          @header['connection'] = "close"
 
211
          @keep_alive = false
155
212
        end
156
213
      else
157
214
        @header['connection'] = "close"
165
222
      end
166
223
    end
167
224
 
 
225
    ##
 
226
    # Sends the headers on +socket+
 
227
 
168
228
    def send_header(socket)
169
229
      if @http_version.major > 0
170
230
        data = status_line()
180
240
      end
181
241
    end
182
242
 
 
243
    ##
 
244
    # Sends the body on +socket+
 
245
 
183
246
    def send_body(socket)
184
247
      case @body
185
248
      when IO then send_body_io(socket)
187
250
      end
188
251
    end
189
252
 
190
 
    def to_s
 
253
    def to_s # :nodoc:
191
254
      ret = ""
192
255
      send_response(ret)
193
256
      ret
194
257
    end
195
258
 
 
259
    ##
 
260
    # Redirects to +url+ with a WEBrick::HTTPStatus::Redirect +status+.
 
261
    #
 
262
    # Example:
 
263
    #
 
264
    #   res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect
 
265
 
196
266
    def set_redirect(status, url)
197
267
      @body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
198
268
      @header['location'] = url.to_s
199
269
      raise status
200
270
    end
201
271
 
 
272
    ##
 
273
    # Creates an error page for exception +ex+ with an optional +backtrace+
 
274
 
202
275
    def set_error(ex, backtrace=false)
203
276
      case ex
204
277
      when HTTPStatus::Status
280
353
      if @request_method == "HEAD"
281
354
        # do nothing
282
355
      elsif chunked?
283
 
        remain = body ? @body.bytesize : 0
 
356
        body ? @body.bytesize : 0
284
357
        while buf = @body[@sent_size, @buffer_size]
285
358
          break if buf.empty?
286
359
          data = ""