# WEBrick::HTTPResponse (Class)

In: | webrick/httpresponse.rb
Parent: | Object

## Methods

[] []= chunked= chunked? each keep_alive? new send_body send_header send_response set_error set_redirect setup_header status= status_line to_s

## Constants

BUFSIZE | = | 1024*4

## Attributes

body | [RW] |
config | [R] |
cookies | [R] |
filename | [RW] |
header | [R] |
http_version | [R] |
keep_alive | [RW] |
reason_phrase | [RW] |
request_http_version | [RW] |
request_method | [RW] |
request_uri | [RW] |
sent_size | [R] |
status | [R] |

## Public Class methods

new(config)

[Source]

    # File webrick/httpresponse.rb, line 31
        def initialize(config)
          @config = config
          @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

## Public Instance methods

status_line()

[Source]

    # File webrick/httpresponse.rb, line 49
        def status_line
          "HTTP/#@http_version #@status #@reason_phrase #{CRLF}"
        end

status=(status)

[Source]

    # File webrick/httpresponse.rb, line 53
        def status=(status)
          @status = status
          @reason_phrase = HTTPStatus::reason_phrase(status)
        end

[](field)

[Source]

    # File webrick/httpresponse.rb, line 58
        def [](field)
          @header[field.downcase]
        end

[]=(field, value)

[Source]

    # File webrick/httpresponse.rb, line 62
        def []=(field, value)
          @header[field.downcase] = value.to_s
        end

each() {|k, v| ...}

[Source]

    # File webrick/httpresponse.rb, line 66
        def each
          @header.each{|k, v|  yield(k, v) }
        end

chunked?()

[Source]

    # File webrick/httpresponse.rb, line 70
        def chunked?
          @chunked
        end

chunked=(val)

[Source]

    # File webrick/httpresponse.rb, line 74
        def chunked=(val)
          @chunked = val ? true : false
        end

keep_alive?()

[Source]

    # File webrick/httpresponse.rb, line 78
        def keep_alive?
          @keep_alive
        end

send_response(socket)

[Source]

    # File webrick/httpresponse.rb, line 82
        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

setup_header()

[Source]

    # File webrick/httpresponse.rb, line 96
        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

          # Determin 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 %{^multipart/byteranges} =~ @header['content-type']
            @header.delete('content-length')
          elsif @header['content-length'].nil?
            unless @body.is_a?(IO)
              @header['content-length'] = @body ? @body.size : 0
            end
          end

          # Keep-Alive connection.

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

          # Location is a single absoluteURI.

          if location = @header['location']
            if @request_uri
              @header['location'] = @request_uri.merge(location)
            end
          end
        end

send_header(socket)

[Source]

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

send_body(socket)

[Source]

    # File webrick/httpresponse.rb, line 165
        def send_body(socket)
          case @body
          when IO then send_body_io(socket)
          else send_body_string(socket)
          end
        end

to_s()

[Source]

    # File webrick/httpresponse.rb, line 172
        def to_s
          ret = ""
          send_response(ret)
          ret
        end

set_redirect(status, url)

[Source]

    # File webrick/httpresponse.rb, line 178
        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

set_error(ex, backtrace=false)

[Source]

    # File webrick/httpresponse.rb, line 184
        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"

          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 << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n<HTML>\n<HEAD><TITLE>\#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>\n<BODY>\n<H1>\#{HTMLUtils::escape(@reason_phrase)}</H1>\n\#{HTMLUtils::escape(ex.message)}\n<HR>\n"

          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 << "<ADDRESS>\n\#{HTMLUtils::escape(@config[:ServerSoftware])} at\n\#{host}:\#{port}\n</ADDRESS>\n</BODY>\n</HTML>\n"
        end

[Validate]