protocol-http1 0.21.0 → 0.23.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66ce05a20db2c35943a45feab35afe95bf530ce562030741984025defb1f0b40
4
- data.tar.gz: e3066206a22ad274cc28ac13369d330cff0b5bee1641d79c113a3b13354f2f82
3
+ metadata.gz: 5883f7878058a83c35d40fe91ea7e673a6abc1895d47e91dfefd57e1849861d5
4
+ data.tar.gz: f01fbad8aa91e32dddd541fa6a3ab184d8204a5761b6a0b2d5bd7eafd5aab717
5
5
  SHA512:
6
- metadata.gz: 6bfbfc8977ca31eb293ee61fa43cf042ecf10ee4342c7124880e2bda32b1d966fed74bf0ad02a083d8b3e52a0112482be04da3388e4b9424ec112ef8ddb4bee0
7
- data.tar.gz: 204d66b3b7b57d3706248d05551cd29ccc50e824d34a4d0173cc90eb8266133abd5d6398cdc7811afb73d5605ca4b4a0107cbfb24679beff0e285616b9354307
6
+ metadata.gz: de91d508479206879dfded7ef4aca6ec5b211372ae8aa9d938afb97c4cb5d1804e9aefbea42d021979ce3c67ad6cf96c28f661be62e6c191219204f9ba96267e
7
+ data.tar.gz: 3c556ecfd10f3b20424629898b4684e6f8d56ad7415c94e3fedcac7485d5fb389141fd2fb9a9bbadd67a20d05a51286e338fc656febe145551b491781c052776
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2023, by Samuel Williams.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
5
  # Copyright, 2023, by Thomas Morgan.
6
6
 
7
- require 'protocol/http/body/readable'
7
+ require "protocol/http/body/readable"
8
8
 
9
9
  module Protocol
10
10
  module HTTP1
@@ -23,15 +23,22 @@ module Protocol
23
23
  end
24
24
 
25
25
  def empty?
26
- @finished
26
+ @stream.nil?
27
27
  end
28
28
 
29
- def close(error = nil)
30
- # We only close the connection if we haven't completed reading the entire body:
31
- unless @finished
32
- @stream.close
33
- @finished = true
29
+ def discard
30
+ if stream = @stream
31
+ @stream = nil
32
+
33
+ # We only close the connection if we haven't completed reading the entire body:
34
+ unless @finished
35
+ stream.close_read
36
+ end
34
37
  end
38
+ end
39
+
40
+ def close(error = nil)
41
+ self.discard
35
42
 
36
43
  super
37
44
  end
@@ -40,35 +47,47 @@ module Protocol
40
47
 
41
48
  # Follows the procedure outlined in https://tools.ietf.org/html/rfc7230#section-4.1.3
42
49
  def read
43
- return nil if @finished
44
-
45
- length, _extensions = read_line.split(";", 2)
46
-
47
- unless length =~ VALID_CHUNK_LENGTH
48
- raise BadRequest, "Invalid chunk length: #{length.inspect}"
49
- end
50
-
51
- # It is possible this line contains chunk extension, so we use `to_i` to only consider the initial integral part:
52
- length = Integer(length, 16)
53
-
54
- if length == 0
55
- @finished = true
56
-
57
- read_trailer
50
+ if !@finished
51
+ if @stream
52
+ length, _extensions = read_line.split(";", 2)
53
+
54
+ unless length =~ VALID_CHUNK_LENGTH
55
+ raise BadRequest, "Invalid chunk length: #{length.inspect}"
56
+ end
57
+
58
+ # It is possible this line contains chunk extension, so we use `to_i` to only consider the initial integral part:
59
+ length = Integer(length, 16)
60
+
61
+ if length == 0
62
+ read_trailer
63
+
64
+ # The final chunk has been read and the stream is now closed:
65
+ @stream = nil
66
+ @finished = true
67
+
68
+ return nil
69
+ end
70
+
71
+ # Read trailing CRLF:
72
+ chunk = @stream.read(length + 2)
73
+
74
+ if chunk.bytesize == length + 2
75
+ # ...and chomp it off:
76
+ chunk.chomp!(CRLF)
77
+
78
+ @length += length
79
+ @count += 1
80
+
81
+ return chunk
82
+ else
83
+ # The stream has been closed before we have read the requested length:
84
+ self.discard
85
+ end
86
+ end
58
87
 
59
- return nil
88
+ # If the stream has been closed before we have read the final chunk, raise an error:
89
+ raise EOFError, "Stream closed before expected length was read!"
60
90
  end
61
-
62
- # Read trailing CRLF:
63
- chunk = @stream.read(length + 2)
64
-
65
- # ...and chomp it off:
66
- chunk.chomp!(CRLF)
67
-
68
- @length += length
69
- @count += 1
70
-
71
- return chunk
72
91
  end
73
92
 
74
93
  def inspect
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
- require 'protocol/http/body/readable'
6
+ require "protocol/http/body/readable"
7
7
 
8
8
  module Protocol
9
9
  module HTTP1
@@ -11,6 +11,7 @@ module Protocol
11
11
  class Fixed < HTTP::Body::Readable
12
12
  def initialize(stream, length)
13
13
  @stream = stream
14
+
14
15
  @length = length
15
16
  @remaining = length
16
17
  end
@@ -19,14 +20,21 @@ module Protocol
19
20
  attr :remaining
20
21
 
21
22
  def empty?
22
- @remaining == 0
23
+ @stream.nil? or @remaining == 0
23
24
  end
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.
27
- if @remaining != 0
28
- @stream.close
26
+ def discard
27
+ if stream = @stream
28
+ @stream = nil
29
+
30
+ if @remaining != 0
31
+ stream.close_read
32
+ end
29
33
  end
34
+ end
35
+
36
+ def close(error = nil)
37
+ self.discard
30
38
 
31
39
  super
32
40
  end
@@ -34,25 +42,22 @@ module Protocol
34
42
  # @raises EOFError if the stream is closed before the expected length is read.
35
43
  def read
36
44
  if @remaining > 0
37
- # `readpartial` will raise `EOFError` if the stream is closed/finished:
38
- if chunk = @stream.readpartial(@remaining)
45
+ if @stream
46
+ # `readpartial` will raise `EOFError` if the stream is finished, or `IOError` if the stream is closed.
47
+ chunk = @stream.readpartial(@remaining)
48
+
39
49
  @remaining -= chunk.bytesize
40
50
 
41
51
  return chunk
42
52
  end
53
+
54
+ # If the stream has been closed before we have read the expected length, raise an error:
55
+ raise EOFError, "Stream closed before expected length was read!"
43
56
  end
44
57
  end
45
58
 
46
- def join
47
- buffer = @stream.read(@remaining)
48
-
49
- @remaining = 0
50
-
51
- return buffer
52
- end
53
-
54
59
  def inspect
55
- "\#<#{self.class} length=#{@length} remaining=#{@remaining}>"
60
+ "\#<#{self.class} length=#{@length} remaining=#{@remaining} state=#{@stream ? 'open' : 'closed'}>"
56
61
  end
57
62
  end
58
63
  end
@@ -3,58 +3,47 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
- require 'protocol/http/body/readable'
6
+ require "protocol/http/body/readable"
7
7
 
8
8
  module Protocol
9
9
  module HTTP1
10
10
  module Body
11
+ # A body that reads all remaining data from the stream.
11
12
  class Remainder < HTTP::Body::Readable
12
13
  BLOCK_SIZE = 1024 * 64
13
14
 
14
15
  # block_size may be removed in the future. It is better managed by stream.
15
16
  def initialize(stream)
16
17
  @stream = stream
17
- @empty = false
18
18
  end
19
19
 
20
20
  def empty?
21
- @empty or @stream.closed?
21
+ @stream.nil?
22
+ end
23
+
24
+ def discard
25
+ if stream = @stream
26
+ @stream = nil
27
+ stream.close_read
28
+ end
22
29
  end
23
30
 
24
31
  def close(error = nil)
25
- # We can't really do anything in this case except close the connection.
26
- @stream.close
27
- @empty = true
32
+ self.discard
28
33
 
29
34
  super
30
35
  end
31
36
 
32
- # TODO this is a bit less efficient in order to maintain compatibility with `IO`.
33
37
  def read
34
- @stream.readpartial(BLOCK_SIZE)
38
+ @stream&.readpartial(BLOCK_SIZE)
35
39
  rescue EOFError, IOError
36
- @empty = true
37
-
40
+ @stream = nil
38
41
  # I noticed that in some cases you will get EOFError, and in other cases IOError!?
39
42
  return nil
40
43
  end
41
44
 
42
- def call(stream)
43
- self.each do |chunk|
44
- stream.write(chunk)
45
- end
46
-
47
- stream.flush
48
- end
49
-
50
- def join
51
- @stream.read
52
- ensure
53
- @empty = true
54
- end
55
-
56
45
  def inspect
57
- "\#<#{self.class} #{@stream.closed? ? 'closed' : 'open'}>"
46
+ "\#<#{self.class} state=#{@stream ? 'open' : 'closed'}>"
58
47
  end
59
48
  end
60
49
  end
@@ -4,34 +4,34 @@
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
5
  # Copyright, 2019, by Brian Morearty.
6
6
  # Copyright, 2020, by Bruno Sutic.
7
- # Copyright, 2023, by Thomas Morgan.
7
+ # Copyright, 2023-2024, by Thomas Morgan.
8
8
  # Copyright, 2024, by Anton Zhuravsky.
9
9
 
10
- require 'protocol/http/headers'
10
+ require "protocol/http/headers"
11
11
 
12
- require_relative 'reason'
13
- require_relative 'error'
12
+ require_relative "reason"
13
+ require_relative "error"
14
14
 
15
- require_relative 'body/chunked'
16
- require_relative 'body/fixed'
17
- require_relative 'body/remainder'
18
- require 'protocol/http/body/head'
15
+ require_relative "body/chunked"
16
+ require_relative "body/fixed"
17
+ require_relative "body/remainder"
18
+ require "protocol/http/body/head"
19
19
 
20
- require 'protocol/http/methods'
20
+ require "protocol/http/methods"
21
21
 
22
22
  module Protocol
23
23
  module HTTP1
24
- CONTENT_LENGTH = 'content-length'
24
+ CONTENT_LENGTH = "content-length"
25
25
 
26
- TRANSFER_ENCODING = 'transfer-encoding'
27
- CHUNKED = 'chunked'
26
+ TRANSFER_ENCODING = "transfer-encoding"
27
+ CHUNKED = "chunked"
28
28
 
29
- CONNECTION = 'connection'
30
- CLOSE = 'close'
31
- KEEP_ALIVE = 'keep-alive'
29
+ CONNECTION = "connection"
30
+ CLOSE = "close"
31
+ KEEP_ALIVE = "keep-alive"
32
32
 
33
- HOST = 'host'
34
- UPGRADE = 'upgrade'
33
+ HOST = "host"
34
+ UPGRADE = "upgrade"
35
35
 
36
36
  # HTTP/1.x request line parser:
37
37
  TOKEN = /[!#$%&'*+\-\.\^_`|~0-9a-zA-Z]+/.freeze
@@ -105,7 +105,7 @@ module Protocol
105
105
  def write_upgrade_header(upgrade)
106
106
  @stream.write("connection: upgrade\r\nupgrade: #{upgrade}\r\n")
107
107
  end
108
-
108
+
109
109
  # Indicates whether the connection has been hijacked meaning its
110
110
  # IO has been handed over and is not usable anymore.
111
111
  # @return [Boolean] hijack status
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
- require 'protocol/http/error'
6
+ require "protocol/http/error"
7
7
 
8
8
  module Protocol
9
9
  module HTTP1
@@ -1,9 +1,9 @@
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-2024, by Samuel Williams.
5
5
 
6
- require 'protocol/http/error'
6
+ require "protocol/http/error"
7
7
 
8
8
  module Protocol
9
9
  module HTTP1
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module HTTP1
8
- VERSION = "0.21.0"
8
+ VERSION = "0.23.0"
9
9
  end
10
10
  end
@@ -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-2024, by Samuel Williams.
5
5
 
6
- require_relative 'http1/version'
7
- require_relative 'http1/connection'
6
+ require_relative "http1/version"
7
+ require_relative "http1/connection"
data/license.md CHANGED
@@ -4,7 +4,7 @@ Copyright, 2019-2024, by Samuel Williams.
4
4
  Copyright, 2019, by Brian Morearty.
5
5
  Copyright, 2020, by Olle Jonsson.
6
6
  Copyright, 2020, by Bruno Sutic.
7
- Copyright, 2023, by Thomas Morgan.
7
+ Copyright, 2023-2024, by Thomas Morgan.
8
8
  Copyright, 2024, by Anton Zhuravsky.
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
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.21.0
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -42,7 +42,7 @@ cert_chain:
42
42
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
43
43
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
44
44
  -----END CERTIFICATE-----
45
- date: 2024-09-02 00:00:00.000000000 Z
45
+ date: 2024-09-17 00:00:00.000000000 Z
46
46
  dependencies:
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: protocol-http
metadata.gz.sig CHANGED
Binary file