Class: UV::Http::Parser

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



30
31
32
33
34
35
# File 'lib/uv-rays/http/parser.rb', line 30

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

Instance Attribute Details

#reasonObject

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



145
146
147
# File 'lib/uv-rays/http/parser.rb', line 145

def reason
  @reason
end

#requestObject (readonly)

Returns the value of attribute request.



38
39
40
# File 'lib/uv-rays/http/parser.rb', line 38

def request
  @request
end

Instance Method Details

#eofObject



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/uv-rays/http/parser.rb', line 146

def eof
    return if @request.nil?

    if @headers_complete && (@headers[:'Content-Length'].nil? || @request.method == :head)
        on_message_complete(nil)
    else
        # Reject if this is a partial response
        @request.reject(@reason || :partial_response)
        cleanup
    end
end

#new_request(request) ⇒ Object



41
42
43
44
45
46
# File 'lib/uv-rays/http/parser.rb', line 41

def new_request(request)
    @headers = nil
    @request = request
    @headers_complete = false
    @state.reset!
end

#on_body(parser, data) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/uv-rays/http/parser.rb', line 123

def on_body(parser, data)
    if @request.streaming?
        @request.notify(data)
    else
        @body << data
    end
end

#on_header_field(parser, data) ⇒ Object



81
82
83
# File 'lib/uv-rays/http/parser.rb', line 81

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

#on_header_value(parser, data) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/uv-rays/http/parser.rb', line 85

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'

    end

    current = @headers[@header]
    if current
        @headers[@header] = "#{current}, #{data}"
    else
        @headers[@header] = data
    end
end

#on_headers_complete(parser) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/uv-rays/http/parser.rb', line 108

def on_headers_complete(parser)
    @headers_complete = true

    # 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:



63
64
65
66
67
68
# File 'lib/uv-rays/http/parser.rb', line 63

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

#on_message_complete(parser) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/uv-rays/http/parser.rb', line 131

def on_message_complete(parser)
    @headers.body = @body

    if @request.resolve(@headers)
        cleanup
    else
        req = @request
        cleanup
        new_request(req)
    end
end

#on_status(parser, data) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/uv-rays/http/parser.rb', line 70

def on_status(parser, data)
    @headers.reason_phrase = data

    # Different HTTP versions have different defaults
    if @state.http_minor == 0
        @close_connection = true
    else
        @close_connection = false
    end
end

#received(data) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/uv-rays/http/parser.rb', line 48

def received(data)
    if @parser.parse(@state, data)
        if @request
            @request.reject(@state.error)
            @request = nil
            @response = nil
            return true
        end
    end

    false
end