protocol-http1 0.21.0 → 0.23.0

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: 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