# encoding: utf-8 module HTTPkit class Response NOT_INCLUDED = [204, 304] NOT_PRESENT = [205] include Support::Message include Adamantium attr_reader :status, :headers, :body, :http_version def initialize(status, headers = {}, body = '', http_version = 1.1) @status = status @headers = headers @body = Body.build(body) @http_version = http_version end def with_headers(new_headers) with(1, headers.merge(new_headers)) end def with_body(new_body) with(2, Body.build(new_body)) end def with(index, argument) args = [status, headers, body, http_version] args[index] = argument new_self(args) end def new_self(args) self.class.new(*args) end def body_included? !informational? && !NOT_INCLUDED.include?(status) end def body_present? !informational? && !NOT_PRESENT.include?(status) end def status_name STATUS_NAMES[status.to_i] || UNKNOWN_STATUS end def status_class status / 100 end def informational? status_class == 1 end def successful? status_class == 2 end def redirection? status_class == 3 end def client_error? status_class == 4 end def server_error? status_class == 5 end UNKNOWN_STATUS = 'Unknown Status'.freeze # TODO: double-check with RFC7230 STATUS_NAMES = { 100 => 'Continue'.freeze, 101 => 'Switching Protocols'.freeze, 102 => 'Processing'.freeze, 200 => 'OK'.freeze, 201 => 'Created'.freeze, 202 => 'Accepted'.freeze, 203 => 'Non-Authoritative Information'.freeze, 204 => 'No Content'.freeze, 205 => 'Reset Content'.freeze, 206 => 'Partial Content'.freeze, 207 => 'Multi-Status'.freeze, 208 => 'Already Reported'.freeze, 226 => 'IM Used'.freeze, 300 => 'Multiple Choices'.freeze, 301 => 'Moved Permanently'.freeze, 302 => 'Found'.freeze, 303 => 'See Other'.freeze, 304 => 'Not Modified'.freeze, 305 => 'Use Proxy'.freeze, 306 => 'Reserved'.freeze, 307 => 'Temporary Redirect'.freeze, 308 => 'Permanent Redirect'.freeze, 400 => 'Bad Request'.freeze, 401 => 'Unauthorized'.freeze, 402 => 'Payment Required'.freeze, 403 => 'Forbidden'.freeze, 404 => 'Not Found'.freeze, 405 => 'Method Not Allowed'.freeze, 406 => 'Not Acceptable'.freeze, 407 => 'Proxy Authentication Required'.freeze, 408 => 'Request Timeout'.freeze, 409 => 'Conflict'.freeze, 410 => 'Gone'.freeze, 411 => 'Length Required'.freeze, 412 => 'Precondition Failed'.freeze, 413 => 'Request Entity Too Large'.freeze, 414 => 'Request-URI Too Long'.freeze, 415 => 'Unsupported Media Type'.freeze, 416 => 'Requested Range Not Satisfiable'.freeze, 417 => 'Expectation Failed'.freeze, 422 => 'Unprocessable Entity'.freeze, 423 => 'Locked'.freeze, 424 => 'Failed Dependency'.freeze, 425 => 'Reserved for WebDAV advanced collections expired proposal'.freeze, 426 => 'Upgrade Required'.freeze, 427 => 'Unassigned'.freeze, 428 => 'Precondition Required'.freeze, 429 => 'Too Many Requests'.freeze, 430 => 'Unassigned'.freeze, 431 => 'Request Header Fields Too Large'.freeze, 500 => 'Internal Server Error'.freeze, 501 => 'Not Implemented'.freeze, 502 => 'Bad Gateway'.freeze, 503 => 'Service Unavailable'.freeze, 504 => 'Gateway Timeout'.freeze, 505 => 'HTTP Version Not Supported'.freeze, 506 => 'Variant Also Negotiates (Experimental)'.freeze, 507 => 'Insufficient Storage'.freeze, 508 => 'Loop Detected'.freeze, 509 => 'Unassigned'.freeze, 510 => 'Not Extended'.freeze, 511 => 'Network Authentication Required'.freeze } end end