Class WEBrick::HTTPResponse
In: webrick/httpresponse.rb
Parent: Object

Methods

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

[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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

# File webrick/httpresponse.rb, line 66
    def content_length
      if len = self['content-length']
        return Integer(len)
      end
    end

[Source]

# File webrick/httpresponse.rb, line 72
    def content_length=(len)
      self['content-length'] = len.to_s
    end

[Source]

# File webrick/httpresponse.rb, line 76
    def content_type
      self['content-type']
    end

[Source]

# File webrick/httpresponse.rb, line 80
    def content_type=(type)
      self['content-type'] = type
    end

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

# File webrick/httpresponse.rb, line 114
    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 %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.size : 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

[Source]

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

[Source]

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

[Source]

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

[Validate]