Class: UV::HttpEndpoint

Inherits:
OutboundConnection show all
Defined in:
lib/uv-rays/http_endpoint.rb

Constant Summary collapse

TRANSFER_ENCODING =
"TRANSFER_ENCODING".freeze
CONTENT_ENCODING =
"CONTENT_ENCODING".freeze
CONTENT_LENGTH =
"CONTENT_LENGTH".freeze
CONTENT_TYPE =
"CONTENT_TYPE".freeze
LAST_MODIFIED =
"LAST_MODIFIED".freeze
KEEP_ALIVE =
"CONNECTION".freeze
LOCATION =
"LOCATION".freeze
HOST =
"HOST".freeze
ETAG =
"ETAG".freeze
CRLF =
"\r\n".freeze
HTTPS =
"https://".freeze
HTTP =
"http://".freeze
@@defaults =
{
    :path => '/',
    :keepalive => true
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from OutboundConnection

#reconnect, #use_tls

Methods inherited from TcpConnection

#close_connection, #keepalive, #stream_file, #write

Methods inherited from Connection

#close_connection, #pause, #paused?, #post_init, #resume

Constructor Details

#initialize(uri, options = {}) ⇒ HttpEndpoint

Returns a new instance of HttpEndpoint.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/uv-rays/http_endpoint.rb', line 52

def initialize(uri, options = {})
    @connect_timeout     = options[:connect_timeout] ||= 5        # default connection setup timeout

    @inactivity_timeout  = options[:inactivity_timeout] ||= 10   # default connection inactivity (post-setup) timeout



    uri = uri.kind_of?(Addressable::URI) ? uri : Addressable::URI::parse(uri.to_s)
    @https = uri.scheme == "https"
    uri.port ||= (@https ? 443 : 80)
    @scheme = @https ? HTTPS : HTTP


    @loop = Libuv::Loop.current || Libuv::Loop.default
    @host = uri.host
    @port = uri.port
    #@transport = @loop.tcp


    # State flags

    @ready = false
    @connecting = false

    # Current requests

    @pending_requests = []
    @pending_responses = []
    @connection_pending = []
    @cookiejar = CookieJar.new

    # Callback methods

    @connection_method = method(:get_connection)
    @next_request_method = method(:next_request)
    @idle_timeout_method = method(:idle_timeout)
    @connect_timeout_method = method(:connect_timeout)

    # Used to indicate when we can start the next send

    @breakpoint = ::Libuv::Q::ResolvedPromise.new(@loop, true)

    # Manages the tokenising of response from the input stream

    @response = Http::Response.new(@pending_responses)

    # Timeout timer

    if @connect_timeout || @inactivity_timeout
        @timer = @loop.timer
    end
end

Instance Attribute Details

#cookiejarObject (readonly)

Returns the value of attribute cookiejar.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def cookiejar
  @cookiejar
end

#hostObject (readonly)

Returns the value of attribute host.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def host
  @host
end

#inactivity_timeoutObject (readonly)

Returns the value of attribute inactivity_timeout.



50
51
52
# File 'lib/uv-rays/http_endpoint.rb', line 50

def inactivity_timeout
  @inactivity_timeout
end

#loopObject (readonly)

Returns the value of attribute loop.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def loop
  @loop
end

#portObject (readonly)

Returns the value of attribute port.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def port
  @port
end

#schemeObject (readonly)

Returns the value of attribute scheme.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def scheme
  @scheme
end

#using_tlsObject (readonly)

Returns the value of attribute using_tls.



49
50
51
# File 'lib/uv-rays/http_endpoint.rb', line 49

def using_tls
  @using_tls
end

Instance Method Details

#delete(options = {}, &blk) ⇒ Object



99
# File 'lib/uv-rays/http_endpoint.rb', line 99

def delete   options = {}, &blk;  request(:delete,  options, &blk); end

#get(options = {}, &blk) ⇒ Object



97
# File 'lib/uv-rays/http_endpoint.rb', line 97

def get      options = {}, &blk;  request(:get,     options, &blk); end

#head(options = {}, &blk) ⇒ Object



98
# File 'lib/uv-rays/http_endpoint.rb', line 98

def head     options = {}, &blk;  request(:head,    options, &blk); end

#middlewareObject



136
137
138
139
# File 'lib/uv-rays/http_endpoint.rb', line 136

def middleware
    # TODO:: allow for middle ware

    []
end

#on_closeObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/uv-rays/http_endpoint.rb', line 150

def on_close
    @ready = false
    @connecting = false
    stop_timer

    # Flush any processing request

    @response.eof if @response.request

    # Reject any requests waiting on a response

    @pending_responses.each do |request|
        request.reject(:disconnected)
    end
    @pending_responses.clear
    
    # Re-connect if there are pending requests

    if not @connection_pending.empty?
        do_connect
    end
end

#on_connect(transport) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/uv-rays/http_endpoint.rb', line 170

def on_connect(transport)
    @connecting = false
    @ready = true

    # start tls if connection is encrypted

    use_tls() if @https

    # Update timeouts

    stop_timer
    if @inactivity_timeout > 0
        @timer.progress @idle_timeout_method
        @timer.start @inactivity_timeout * 1000
    end

    # Kick off pending requests

    @response.reset!
    @connection_pending.each do |callback|
        callback.call
    end
    @connection_pending.clear
end

#on_read(data, *args) ⇒ Object



141
142
143
144
145
146
147
148
# File 'lib/uv-rays/http_endpoint.rb', line 141

def on_read(data, *args)
    @timer.again if @inactivity_timeout > 0
    # returns true on error

    # Response rejects the request

    if @response.receive(data)
        @transport.close
    end
end

#options(options = {}, &blk) ⇒ Object



103
# File 'lib/uv-rays/http_endpoint.rb', line 103

def options  options = {}, &blk;  request(:options, options, &blk); end

#patch(options = {}, &blk) ⇒ Object



102
# File 'lib/uv-rays/http_endpoint.rb', line 102

def patch    options = {}, &blk;  request(:patch,   options, &blk); end

#post(options = {}, &blk) ⇒ Object



101
# File 'lib/uv-rays/http_endpoint.rb', line 101

def post     options = {}, &blk;  request(:post,    options, &blk); end

#put(options = {}, &blk) ⇒ Object



100
# File 'lib/uv-rays/http_endpoint.rb', line 100

def put      options = {}, &blk;  request(:put,     options, &blk); end

#request(method, options = {}, &blk) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/uv-rays/http_endpoint.rb', line 106

def request(method, options = {}, &blk)
    options = @@defaults.merge(options)
    options[:method] = method

    # Setup the request with callbacks

    request = Http::Request.new(self, options)
    request.then proc { |result|
        if !result[:headers].keep_alive
            @transport.close
        end
        result
    }

    ##

    # TODO:: Add response middleware here

    request.then blk if blk

    # Add to pending requests and schedule using the breakpoint

    @pending_requests << request
    @breakpoint.finally @next_request_method
    if options[:pipeline] == true
        options[:keepalive] = true
    else
        @breakpoint = request
    end

    # return the request

    request
end