h1p 0.2 → 0.3

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.
@@ -5,13 +5,13 @@ require 'h1p'
5
5
  require 'socket'
6
6
  require_relative '../ext/h1p/limits'
7
7
 
8
- class H1PTest < MiniTest::Test
8
+ class H1PRequestTest < MiniTest::Test
9
9
  Error = H1P::Error
10
10
 
11
11
  def setup
12
12
  super
13
13
  @i, @o = IO.pipe
14
- @parser = H1P::Parser.new(@i)
14
+ @parser = H1P::Parser.new(@i, :server)
15
15
  end
16
16
  alias_method :reset_parser, :setup
17
17
 
@@ -75,7 +75,7 @@ class H1PTest < MiniTest::Test
75
75
  @o.close
76
76
 
77
77
  assert_raises(Error) { @parser.parse_headers }
78
-
78
+
79
79
  max_length = H1P_LIMITS[:max_method_length]
80
80
 
81
81
  reset_parser
@@ -96,7 +96,7 @@ class H1PTest < MiniTest::Test
96
96
  def test_bad_path
97
97
  @o << "GET HTTP/1.1\r\n\r\n"
98
98
  assert_raises(Error) { @parser.parse_headers }
99
-
99
+
100
100
  max_length = H1P_LIMITS[:max_path_length]
101
101
 
102
102
  reset_parser
@@ -149,26 +149,26 @@ class H1PTest < MiniTest::Test
149
149
  assert_raises(Error) { @parser.parse_headers }
150
150
 
151
151
  reset_parser
152
- @o << "GET / http/1.1.1\r\n\r\n"
152
+ @o << "GET / HTTP/1.1.1\r\n\r\n"
153
153
  assert_raises(Error) { @parser.parse_headers }
154
154
  end
155
155
 
156
156
  def test_headers_eof
157
157
  @o << "GET / HTTP/1.1\r\na"
158
158
  @o.close
159
-
159
+
160
160
  assert_nil @parser.parse_headers
161
161
 
162
162
  reset_parser
163
163
  @o << "GET / HTTP/1.1\r\na:"
164
164
  @o.close
165
-
165
+
166
166
  assert_nil @parser.parse_headers
167
167
 
168
168
  reset_parser
169
169
  @o << "GET / HTTP/1.1\r\na: "
170
170
  @o.close
171
-
171
+
172
172
  assert_nil @parser.parse_headers
173
173
  end
174
174
 
@@ -197,46 +197,46 @@ class H1PTest < MiniTest::Test
197
197
  end
198
198
 
199
199
  def test_bad_headers
200
- @o << "GET / http/1.1\r\n a: b\r\n\r\n"
200
+ @o << "GET / HTTP/1.1\r\n a: b\r\n\r\n"
201
201
  assert_raises(Error) { @parser.parse_headers }
202
202
 
203
203
  reset_parser
204
- @o << "GET / http/1.1\r\na b\r\n\r\n"
204
+ @o << "GET / HTTP/1.1\r\na b\r\n\r\n"
205
205
  assert_raises(Error) { @parser.parse_headers }
206
206
 
207
207
  max_key_length = H1P_LIMITS[:max_header_key_length]
208
208
 
209
209
  reset_parser
210
- @o << "GET / http/1.1\r\n#{'a' * max_key_length}: b\r\n\r\n"
210
+ @o << "GET / HTTP/1.1\r\n#{'a' * max_key_length}: b\r\n\r\n"
211
211
  headers = @parser.parse_headers
212
212
  assert_equal 'b', headers['a' * max_key_length]
213
213
 
214
214
  reset_parser
215
- @o << "GET / http/1.1\r\n#{'a' * (max_key_length + 1)}: b\r\n\r\n"
215
+ @o << "GET / HTTP/1.1\r\n#{'a' * (max_key_length + 1)}: b\r\n\r\n"
216
216
  assert_raises(Error) { @parser.parse_headers }
217
217
 
218
218
  max_value_length = H1P_LIMITS[:max_header_value_length]
219
219
 
220
220
  reset_parser
221
- @o << "GET / http/1.1\r\nfoo: #{'a' * max_value_length}\r\n\r\n"
221
+ @o << "GET / HTTP/1.1\r\nfoo: #{'a' * max_value_length}\r\n\r\n"
222
222
  headers = @parser.parse_headers
223
223
  assert_equal 'a' * max_value_length, headers['foo']
224
224
 
225
225
  reset_parser
226
- @o << "GET / http/1.1\r\nfoo: #{'a' * (max_value_length + 1)}\r\n\r\n"
226
+ @o << "GET / HTTP/1.1\r\nfoo: #{'a' * (max_value_length + 1)}\r\n\r\n"
227
227
  assert_raises(Error) { @parser.parse_headers }
228
228
 
229
229
  max_header_count = H1P_LIMITS[:max_header_count]
230
230
 
231
231
  reset_parser
232
232
  hdrs = (1..max_header_count).map { |i| "foo#{i}: bar\r\n" }.join
233
- @o << "GET / http/1.1\r\n#{hdrs}\r\n"
233
+ @o << "GET / HTTP/1.1\r\n#{hdrs}\r\n"
234
234
  headers = @parser.parse_headers
235
235
  assert_equal (max_header_count + 4), headers.size
236
236
 
237
237
  reset_parser
238
238
  hdrs = (1..(max_header_count + 1)).map { |i| "foo#{i}: bar\r\n" }.join
239
- @o << "GET / http/1.1\r\n#{hdrs}\r\n"
239
+ @o << "GET / HTTP/1.1\r\n#{hdrs}\r\n"
240
240
  assert_raises(Error) { @parser.parse_headers }
241
241
  end
242
242
 
@@ -256,7 +256,7 @@ class H1PTest < MiniTest::Test
256
256
  def test_read_body_with_content_length
257
257
  10.times do
258
258
  data = ' ' * rand(20..60000)
259
- msg = "POST /foo HTTP/1.1\r\nContent-Length: #{data.bytesize}\r\n\r\n#{data}"
259
+ msg = "GET / HTTP/1.1\r\nContent-Length: #{data.bytesize}\r\n\r\n#{data}"
260
260
  Thread.new { @o << msg }
261
261
 
262
262
  headers = @parser.parse_headers
@@ -270,7 +270,7 @@ class H1PTest < MiniTest::Test
270
270
 
271
271
  def test_read_body_chunk_with_content_length
272
272
  data = 'abc' * 20000
273
- msg = "POST /foo HTTP/1.1\r\nContent-Length: #{data.bytesize}\r\n\r\n#{data}"
273
+ msg = "GET / HTTP/1.1\r\nContent-Length: #{data.bytesize}\r\n\r\n#{data}"
274
274
  Thread.new { @o << msg }
275
275
  headers = @parser.parse_headers
276
276
  assert_equal data.bytesize.to_s, headers['content-length']
@@ -290,7 +290,7 @@ class H1PTest < MiniTest::Test
290
290
  def test_read_body_with_content_length_incomplete
291
291
  data = ' ' * rand(20..60000)
292
292
  Thread.new do
293
- @o << "POST /foo HTTP/1.1\r\nContent-Length: #{data.bytesize + 1}\r\n\r\n#{data}"
293
+ @o << "GET / HTTP/1.1\r\nContent-Length: #{data.bytesize + 1}\r\n\r\n#{data}"
294
294
  @o.close # !!! otherwise the parser will keep waiting
295
295
  end
296
296
  headers = @parser.parse_headers
@@ -300,7 +300,7 @@ class H1PTest < MiniTest::Test
300
300
 
301
301
  def test_read_body_chunk_with_content_length_incomplete
302
302
  data = 'abc' * 50
303
- @o << "POST /foo HTTP/1.1\r\nContent-Length: #{data.bytesize + 1}\r\n\r\n#{data}"
303
+ @o << "GET / HTTP/1.1\r\nContent-Length: #{data.bytesize + 1}\r\n\r\n#{data}"
304
304
  @o.close
305
305
  headers = @parser.parse_headers
306
306
 
@@ -311,7 +311,7 @@ class H1PTest < MiniTest::Test
311
311
  chunks = []
312
312
  total_sent = 0
313
313
  Thread.new do
314
- msg = "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
314
+ msg = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
315
315
  @o << msg
316
316
  total_sent += msg.bytesize
317
317
  rand(8..16).times do |i|
@@ -324,7 +324,7 @@ class H1PTest < MiniTest::Test
324
324
  msg = "0\r\n\r\n"
325
325
  @o << msg
326
326
  total_sent += msg.bytesize
327
- end
327
+ end
328
328
  headers = @parser.parse_headers
329
329
  assert_equal 'chunked', headers['transfer-encoding']
330
330
 
@@ -337,7 +337,7 @@ class H1PTest < MiniTest::Test
337
337
  chunks = []
338
338
  total_sent = 0
339
339
  Thread.new do
340
- msg = "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
340
+ msg = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
341
341
  @o << msg
342
342
  total_sent += msg.bytesize
343
343
  rand(8..16).times do |i|
@@ -350,7 +350,7 @@ class H1PTest < MiniTest::Test
350
350
  msg = "0\r\n\r\n"
351
351
  @o << msg
352
352
  total_sent += msg.bytesize
353
- end
353
+ end
354
354
  headers = @parser.parse_headers
355
355
  assert_equal 'chunked', headers['transfer-encoding']
356
356
 
@@ -364,7 +364,7 @@ class H1PTest < MiniTest::Test
364
364
 
365
365
  def test_read_body_with_chunked_encoding_malformed
366
366
  Thread.new do
367
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
367
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
368
368
  chunk = ' '.to_s * rand(40000..360000)
369
369
  @o << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n3"
370
370
  @o << "0\r\n\r\n"
@@ -376,22 +376,22 @@ class H1PTest < MiniTest::Test
376
376
  reset_parser
377
377
  # missing last empty chunk
378
378
  Thread.new do
379
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
379
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
380
380
  chunk = ' '.to_s * rand(40000..360000)
381
381
  @o << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
382
382
  @o.close
383
- end
383
+ end
384
384
  headers = @parser.parse_headers
385
385
  assert_raises(H1P::Error) { @parser.read_body }
386
386
 
387
387
  reset_parser
388
388
  # bad chunk size
389
389
  Thread.new do
390
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
390
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
391
391
  chunk = ' '.to_s * rand(40000..360000)
392
392
  @o << "-#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
393
393
  @o.close
394
- end
394
+ end
395
395
  headers = @parser.parse_headers
396
396
  assert_raises(H1P::Error) { @parser.read_body }
397
397
  end
@@ -399,7 +399,7 @@ class H1PTest < MiniTest::Test
399
399
  def test_read_body_chunk_with_chunked_encoding_malformed
400
400
  chunk = nil
401
401
  Thread.new do
402
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
402
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
403
403
  chunk = ' ' * rand(40000..360000)
404
404
  @o << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n3"
405
405
  @o << "0\r\n\r\n"
@@ -415,7 +415,7 @@ class H1PTest < MiniTest::Test
415
415
  # missing last empty chunk
416
416
  chunk = nil
417
417
  Thread.new do
418
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
418
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
419
419
  chunk = ' '.to_s * rand(20..1600)
420
420
  @o << "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
421
421
  @o.close
@@ -429,18 +429,18 @@ class H1PTest < MiniTest::Test
429
429
 
430
430
  # bad chunk size
431
431
  Thread.new do
432
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
432
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
433
433
  chunk = ' '.to_s * rand(20..1600)
434
434
  @o << "-#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
435
435
  @o.close
436
- end
436
+ end
437
437
  headers = @parser.parse_headers
438
438
  assert_raises(H1P::Error) { @parser.read_body_chunk(false) }
439
439
 
440
440
  reset_parser
441
441
 
442
442
  # missing body
443
- @o << "POST /foo HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
443
+ @o << "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
444
444
  @o.close
445
445
  headers = @parser.parse_headers
446
446
  assert_raises(H1P::Error) { @parser.read_body_chunk(false) }
@@ -519,7 +519,7 @@ class H1PTest < MiniTest::Test
519
519
  server_thread = Thread.new do
520
520
  while (socket = server.accept)
521
521
  Thread.new do
522
- parser = H1P::Parser.new(socket)
522
+ parser = H1P::Parser.new(socket, :server)
523
523
  headers = parser.parse_headers
524
524
  socket << headers.inspect
525
525
  socket.shutdown
@@ -556,7 +556,7 @@ class H1PTest < MiniTest::Test
556
556
  request
557
557
  end
558
558
 
559
- parser = H1P::Parser.new(callable)
559
+ parser = H1P::Parser.new(callable, :server)
560
560
 
561
561
  headers = parser.parse_headers
562
562
  assert_equal({
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: h1p
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-20 00:00:00.000000000 Z
11
+ date: 2022-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 5.14.4
55
- description:
55
+ description:
56
56
  email: sharon@noteflakes.com
57
57
  executables: []
58
58
  extensions:
@@ -70,6 +70,7 @@ files:
70
70
  - Rakefile
71
71
  - TODO.md
72
72
  - benchmarks/bm_http1_parser.rb
73
+ - benchmarks/pipelined.rb
73
74
  - examples/callable.rb
74
75
  - examples/http_server.rb
75
76
  - ext/h1p/extconf.rb
@@ -80,13 +81,15 @@ files:
80
81
  - lib/h1p.rb
81
82
  - lib/h1p/version.rb
82
83
  - test/helper.rb
83
- - test/test_h1p.rb
84
+ - test/run.rb
85
+ - test/test_h1p_client.rb
86
+ - test/test_h1p_server.rb
84
87
  homepage: http://github.com/digital-fabric/h1p
85
88
  licenses:
86
89
  - MIT
87
90
  metadata:
88
91
  source_code_uri: https://github.com/digital-fabric/h1p
89
- post_install_message:
92
+ post_install_message:
90
93
  rdoc_options:
91
94
  - "--title"
92
95
  - h1p
@@ -105,8 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
108
  - !ruby/object:Gem::Version
106
109
  version: '0'
107
110
  requirements: []
108
- rubygems_version: 3.1.4
109
- signing_key:
111
+ rubygems_version: 3.3.3
112
+ signing_key:
110
113
  specification_version: 4
111
114
  summary: H1P is a blocking HTTP/1 parser for Ruby
112
115
  test_files: []