Class: UV::Http::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/uv-rays/http/response.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResponse



17
18
19
20
21
# File 'lib/uv-rays/http/response.rb', line 17

def initialize
    @parser = ::HttpParser::Parser.new(self)
    @state = ::HttpParser::Parser.new_instance
    @state.type = :response
end

Instance Attribute Details

#requestObject

Returns the value of attribute request.



24
25
26
# File 'lib/uv-rays/http/response.rb', line 24

def request
  @request
end

Instance Method Details

#eofObject

We need to flush the response on disconnect if content-length is undefined As per the HTTP spec



125
126
127
128
129
130
131
132
# File 'lib/uv-rays/http/response.rb', line 125

def eof
    if @headers.nil? && @request.headers && @request.headers[:'Content-Length'].nil?
        on_message_complete(nil)
    else
        # Reject if this is a partial response
        @request.reject(:partial_response)
    end
end

#on_body(parser, data) ⇒ Object



105
106
107
108
109
110
# File 'lib/uv-rays/http/response.rb', line 105

def on_body(parser, data)
    @body << data
    # TODO:: What if it is a chunked response body?
    # We should buffer complete chunks
    @request.notify(data)
end

#on_header_field(parser, data) ⇒ Object



66
67
68
# File 'lib/uv-rays/http/response.rb', line 66

def on_header_field(parser, data)
    @header = data.to_sym
end

#on_header_value(parser, data) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/uv-rays/http/response.rb', line 70

def on_header_value(parser, data)
    case @header
    when :"Set-Cookie"
        @request.set_cookie(data)

    when :Connection
        # Overwrite the default
        @close_connection = data == 'close'

    when :"Transfer-Encoding"
        # If chunked we'll buffer streaming data for notification
        @chunked = data == 'chunked'

    else
        @headers[@header] = data
    end
end

#on_headers_complete(parser) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/uv-rays/http/response.rb', line 88

def on_headers_complete(parser)
    headers = @headers
    @headers = nil
    @header = nil

    # https://github.com/joyent/http-parser indicates we should extract
    # this information here
    headers.http_version = @state.http_version
    headers.status = @state.http_status
    headers.cookies = @request.cookies_hash
    headers.keep_alive = !@close_connection

    # User code may throw an error
    # Errors will halt the processing and return a PAUSED error
    @request.set_headers(headers)
end

#on_message_begin(parser) ⇒ Object

Parser Callbacks:



51
52
53
54
55
# File 'lib/uv-rays/http/response.rb', line 51

def on_message_begin(parser)
    @headers = Headers.new
    @body = ''
    @chunked = false
end

#on_message_complete(parser) ⇒ Object



112
113
114
115
116
117
118
119
120
121
# File 'lib/uv-rays/http/response.rb', line 112

def on_message_complete(parser)
    req = @request
    bod = @body

    # Clean up memory
    @request = nil
    @body = nil

    req.resolve(self, bod)
end

#on_status(parser, data) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/uv-rays/http/response.rb', line 57

def on_status(parser, data)
    # Different HTTP versions have different defaults
    if @state.http_minor == 0
        @close_connection = true
    else
        @close_connection = false
    end
end

#receive(data) ⇒ Object

Socket level data is forwarded as it arrives



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/uv-rays/http/response.rb', line 33

def receive(data)
    # Returns true if error
    if @parser.parse(@state, data)
        if @request
            @request.reject(@state.error)
            @request = nil
            return true
        #else # silently fail here
        #    p 'parse error and no request..'
        #    p @state.error
        end
    end

    false
end

#reset!Object

Called on connection disconnect



28
29
30
# File 'lib/uv-rays/http/response.rb', line 28

def reset!
    @state.reset!
end