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

#initialize(requests) ⇒ Response



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

def initialize(requests)
    @requests = requests

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

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



26
27
28
# File 'lib/uv-rays/http/response.rb', line 26

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[:'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



108
109
110
111
112
113
# File 'lib/uv-rays/http/response.rb', line 108

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



69
70
71
# File 'lib/uv-rays/http/response.rb', line 69

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

#on_header_value(parser, data) ⇒ Object



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

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



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

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:



53
54
55
56
57
58
# File 'lib/uv-rays/http/response.rb', line 53

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

#on_message_complete(parser) ⇒ Object



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

def on_message_complete(parser)
    @request.resolve(@body)

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

#on_status(parser, data) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/uv-rays/http/response.rb', line 60

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



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

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



30
31
32
# File 'lib/uv-rays/http/response.rb', line 30

def reset!
    @state.reset!
end