Class: Ebb::Response

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

Constant Summary collapse

HTTP_STATUS_CODES =
{
  100  => 'Continue', 
  101  => 'Switching Protocols', 
  200  => 'OK', 
  201  => 'Created', 
  202  => 'Accepted', 
  203  => 'Non-Authoritative Information', 
  204  => 'No Content', 
  205  => 'Reset Content', 
  206  => 'Partial Content', 
  300  => 'Multiple Choices', 
  301  => 'Moved Permanently', 
  302  => 'Moved Temporarily', 
  303  => 'See Other', 
  304  => 'Not Modified', 
  305  => 'Use Proxy', 
  400  => 'Bad Request', 
  401  => 'Unauthorized', 
  402  => 'Payment Required', 
  403  => 'Forbidden', 
  404  => 'Not Found', 
  405  => 'Method Not Allowed', 
  406  => 'Not Acceptable', 
  407  => 'Proxy Authentication Required', 
  408  => 'Request Time-out', 
  409  => 'Conflict', 
  410  => 'Gone', 
  411  => 'Length Required', 
  412  => 'Precondition Failed', 
  413  => 'Request Entity Too Large', 
  414  => 'Request-URI Too Large', 
  415  => 'Unsupported Media Type', 
  500  => 'Internal Server Error', 
  501  => 'Not Implemented', 
  502  => 'Bad Gateway', 
  503  => 'Service Unavailable', 
  504  => 'Gateway Time-out', 
  505  => 'HTTP Version not supported'
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, last) ⇒ Response

Returns a new instance of Response.



163
164
165
166
167
168
169
# File 'lib/ebb.rb', line 163

def initialize(connection, last)
  @connection = connection
  @last = last
  @output = []
  @finished = false
  @chunked = false 
end

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



162
163
164
# File 'lib/ebb.rb', line 162

def connection
  @connection
end

#lastObject

Returns the value of attribute last.



162
163
164
# File 'lib/ebb.rb', line 162

def last
  @last
end

#outputObject (readonly)

Returns the value of attribute output.



161
162
163
# File 'lib/ebb.rb', line 161

def output
  @output
end

Instance Method Details

#call(status, headers, body) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/ebb.rb', line 171

def call(status, headers, body)
  @head = "HTTP/1.1 #{status} #{HTTP_STATUS_CODES[status.to_i]}\r\n"

  # Hack to be compatible with frameworks who return Strings.
  if body.kind_of?(String)
    headers["Content-Length"] = body.length.to_s
    body = [body]
  end

  # XXX i would prefer to do
  # @chunked = true unless body.respond_to?(:length)
  if headers["Transfer-Encoding"] == "chunked" or 
     !headers.has_key?("Content-Length") 
  then
    headers["Transfer-Encoding"] = "chunked"
    @chunked = true 
  end
  # I also don't like this
  @last = true if headers["Connection"] == "close"

  headers.each { |field, value| @head << "#{field}: #{value}\r\n" }
  @head << "\r\n"
  
  body.each do |chunk| 
    write(chunk) 
  end

  body.on_error { close } if body.respond_to?(:on_error)

  if body.respond_to?(:on_eof)
    body.on_eof { finish }
  else
    finish
  end

  # deferred requests SHOULD NOT respond to close
  body.close if body.respond_to?(:close)
end

#finishObject



214
215
216
217
# File 'lib/ebb.rb', line 214

def finish
  @finished = true 
  write("") if @chunked
end

#finished?Boolean

Returns:

  • (Boolean)


210
211
212
# File 'lib/ebb.rb', line 210

def finished?
  @output.empty? and @finished
end

#write(chunk) ⇒ Object



219
220
221
222
223
224
225
226
227
228
# File 'lib/ebb.rb', line 219

def write(chunk)
  encoded = @chunked ? "#{chunk.length.to_s(16)}\r\n#{chunk}\r\n" : chunk
  if @head.nil?
    @output << encoded
  else
    @output << @head + encoded
    @head = nil
  end
  @connection.write
end