Class: WEBrick::HTTPResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/webrick/httpresponse.rb

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (HTTPResponse) initialize(config)

A new instance of HTTPResponse



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/webrick/httpresponse.rb', line 29

def initialize(config)
  @config = config
  @buffer_size = config[:OutputBufferSize]
  @logger = config[:Logger]
  @header = Hash.new
  @status = HTTPStatus::RC_OK
  @reason_phrase = nil
  @http_version = HTTPVersion::convert(@config[:HTTPVersion])
  @body = ''
  @keep_alive = true
  @cookies = []
  @request_method = nil
  @request_uri = nil
  @request_http_version = @http_version  # temporary
  @chunked = false
  @filename = nil
  @sent_size = 0
end

Instance Attribute Details

- (Object) body

Returns the value of attribute body



22
23
24
# File 'lib/webrick/httpresponse.rb', line 22

def body
  @body
end

- (Object) config (readonly)

Returns the value of attribute config



27
28
29
# File 'lib/webrick/httpresponse.rb', line 27

def config
  @config
end

- (Object) cookies (readonly)

Returns the value of attribute cookies



20
21
22
# File 'lib/webrick/httpresponse.rb', line 20

def cookies
  @cookies
end

- (Object) filename

Returns the value of attribute filename



25
26
27
# File 'lib/webrick/httpresponse.rb', line 25

def filename
  @filename
end

- (Object) header (readonly)

Returns the value of attribute header



19
20
21
# File 'lib/webrick/httpresponse.rb', line 19

def header
  @header
end

- (Object) http_version (readonly)

Returns the value of attribute http_version



19
20
21
# File 'lib/webrick/httpresponse.rb', line 19

def http_version
  @http_version
end

- (Object) keep_alive

Returns the value of attribute keep_alive



26
27
28
# File 'lib/webrick/httpresponse.rb', line 26

def keep_alive
  @keep_alive
end

- (Object) reason_phrase

Returns the value of attribute reason_phrase



21
22
23
# File 'lib/webrick/httpresponse.rb', line 21

def reason_phrase
  @reason_phrase
end

- (Object) request_http_version

Returns the value of attribute request_http_version



24
25
26
# File 'lib/webrick/httpresponse.rb', line 24

def request_http_version
  @request_http_version
end

- (Object) request_method

Returns the value of attribute request_method



24
25
26
# File 'lib/webrick/httpresponse.rb', line 24

def request_method
  @request_method
end

- (Object) request_uri

Returns the value of attribute request_uri



24
25
26
# File 'lib/webrick/httpresponse.rb', line 24

def request_uri
  @request_uri
end

- (Object) sent_size (readonly)

Returns the value of attribute sent_size



27
28
29
# File 'lib/webrick/httpresponse.rb', line 27

def sent_size
  @sent_size
end

- (Object) status

Returns the value of attribute status



19
20
21
# File 'lib/webrick/httpresponse.rb', line 19

def status
  @status
end

Instance Method Details

- (Object) [](field)



57
58
59
# File 'lib/webrick/httpresponse.rb', line 57

def [](field)
  @header[field.downcase]
end

- (Object) []=(field, value)



61
62
63
# File 'lib/webrick/httpresponse.rb', line 61

def []=(field, value)
  @header[field.downcase] = value.to_s
end

- (Object) chunked=(val)



91
92
93
# File 'lib/webrick/httpresponse.rb', line 91

def chunked=(val)
  @chunked = val ? true : false
end

- (Boolean) chunked?

Returns:

  • (Boolean)


87
88
89
# File 'lib/webrick/httpresponse.rb', line 87

def chunked?
  @chunked
end

- (Object) content_length



65
66
67
68
69
# File 'lib/webrick/httpresponse.rb', line 65

def content_length
  if len = self['content-length']
    return Integer(len)
  end
end

- (Object) content_length=(len)



71
72
73
# File 'lib/webrick/httpresponse.rb', line 71

def content_length=(len)
  self['content-length'] = len.to_s
end

- (Object) content_type



75
76
77
# File 'lib/webrick/httpresponse.rb', line 75

def content_type
  self['content-type']
end

- (Object) content_type=(type)



79
80
81
# File 'lib/webrick/httpresponse.rb', line 79

def content_type=(type)
  self['content-type'] = type
end

- (Object) each



83
84
85
# File 'lib/webrick/httpresponse.rb', line 83

def each
  @header.each{|k, v|  yield(k, v) }
end

- (Boolean) keep_alive?

Returns:

  • (Boolean)


95
96
97
# File 'lib/webrick/httpresponse.rb', line 95

def keep_alive?
  @keep_alive
end

- (Object) send_body(socket)



183
184
185
186
187
188
# File 'lib/webrick/httpresponse.rb', line 183

def send_body(socket)
  case @body
  when IO then send_body_io(socket)
  else send_body_string(socket)
  end
end

- (Object) send_header(socket)



168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/webrick/httpresponse.rb', line 168

def send_header(socket)
  if @http_version.major > 0
    data = status_line()
    @header.each{|key, value|
      tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase }
      data << "#{tmp}: #{value}" << CRLF
    }
    @cookies.each{|cookie|
      data << "Set-Cookie: " << cookie.to_s << CRLF
    }
    data << CRLF
    _write_data(socket, data)
  end
end

- (Object) send_response(socket)



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/webrick/httpresponse.rb', line 99

def send_response(socket)
  begin
    setup_header()
    send_header(socket)
    send_body(socket)
  rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex
    @logger.debug(ex)
    @keep_alive = false
  rescue Exception => ex
    @logger.error(ex)
    @keep_alive = false
  end
end

- (Object) set_error(ex, backtrace = false)



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/webrick/httpresponse.rb', line 202

def set_error(ex, backtrace=false)
  case ex
  when HTTPStatus::Status
    @keep_alive = false if HTTPStatus::error?(ex.code)
    self.status = ex.code
  else
    @keep_alive = false
    self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
  end
  @header['content-type'] = "text/html; charset=utf-8"

  if respond_to?(:create_error_page)
    create_error_page()
    return
  end

  if @request_uri
    host, port = @request_uri.host, @request_uri.port
  else
    host, port = @config[:ServerName], @config[:Port]
  end

  @body = ''
  @body << <<-_end_of_html_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>
  <BODY>
<H1>#{HTMLUtils::escape(@reason_phrase)}</H1>
#{HTMLUtils::escape(ex.message)}
<HR>
  _end_of_html_

  if backtrace && $DEBUG
    @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' "
    @body << "#{HTMLUtils::escape(ex.message)}"
    @body << "<PRE>"
    ex.backtrace.each{|line| @body << "\t#{line}\n"}
    @body << "</PRE><HR>"
  end

  @body << <<-_end_of_html_
<ADDRESS>
 #{HTMLUtils::escape(@config[:ServerSoftware])} at
 #{host}:#{port}
</ADDRESS>
  </BODY>
</HTML>
  _end_of_html_
end

- (Object) set_redirect(status, url)



196
197
198
199
200
# File 'lib/webrick/httpresponse.rb', line 196

def set_redirect(status, url)
  @body = "<HTML><A HREF=\"#{url.to_s}\">#{url.to_s}</A>.</HTML>\n"
  @header['location'] = url.to_s
  raise status
end

- (Object) setup_header



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/webrick/httpresponse.rb', line 113

def setup_header()
  @reason_phrase    ||= HTTPStatus::reason_phrase(@status)
  @header['server'] ||= @config[:ServerSoftware]
  @header['date']   ||= Time.now.httpdate

  # HTTP/0.9 features
  if @request_http_version < "1.0"
    @http_version = HTTPVersion.new("0.9")
    @keep_alive = false
  end

  # HTTP/1.0 features
  if @request_http_version < "1.1"
    if chunked?
      @chunked = false
      ver = @request_http_version.to_s
      msg = "chunked is set for an HTTP/#{ver} request. (ignored)"
      @logger.warn(msg)
    end
  end

  # Determine the message length (RFC2616 -- 4.4 Message Length)
  if @status == 304 || @status == 204 || HTTPStatus::info?(@status)
    @header.delete('content-length')
    @body = ""
  elsif chunked?
    @header["transfer-encoding"] = "chunked"
    @header.delete('content-length')
  elsif %r{^multipart/byteranges} =~ @header['content-type']
    @header.delete('content-length')
  elsif @header['content-length'].nil?
    unless @body.is_a?(IO)
      @header['content-length'] = @body ? @body.bytesize : 0
    end
  end

  # Keep-Alive connection.
  if @header['connection'] == "close"
     @keep_alive = false
  elsif keep_alive?
    if chunked? || @header['content-length']
      @header['connection'] = "Keep-Alive"
    end
  else
    @header['connection'] = "close"
  end

  # Location is a single absoluteURI.
  if location = @header['location']
    if @request_uri
      @header['location'] = @request_uri.merge(location)
    end
  end
end

- (Object) status_line



48
49
50
# File 'lib/webrick/httpresponse.rb', line 48

def status_line
  "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
end

- (Object) to_s



190
191
192
193
194
# File 'lib/webrick/httpresponse.rb', line 190

def to_s
  ret = ""
  send_response(ret)
  ret
end