httpray 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -3
- data/lib/httpray/version.rb +1 -1
- data/lib/httpray.rb +13 -4
- data/test/httpray_test.rb +7 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94354672b454e3ffb1f53a0d0704157c4a3208c2
|
4
|
+
data.tar.gz: 755940a03eedb6095bf8b8c7c2a5174b85d3125e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18e91441b0908e96d8f45c2d76fce167c855dd5b4526976b811e7918c2932a52d98eba43e497d2816fb06cfeede05cfdab531e18c9858b2a5459840753967127
|
7
|
+
data.tar.gz: c94caa608c92993d0856aada6f22fafbf9498950d2816b3219a32de4502cf6c4080eaa364210c0133877d20d0e8bd0113fb7c0422bf2624a80fcfc355375f1bf
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Non-blocking HTTP library for Ruby
|
|
5
5
|
|
6
6
|
Started out the same as the [fire-and-forget](https://github.com/mattetti/fire-and-forget) gem but with a more exposed interface, TLS support, and a better name. Added ideas from [tcp_timeout](https://github.com/lann/tcp-timeout-ruby) and accidentally ended up creating a light-weight, non-blocking HTTP client.
|
7
7
|
|
8
|
-
It differs from other Ruby HTTP libraries that support async because it doesn't use Threads, making HTTPray much less resource intensive to use since it instead directly implements HTTP/HTTPS 1.0 using `Socket` and `IO#select` for timeouts. You can optionally ask to be handed back the socket before it is closed in case you want to listen for a response, but that's not really what you're here for
|
8
|
+
It differs from other Ruby HTTP libraries that support async because it doesn't use Threads, making HTTPray much less resource intensive to use since it instead directly implements HTTP/HTTPS 1.0 using `Socket` and `IO#select` for timeouts. You can optionally ask to be handed back the socket before it is closed in case you want to listen for a response, but that's not really what you're here for.
|
9
9
|
|
10
10
|
Great for use with sending data to HTTP endpoints for which you are willing to accept a UDP-style best-effort approach, but with the added guarantee of TCP that the packets made it to the server. Only the server will know what it did with the data, though!
|
11
11
|
|
@@ -30,7 +30,7 @@ HTTPray.request(
|
|
30
30
|
"It's me, Margret",
|
31
31
|
1) # timeout in seconds
|
32
32
|
|
33
|
-
# party with a response
|
33
|
+
# party with a response, but costs a Fiber
|
34
34
|
HTTPray.request("GET", "https://your.diety/answered_prayers") do |socket|
|
35
35
|
socket.gets
|
36
36
|
end
|
@@ -39,11 +39,26 @@ end
|
|
39
39
|
socket = HTTPray.request!("GET", "https://your.diety/answered_prayers")
|
40
40
|
puts socket.gets
|
41
41
|
socket.close
|
42
|
+
|
43
|
+
# use a persistent connection to keep the party rolling
|
44
|
+
# will automatically reconnect if connection is lost
|
45
|
+
uri = URI.parse("https://your.diety/pray")
|
46
|
+
ark = HTTPray::Connection.new(uri.host, uri.port, 1, OpenSSL::SSL::SSLContext.new)
|
47
|
+
ark.request("POST", uri,
|
48
|
+
{"Content-Type" => "application/prayer"},
|
49
|
+
"Why did it have to be snakes?")
|
50
|
+
ark.socket.close
|
51
|
+
ark.request("POST", uri,
|
52
|
+
{"Content-Type" => "application/prayer"},
|
53
|
+
"Don't call me junior!")
|
54
|
+
|
42
55
|
```
|
43
56
|
|
44
57
|
## Help
|
45
58
|
|
46
|
-
HTTPray has minimal convenience and sanitization features because I didn't need them. All that it does is fill in the Host, User-Agent, Accept, and Content-Length headers for you. The body must be a string, so convert it yourself first. The URI can be a `URI` or a `String` that will go through `URI.parse`. You're welcome.
|
59
|
+
HTTPray has minimal convenience and sanitization features because I didn't need them. All that it does is fill in the Host, User-Agent, Accept, and Content-Length headers for you. The body must be a string, so convert it yourself first. The URI can be a `URI` or a `String` that will go through `URI.parse`. You're welcome.
|
60
|
+
|
61
|
+
If you're using `Connection` with TLS you need to provide an `OpenSSL::SSL::SSLContext` when creating the connection. `HTTPray.request!` is more forgiving and if you don't give it one it will create it for you if needed.
|
47
62
|
|
48
63
|
Timeout support does not extend to the response since you just get back a `Socket`. You're own your own for how you want to handle that.
|
49
64
|
|
data/lib/httpray/version.rb
CHANGED
data/lib/httpray.rb
CHANGED
@@ -9,15 +9,17 @@ module HTTPray
|
|
9
9
|
|
10
10
|
DEFAULT_HEADERS = {
|
11
11
|
"User-Agent" => "HTTPray #{VERSION}",
|
12
|
-
"Accept" => "*/*"
|
12
|
+
"Accept" => "*/*",
|
13
|
+
"Connection" => "keep-alive"
|
13
14
|
}.freeze
|
14
15
|
|
15
16
|
class Connection
|
16
|
-
def initialize(host, port, timeout = 1, ssl_context = nil)
|
17
|
+
def initialize(host, port, timeout = 1, ssl_context = nil, retry_count = 1)
|
17
18
|
@host = host
|
18
19
|
@port = port
|
19
20
|
@timeout = timeout
|
20
21
|
@ssl_context = ssl_context
|
22
|
+
@retry_count = retry_count
|
21
23
|
@socket = connect
|
22
24
|
end
|
23
25
|
|
@@ -28,6 +30,7 @@ module HTTPray
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def request!(method, uri, headers = {}, body = nil)
|
33
|
+
tries ||= 0
|
31
34
|
begin
|
32
35
|
IO.select([@socket], [@socket], [@socket], @timeout) if @socket
|
33
36
|
rescue; end
|
@@ -45,6 +48,12 @@ module HTTPray
|
|
45
48
|
socket.write_nonblock "\r\n"
|
46
49
|
socket.write_nonblock body if body
|
47
50
|
socket
|
51
|
+
rescue
|
52
|
+
@socket.close
|
53
|
+
if tries < @retry_count
|
54
|
+
tries += 1
|
55
|
+
retry
|
56
|
+
end
|
48
57
|
end
|
49
58
|
|
50
59
|
def request(*args)
|
@@ -100,8 +109,8 @@ module HTTPray
|
|
100
109
|
uri = URI.parse(uri) unless URI === uri
|
101
110
|
ssl_context = nil
|
102
111
|
ssl_context = OpenSSL::SSL::SSLContext.new if uri.scheme == "https"
|
103
|
-
ark = Connection.new(uri.host, uri.port, timeout, ssl_context)
|
104
|
-
ark.request!(method, uri, headers, body)
|
112
|
+
ark = Connection.new(uri.host, uri.port, timeout, ssl_context, 0)
|
113
|
+
ark.request!(method, uri, {"Connection" => ""}.merge(headers), body)
|
105
114
|
end
|
106
115
|
|
107
116
|
def self.request(*args)
|
data/test/httpray_test.rb
CHANGED
@@ -99,4 +99,11 @@ class HTTPrayTest < MiniTest::Test
|
|
99
99
|
ark.request("GET", uri)
|
100
100
|
refute_same original_socket, ark.socket
|
101
101
|
end
|
102
|
+
def test_retries_on_random_errors
|
103
|
+
uri = URI.parse("http://httpbin.org/deny")
|
104
|
+
ark = HTTPray::Connection.new(uri.host, uri.port, 1, nil)
|
105
|
+
ark.socket.stub(:write_nonblock, lambda { |*args| raise "Broken pipe" }) do
|
106
|
+
ark.request("GET", uri, {"Connection" => ""})
|
107
|
+
end
|
108
|
+
end
|
102
109
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpray
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- G Gordon Worley III
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Fire-and-forget HTTP requests for Ruby
|
14
14
|
email:
|