protocol-http1 0.14.6 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a46985e11bfc9d2130f9abceacbd769c4aa83881a1a607afe9d0b4d07ad37e81
4
- data.tar.gz: cb08e884e92c03ab5a05b2d83e75478d458335502222dc89eabf961a43d08ba1
3
+ metadata.gz: 628996f62e649fce9998463a3147bba9690074ccd422d8973b56840f169ddbef
4
+ data.tar.gz: 368fd3265a87abe2f0300741f568194d5f479121fd49ccf51e0fdce6725dd080
5
5
  SHA512:
6
- metadata.gz: 0e78ae57c521f71a09aafec920e852dae0a66068bcc35271029567e053211967e56797e123a6046eb5323a703c6617ca9310d500ead439574c45d6c49c615000
7
- data.tar.gz: aae580287000a506cfd34cfee5ccd00c0ee26194cacf73725462885c37acff442a04ac69ca1ba0a4f4d996fcad2317741773d4a81d2a9cbc1045ecf3270f3053
6
+ metadata.gz: c3b589a20fb9395b6245ace8b113b7c57f541e9077562cece7673e8ba3577c0825bc71ed229902447e7abc735e126e6d2cd7a2b4a5b9385e24b5e5fb7c3596da
7
+ data.tar.gz: 15ff254cb06790546e76b00de892c10e712eb42ca30629b9c527d90034c252993c9de71be6d6b9f3f0cb26745ab554cf71e75e63e18a8b847c510d2bad16d45c
checksums.yaml.gz.sig CHANGED
Binary file
@@ -35,12 +35,20 @@ module Protocol
35
35
  super
36
36
  end
37
37
 
38
+ VALID_CHUNK_LENGTH = /\A[0-9a-fA-F]+\z/
39
+
38
40
  # Follows the procedure outlined in https://tools.ietf.org/html/rfc7230#section-4.1.3
39
41
  def read
40
42
  return nil if @finished
41
43
 
44
+ length, extensions = read_line.split(";", 2)
45
+
46
+ unless length =~ VALID_CHUNK_LENGTH
47
+ raise BadRequest, "Invalid chunk length: #{length.dump}"
48
+ end
49
+
42
50
  # It is possible this line contains chunk extension, so we use `to_i` to only consider the initial integral part:
43
- length = read_line.to_i(16)
51
+ length = Integer(length, 16)
44
52
 
45
53
  if length == 0
46
54
  @finished = true
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2022, by Samuel Williams.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
5
 
6
6
  require 'protocol/http/body/readable'
7
7
 
@@ -23,6 +23,7 @@ module Protocol
23
23
  end
24
24
 
25
25
  def close(error = nil)
26
+ # If we are closing the body without fully reading it, the underlying connection is now in an undefined state.
26
27
  if @remaining != 0
27
28
  @stream.close
28
29
  end
@@ -30,14 +31,16 @@ module Protocol
30
31
  super
31
32
  end
32
33
 
34
+ # @raises EOFError if the stream is closed before the expected length is read.
33
35
  def read
34
36
  if @remaining > 0
37
+ # `readpartial` will raise `EOFError` if the stream is closed/finished:
35
38
  if chunk = @stream.readpartial(@remaining)
36
39
  @remaining -= chunk.bytesize
37
40
 
38
41
  return chunk
39
- else
40
- raise EOFError, "Stream closed with #{@remaining} bytes remaining!"
42
+ # else
43
+ # raise EOFError, "Stream closed with #{@remaining} bytes remaining!"
41
44
  end
42
45
  end
43
46
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2022, by Samuel Williams.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
+ # Copyright, 2019, by Brian Morearty.
5
6
  # Copyright, 2020, by Bruno Sutic.
6
7
 
7
8
  require 'protocol/http/headers'
@@ -31,7 +32,7 @@ module Protocol
31
32
  UPGRADE = 'upgrade'
32
33
 
33
34
  # HTTP/1.x request line parser:
34
- TOKEN = /[!#$%&'*+-\.^_`|~0-9a-zA-Z]+/.freeze
35
+ TOKEN = /[!#$%&'*+\-\.\^_`|~0-9a-zA-Z]+/.freeze
35
36
  REQUEST_LINE = /\A(#{TOKEN}) ([^\s]+) (HTTP\/\d.\d)\z/.freeze
36
37
 
37
38
  # HTTP/1.x header parser:
@@ -63,12 +64,6 @@ module Protocol
63
64
  # The number of requests processed.
64
65
  attr :count
65
66
 
66
- def upgrade?(headers)
67
- if upgrade = headers[UPGRADE]
68
- return upgrade
69
- end
70
- end
71
-
72
67
  def persistent?(version, method, headers)
73
68
  if method == HTTP::Methods::CONNECT
74
69
  return false
@@ -281,7 +276,7 @@ module Protocol
281
276
  chunk_length += chunk.bytesize
282
277
 
283
278
  if chunk_length > length
284
- raise Error, "Trying to write #{chunk_length} bytes, but content length was #{length} bytes!"
279
+ raise ContentLengthError, "Trying to write #{chunk_length} bytes, but content length was #{length} bytes!"
285
280
  end
286
281
 
287
282
  @stream.write(chunk)
@@ -291,7 +286,7 @@ module Protocol
291
286
  @stream.flush
292
287
 
293
288
  if chunk_length != length
294
- raise Error, "Wrote #{chunk_length} bytes, but content length was #{length} bytes!"
289
+ raise ContentLengthError, "Wrote #{chunk_length} bytes, but content length was #{length} bytes!"
295
290
  end
296
291
  end
297
292
 
@@ -400,13 +395,21 @@ module Protocol
400
395
  read_remainder_body
401
396
  end
402
397
 
403
- def read_upgrade_body(protocol)
404
- read_remainder_body
405
- end
406
-
407
398
  HEAD = "HEAD"
408
399
  CONNECT = "CONNECT"
409
400
 
401
+ VALID_CONTENT_LENGTH = /\A\d+\z/
402
+
403
+ def extract_content_length(headers)
404
+ if content_length = headers.delete(CONTENT_LENGTH)
405
+ if content_length =~ VALID_CONTENT_LENGTH
406
+ yield Integer(content_length, 10)
407
+ else
408
+ raise BadRequest, "Invalid content length: #{content_length}"
409
+ end
410
+ end
411
+ end
412
+
410
413
  def read_response_body(method, status, headers)
411
414
  # RFC 7230 3.3.3
412
415
  # 1. Any response to a HEAD request and any response with a 1xx
@@ -415,19 +418,16 @@ module Protocol
415
418
  # header fields, regardless of the header fields present in the
416
419
  # message, and thus cannot contain a message body.
417
420
  if method == HTTP::Methods::HEAD
418
- if content_length = headers.delete(CONTENT_LENGTH)
419
- length = Integer(content_length)
420
-
421
+ extract_content_length(headers) do |length|
421
422
  if length > 0
422
423
  return read_head_body(length)
423
- elsif length == 0
424
- return nil
425
424
  else
426
- raise BadRequest, "Invalid content length: #{content_length}"
425
+ return nil
427
426
  end
428
- else
429
- return nil
430
427
  end
428
+
429
+ # There is no body for a HEAD request if there is no content length:
430
+ return nil
431
431
  end
432
432
 
433
433
  if (status >= 100 and status < 200) or status == 204 or status == 304
@@ -499,14 +499,11 @@ module Protocol
499
499
  # the recipient times out before the indicated number of octets are
500
500
  # received, the recipient MUST consider the message to be
501
501
  # incomplete and close the connection.
502
- if content_length = headers.delete(CONTENT_LENGTH)
503
- length = Integer(content_length)
502
+ extract_content_length(headers) do |length|
504
503
  if length > 0
505
504
  return read_fixed_body(length)
506
- elsif length == 0
507
- return nil
508
505
  else
509
- raise BadRequest, "Invalid content length: #{content_length}"
506
+ return nil
510
507
  end
511
508
  end
512
509
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2022, by Samuel Williams.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
5
 
6
6
  require 'protocol/http/error'
7
7
 
@@ -13,6 +13,10 @@ module Protocol
13
13
  class InvalidRequest < Error
14
14
  end
15
15
 
16
+ # The specified content length and the given content's length do not match.
17
+ class ContentLengthError < Error
18
+ end
19
+
16
20
  # The request was parsed correctly, but was invalid for some other reason.
17
21
  class BadRequest < Error
18
22
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2022, by Samuel Williams.
4
+ # Copyright, 2019-2023, by Samuel Williams.
5
5
 
6
6
  module Protocol
7
7
  module HTTP1
8
- VERSION = "0.14.6"
8
+ VERSION = "0.15.1"
9
9
  end
10
10
  end
data/license.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2019-2022, by Samuel Williams.
3
+ Copyright, 2019-2023, by Samuel Williams.
4
+ Copyright, 2019, by Brian Morearty.
5
+ Copyright, 2020, by Olle Jonsson.
4
6
  Copyright, 2020, by Bruno Sutic.
5
7
 
6
8
  Permission is hereby granted, free of charge, to any person obtaining a copy
data/readme.md CHANGED
@@ -61,32 +61,18 @@ end
61
61
 
62
62
  ## Contributing
63
63
 
64
- 1. Fork it
65
- 2. Create your feature branch (`git checkout -b my-new-feature`)
66
- 3. Commit your changes (`git commit -am 'Add some feature'`)
67
- 4. Push to the branch (`git push origin my-new-feature`)
68
- 5. Create new Pull Request
69
-
70
- ## License
71
-
72
- Released under the MIT license.
73
-
74
- Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
75
-
76
- Permission is hereby granted, free of charge, to any person obtaining a copy
77
- of this software and associated documentation files (the "Software"), to deal
78
- in the Software without restriction, including without limitation the rights
79
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
80
- copies of the Software, and to permit persons to whom the Software is
81
- furnished to do so, subject to the following conditions:
82
-
83
- The above copyright notice and this permission notice shall be included in
84
- all copies or substantial portions of the Software.
85
-
86
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
89
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
90
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
91
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
92
- THE SOFTWARE.
64
+ We welcome contributions to this project.
65
+
66
+ 1. Fork it.
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
68
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
69
+ 4. Push to the branch (`git push origin my-new-feature`).
70
+ 5. Create new Pull Request.
71
+
72
+ ### Developer Certificate of Origin
73
+
74
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
75
+
76
+ ### Contributor Covenant
77
+
78
+ This project is governed by [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http1
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.6
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -40,7 +40,7 @@ cert_chain:
40
40
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
41
41
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
42
42
  -----END CERTIFICATE-----
43
- date: 2022-08-29 00:00:00.000000000 Z
43
+ date: 2023-07-30 00:00:00.000000000 Z
44
44
  dependencies:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: protocol-http
@@ -56,76 +56,6 @@ dependencies:
56
56
  - - "~>"
57
57
  - !ruby/object:Gem::Version
58
58
  version: '0.22'
59
- - !ruby/object:Gem::Dependency
60
- name: bundler
61
- requirement: !ruby/object:Gem::Requirement
62
- requirements:
63
- - - ">="
64
- - !ruby/object:Gem::Version
65
- version: '0'
66
- type: :development
67
- prerelease: false
68
- version_requirements: !ruby/object:Gem::Requirement
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: '0'
73
- - !ruby/object:Gem::Dependency
74
- name: covered
75
- requirement: !ruby/object:Gem::Requirement
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- type: :development
81
- prerelease: false
82
- version_requirements: !ruby/object:Gem::Requirement
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- version: '0'
87
- - !ruby/object:Gem::Dependency
88
- name: rspec
89
- requirement: !ruby/object:Gem::Requirement
90
- requirements:
91
- - - "~>"
92
- - !ruby/object:Gem::Version
93
- version: '3.0'
94
- type: :development
95
- prerelease: false
96
- version_requirements: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - "~>"
99
- - !ruby/object:Gem::Version
100
- version: '3.0'
101
- - !ruby/object:Gem::Dependency
102
- name: rspec-files
103
- requirement: !ruby/object:Gem::Requirement
104
- requirements:
105
- - - "~>"
106
- - !ruby/object:Gem::Version
107
- version: '1.0'
108
- type: :development
109
- prerelease: false
110
- version_requirements: !ruby/object:Gem::Requirement
111
- requirements:
112
- - - "~>"
113
- - !ruby/object:Gem::Version
114
- version: '1.0'
115
- - !ruby/object:Gem::Dependency
116
- name: rspec-memory
117
- requirement: !ruby/object:Gem::Requirement
118
- requirements:
119
- - - "~>"
120
- - !ruby/object:Gem::Version
121
- version: '1.0'
122
- type: :development
123
- prerelease: false
124
- version_requirements: !ruby/object:Gem::Requirement
125
- requirements:
126
- - - "~>"
127
- - !ruby/object:Gem::Version
128
- version: '1.0'
129
59
  description:
130
60
  email:
131
61
  executables: []
@@ -154,14 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
84
  requirements:
155
85
  - - ">="
156
86
  - !ruby/object:Gem::Version
157
- version: '2.4'
87
+ version: 2.7.6b
158
88
  required_rubygems_version: !ruby/object:Gem::Requirement
159
89
  requirements:
160
90
  - - ">="
161
91
  - !ruby/object:Gem::Version
162
92
  version: '0'
163
93
  requirements: []
164
- rubygems_version: 3.3.7
94
+ rubygems_version: 3.4.10
165
95
  signing_key:
166
96
  specification_version: 4
167
97
  summary: A low level implementation of the HTTP/1 protocol.
metadata.gz.sig CHANGED
Binary file