net-http-pipeline 0.0

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.
@@ -0,0 +1,2 @@
1
+ '75
2
+ �Vq�א�D�r}���
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
@@ -0,0 +1,6 @@
1
+ === 0.0 / 2010-12-07
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/net/http/pipeline.rb
7
+ sample/two_get.rb
8
+ test/test_net_http_pipeline.rb
@@ -0,0 +1,60 @@
1
+ = net-http-pipeline
2
+
3
+ * http://seattlerb.rubyforge.org/net-http-pipeline
4
+ * http://github.com/drbrain/net-http-pipeline
5
+
6
+ == DESCRIPTION:
7
+
8
+ An HTTP/1.1 pipelining implementation atop Net::HTTP. This is an experimental
9
+ proof of concept.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * Provides HTTP/1.1 pipelining
14
+ * Does not implement request wrangling per RFC 2616 8.1.2.2
15
+ * Does not handle errors
16
+ * May not work on Ruby 1.8, untested
17
+
18
+ == SYNOPSIS:
19
+
20
+ require 'net/http/pipeline'
21
+
22
+ Net::HTTP.start 'localhost' do |http|
23
+ req1 = Net::HTTP::Get.new '/'
24
+ req2 = Net::HTTP::Get.new '/'
25
+
26
+ http.pipeline req1, req2 do |res|
27
+ puts res.code
28
+ puts res.body[0..60].inspect
29
+ puts
30
+ end
31
+ end
32
+
33
+ == INSTALL:
34
+
35
+ gem install net-http-pipeline
36
+
37
+ == LICENSE:
38
+
39
+ (The MIT License)
40
+
41
+ Copyright (c) 2010 Eric Hodel
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining
44
+ a copy of this software and associated documentation files (the
45
+ 'Software'), to deal in the Software without restriction, including
46
+ without limitation the rights to use, copy, modify, merge, publish,
47
+ distribute, sublicense, and/or sell copies of the Software, and to
48
+ permit persons to whom the Software is furnished to do so, subject to
49
+ the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be
52
+ included in all copies or substantial portions of the Software.
53
+
54
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
55
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
56
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
57
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
58
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
59
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
60
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugin :git
7
+ Hoe.plugin :minitest
8
+ Hoe.plugins.delete :rubyforge
9
+
10
+ Hoe.spec 'net-http-pipeline' do
11
+ developer 'Eric Hodel', 'drbrain@segment7.net'
12
+ end
13
+
14
+ # vim: syntax=Ruby
@@ -0,0 +1,103 @@
1
+ require 'net/http'
2
+
3
+ ##
4
+ # An HTTP/1.1 pipelining implementation atop Net::HTTP. Currently this is not
5
+ # compliant with RFC 2616 8.1.2.2.
6
+ #
7
+ # Pipeline allows pou to create a bunch of requests then pipeline them to an
8
+ # HTTP/1.1 server.
9
+ #
10
+ # = Example
11
+ #
12
+ # require 'net/http/pipeline'
13
+ #
14
+ # Net::HTTP.start 'localhost' do |http|
15
+ # req1 = Net::HTTP::Get.new '/'
16
+ # req2 = Net::HTTP::Get.new '/'
17
+ #
18
+ # http.pipeline req1, req2 do |res|
19
+ # puts res.code
20
+ # puts res.body[0..60].inspect
21
+ # puts
22
+ # end
23
+ # end
24
+
25
+ module Net::HTTP::Pipeline
26
+
27
+ VERSION = '0.0'
28
+
29
+ ##
30
+ # Pipeline error class
31
+
32
+ class Error < RuntimeError
33
+ end
34
+
35
+ ##
36
+ # Pipelines +requests+ to the HTTP server yielding responses if a block is
37
+ # given. Returns all responses recieved.
38
+ #
39
+ # Raises an exception if the connection is not pipelining-capable or if the
40
+ # HTTP session has not been started.
41
+
42
+ def pipeline *requests
43
+ raise Error, 'pipelining requires HTTP/1.1 or newer' unless
44
+ @curr_http_version >= '1.1'
45
+ raise Error, 'Net::HTTP not started' unless started?
46
+
47
+ requests.each do |req|
48
+ begin_transport req
49
+ req.exec @socket, @curr_http_version, edit_path(req.path)
50
+ end
51
+
52
+ responses = []
53
+
54
+ requests.each do |req|
55
+ begin
56
+ res = Net::HTTPResponse.read_new @socket
57
+ end while res.kind_of? Net::HTTPContinue
58
+
59
+ res.reading_body @socket, req.response_body_permitted? do
60
+ responses << res
61
+ yield res if block_given?
62
+ end
63
+
64
+ pipeline_end_transport res
65
+ end
66
+
67
+ responses
68
+ end
69
+
70
+ ##
71
+ # Updates the HTTP version and ensures the connection has keep-alive.
72
+
73
+ def pipeline_end_transport res
74
+ @curr_http_version = res.http_version
75
+
76
+ if @socket.closed? then
77
+ D 'Conn socket closed on pipeline'
78
+ elsif pipeline_keep_alive? res then
79
+ D 'Conn pipeline keep-alive'
80
+ else
81
+ D 'Conn close on pipeline'
82
+ @socket.close
83
+ end
84
+ end
85
+
86
+ ##
87
+ # Checks for an connection close header
88
+
89
+ def pipeline_keep_alive? res
90
+ not res.connection_close?
91
+ end
92
+
93
+ end
94
+
95
+ class Net::HTTP
96
+
97
+ ##
98
+ # Adds pipeline support to Net::HTTP
99
+
100
+ include Pipeline
101
+
102
+ end
103
+
@@ -0,0 +1,12 @@
1
+ require 'net/http/pipeline'
2
+
3
+ Net::HTTP.start 'localhost' do |http|
4
+ req1 = Net::HTTP::Get.new '/'
5
+ req2 = Net::HTTP::Get.new '/'
6
+
7
+ http.pipeline req1, req2 do |res|
8
+ puts res.code
9
+ puts res.body[0..60].inspect
10
+ puts
11
+ end
12
+ end
@@ -0,0 +1,200 @@
1
+ require "test/unit"
2
+ require 'net/http/pipeline'
3
+ require 'stringio'
4
+
5
+ class TestNetHttpPipeline < Test::Unit::TestCase
6
+
7
+ ##
8
+ # Net::BufferedIO stub
9
+
10
+ class Buffer
11
+ attr_accessor :read_io, :write_io
12
+ def initialize
13
+ @read_io = StringIO.new
14
+ @write_io = StringIO.new
15
+ @closed = false
16
+ end
17
+
18
+ def close
19
+ @closed = true
20
+ end
21
+
22
+ def closed?
23
+ @closed
24
+ end
25
+
26
+ def finish
27
+ @write_io.rewind
28
+ end
29
+
30
+ def read bytes, dest = '', ignored = nil
31
+ @read_io.read bytes, dest
32
+
33
+ dest
34
+ end
35
+
36
+ def readline
37
+ @read_io.readline.chomp "\r\n"
38
+ end
39
+
40
+ def readuntil terminator, ignored
41
+ @read_io.gets terminator
42
+ end
43
+
44
+ def start
45
+ @read_io.rewind
46
+ end
47
+
48
+ def write data
49
+ @write_io.write data
50
+ end
51
+ end
52
+
53
+ include Net::HTTP::Pipeline
54
+
55
+ attr_writer :started
56
+
57
+ def setup
58
+ @curr_http_version = '1.1'
59
+ @started = true
60
+ end
61
+
62
+ def D(*) end
63
+
64
+ def begin_transport req
65
+ end
66
+
67
+ def edit_path path
68
+ path
69
+ end
70
+
71
+ def http_response body, *extra_header
72
+ http_response = []
73
+ http_response << 'HTTP/1.1 200 OK'
74
+ http_response << "Content-Length: #{body.bytesize}"
75
+ http_response.push(*extra_header)
76
+ http_response.push nil, nil # Array chomps on #join
77
+
78
+ http_response.join("\r\n") << body
79
+ end
80
+
81
+ def response
82
+ r = Net::HTTPResponse.allocate
83
+ def r.http_version() Net::HTTP::HTTPVersion end
84
+ def r.read_body() true end
85
+
86
+ r.instance_variable_set :@header, {}
87
+ def r.header() @header end
88
+ r
89
+ end
90
+
91
+ def started?() @started end
92
+
93
+ def test_pipeline
94
+ @socket = Buffer.new
95
+
96
+ @socket.read_io.write http_response('Worked 1!')
97
+ @socket.read_io.write http_response('Worked 2!')
98
+
99
+ req1 = Net::HTTP::Get.new '/'
100
+ req2 = Net::HTTP::Get.new '/'
101
+
102
+ @socket.start
103
+
104
+ responses = pipeline req1, req2
105
+
106
+ @socket.finish
107
+
108
+ expected = <<-EXPECTED
109
+ GET / HTTP/1.1\r
110
+ Accept: */*\r
111
+ User-Agent: Ruby\r
112
+ \r
113
+ GET / HTTP/1.1\r
114
+ Accept: */*\r
115
+ User-Agent: Ruby\r
116
+ \r
117
+ EXPECTED
118
+
119
+ assert_equal expected, @socket.write_io.read
120
+ refute @socket.closed?
121
+
122
+ assert_equal 'Worked 1!', responses.first.body
123
+ assert_equal 'Worked 2!', responses.last.body
124
+ end
125
+
126
+ def test_pipeline_connection_close
127
+ @socket = Buffer.new
128
+
129
+ @socket.read_io.write http_response('Worked 1!', 'Connection: close')
130
+
131
+ req1 = Net::HTTP::Get.new '/'
132
+
133
+ @socket.start
134
+
135
+ pipeline req1
136
+
137
+ @socket.finish
138
+
139
+ assert @socket.closed?
140
+ end
141
+
142
+ def test_pipeline_http_1_0
143
+ @curr_http_version = '1.0'
144
+
145
+ e = assert_raises Net::HTTP::Pipeline::Error do
146
+ pipeline
147
+ end
148
+
149
+ assert_equal 'pipelining requires HTTP/1.1 or newer', e.message
150
+ end
151
+
152
+ def test_pipeline_not_started
153
+ @started = false
154
+
155
+ e = assert_raises Net::HTTP::Pipeline::Error do
156
+ pipeline
157
+ end
158
+
159
+ assert_equal 'Net::HTTP not started', e.message
160
+ end
161
+
162
+ def test_pipeline_end_transport
163
+ @curr_http_version = nil
164
+
165
+ res = response
166
+
167
+ @socket = StringIO.new
168
+
169
+ pipeline_end_transport res
170
+
171
+ refute @socket.closed?
172
+ assert_equal '1.1', @curr_http_version
173
+ end
174
+
175
+ def test_pipeline_end_transport_no_keep_alive
176
+ @curr_http_version = nil
177
+
178
+ res = response
179
+ res.header['connection'] = ['close']
180
+
181
+ @socket = StringIO.new
182
+
183
+ pipeline_end_transport res
184
+
185
+ assert @socket.closed?
186
+ assert_equal '1.1', @curr_http_version
187
+ end
188
+
189
+ def test_pipeline_keep_alive_eh
190
+ res = response
191
+
192
+ assert pipeline_keep_alive? res
193
+
194
+ res.header['connection'] = ['close']
195
+
196
+ refute pipeline_keep_alive? res
197
+ end
198
+
199
+ end
200
+
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-http-pipeline
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ version: "0.0"
9
+ platform: ruby
10
+ authors:
11
+ - Eric Hodel
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain:
15
+ - |
16
+ -----BEGIN CERTIFICATE-----
17
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
18
+ YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
19
+ ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk
20
+ cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
21
+ FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
22
+ LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
23
+ U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
24
+ Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
25
+ mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
26
+ g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
27
+ sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
28
+ BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX
29
+ kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19
30
+ bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF
31
+ DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6
32
+ UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag
33
+ 14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v
34
+ x52qPcexcYZR7w==
35
+ -----END CERTIFICATE-----
36
+
37
+ date: 2010-12-07 00:00:00 -08:00
38
+ default_executable:
39
+ dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest
42
+ prerelease: false
43
+ requirement: &id001 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ segments:
49
+ - 2
50
+ - 0
51
+ - 0
52
+ version: 2.0.0
53
+ type: :development
54
+ version_requirements: *id001
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ prerelease: false
58
+ requirement: &id002 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 2
65
+ - 6
66
+ - 0
67
+ version: 2.6.0
68
+ type: :development
69
+ version_requirements: *id002
70
+ description: |-
71
+ An HTTP/1.1 pipelining implementation atop Net::HTTP. This is an experimental
72
+ proof of concept.
73
+ email:
74
+ - drbrain@segment7.net
75
+ executables: []
76
+
77
+ extensions: []
78
+
79
+ extra_rdoc_files:
80
+ - History.txt
81
+ - Manifest.txt
82
+ - README.txt
83
+ files:
84
+ - .autotest
85
+ - History.txt
86
+ - Manifest.txt
87
+ - README.txt
88
+ - Rakefile
89
+ - lib/net/http/pipeline.rb
90
+ - sample/two_get.rb
91
+ - test/test_net_http_pipeline.rb
92
+ has_rdoc: true
93
+ homepage: http://seattlerb.rubyforge.org/net-http-pipeline
94
+ licenses: []
95
+
96
+ post_install_message:
97
+ rdoc_options:
98
+ - --main
99
+ - README.txt
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ requirements: []
119
+
120
+ rubyforge_project: net-http-pipeline
121
+ rubygems_version: 1.3.7
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: An HTTP/1.1 pipelining implementation atop Net::HTTP
125
+ test_files:
126
+ - test/test_net_http_pipeline.rb
@@ -0,0 +1,3 @@
1
+ 0�@�
2
+ ��c� 8TU�Mׅ�Ͻ�����\9��=�W����}l����_$����� �Q��}JBV*��4�`��Rʴ0u�uzw�]����^}'¦#�I^(U`�0��q|�����?0�t�P �Iz%ѵ��H�;=�����Hfw: �O��Iחn�\A�F��J�w* �h=��4L4g�NI�>y�� m�o��?�7����y��et2�,-��-�AL"_;I�<b�P�)���K�
3
+ R��ˍ�r5��x�x