protocol-http 0.26.4 → 0.26.6

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: '0817ddd3e60c6de45f9e5a73ecedb00e60c11c8171bcddca6b1da0b3bc898708'
4
- data.tar.gz: bac2be42911aab9457374fc16d80ca4db76e9b7b4a9bacb5d6937e63e5520298
3
+ metadata.gz: 54ef214891be3dd78e03f7c061f9b6e6f754efc9fc28445f5d8924d779c217bd
4
+ data.tar.gz: 6a637bcae7852f2acf31d9ff76a35781da93e6e33efb26131fe9ef0466c21cdc
5
5
  SHA512:
6
- metadata.gz: f78f1dcb03b5d203fae96a278a2152ee938ac8256692bf379819d44742104bc3c310ed1e6ce09f652f71ac86a08b1157705e7500974a4b2cdfdba7a00ed5a6fb
7
- data.tar.gz: 1bba3d55382e65a7a79f60c81d089c129dde3b4bc2ab5e550172797a86be0d962426d1beb4910710c96a418f5b4460c2578f34bcac15cb34e1e0f93f1fdcf253
6
+ metadata.gz: 56f697b23039bebe8edbc71c2ddfbbc60c552de4d87403785004f7adbb76456a0c37005cd5b307f415cadba9ca1f91bfc0825a5924f0ede2c88e538f2c77cdcc
7
+ data.tar.gz: 733dd1c04f5bd2e900a563940a546d749084eacd5725707cfb2255c7a1259d858a4b598b3de840951751a1d2e286c60d13bed4d4fe1b8fbc934ec918d6f311c9
checksums.yaml.gz.sig CHANGED
Binary file
@@ -12,7 +12,11 @@ module Protocol
12
12
  # A body which buffers all it's contents.
13
13
  class Buffered < Readable
14
14
  # Wraps an array into a buffered body.
15
- # @return [Readable, nil] the wrapped body or nil if nil was given.
15
+ #
16
+ # For compatibility, also accepts anything that behaves like an `Array(String)`.
17
+ #
18
+ # @parameter body [String | Array(String) | Readable | nil] the body to wrap.
19
+ # @returns [Readable | nil] the wrapped body or nil if nil was given.
16
20
  def self.wrap(body)
17
21
  if body.is_a?(Readable)
18
22
  return body
@@ -1,7 +1,7 @@
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
 
6
6
  require_relative 'wrapper'
7
7
 
@@ -1,7 +1,7 @@
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 Bruno Sutic.
6
6
 
7
7
  module Protocol
@@ -1,7 +1,7 @@
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
 
6
6
  require_relative 'readable'
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2023, by Samuel Williams.
4
+ # Copyright, 2018-2024, by Samuel Williams.
5
5
 
6
6
  require_relative 'header/split'
7
7
  require_relative 'header/multiple'
@@ -65,12 +65,12 @@ module Protocol
65
65
  return to_enum(:each) unless block_given?
66
66
 
67
67
  constants.each do |name|
68
- yield name, const_get(name)
68
+ yield name.downcase, const_get(name)
69
69
  end
70
70
  end
71
71
 
72
72
  self.each do |name, value|
73
- define_method(name.downcase) do |location, headers = nil, body = nil|
73
+ define_method(name) do |location, headers = nil, body = nil|
74
74
  self.call(
75
75
  Request[value, location.to_s, Headers[headers], body]
76
76
  )
@@ -1,7 +1,7 @@
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
 
6
6
  require_relative '../middleware'
7
7
 
@@ -30,7 +30,13 @@ module Protocol
30
30
  def self.build(&block)
31
31
  builder = Builder.new
32
32
 
33
- builder.instance_eval(&block)
33
+ if block_given?
34
+ if block.arity == 0
35
+ builder.instance_exec(&block)
36
+ else
37
+ yield builder
38
+ end
39
+ end
34
40
 
35
41
  return builder.to_app
36
42
  end
@@ -1,7 +1,7 @@
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
 
6
6
  require_relative 'body/buffered'
7
7
  require_relative 'body/reader'
@@ -11,6 +11,17 @@ require_relative 'methods'
11
11
 
12
12
  module Protocol
13
13
  module HTTP
14
+ # Represents an HTTP request which can be used both server and client-side.
15
+ #
16
+ # ~~~ ruby
17
+ # require 'protocol/http'
18
+ #
19
+ # # Long form:
20
+ # Protocol::HTTP::Request.new("http", "example.com", "GET", "/index.html", "HTTP/1.1", Protocol::HTTP::Headers[["accept", "text/html"]])
21
+ #
22
+ # # Short form:
23
+ # Protocol::HTTP::Request["GET", "/index.html", {"accept" => "text/html"}]
24
+ # ~~~
14
25
  class Request
15
26
  prepend Body::Reader
16
27
 
@@ -25,28 +36,28 @@ module Protocol
25
36
  @protocol = protocol
26
37
  end
27
38
 
28
- # The request scheme, usually one of "http" or "https".
39
+ # @attribute [String] the request scheme, usually `"http"` or `"https"`.
29
40
  attr_accessor :scheme
30
-
31
- # The request authority, usually a hostname and port number.
41
+
42
+ # @attribute [String] the request authority, usually a hostname and port number, e.g. `"example.com:80"`.
32
43
  attr_accessor :authority
33
-
34
- # The request method, usually one of "GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT" or "OPTIONS".
44
+
45
+ # @attribute [String] the request method, usually one of `"GET"`, `"HEAD"`, `"POST"`, `"PUT"`, `"DELETE"`, `"CONNECT"` or `"OPTIONS"`, etc.
35
46
  attr_accessor :method
36
-
37
- # The request path, usually a path and query string.
47
+
48
+ # @attribute [String] the request path, usually a path and query string, e.g. `"/index.html"`, `"/search?q=hello"`, however it can be any [valid request target](https://www.rfc-editor.org/rfc/rfc9110#target.resource).
38
49
  attr_accessor :path
39
-
40
- # The request version, usually "http/1.0", "http/1.1", "h2", or "h3".
50
+
51
+ # @attribute [String] the request version, usually `"http/1.0"`, `"http/1.1"`, `"h2"`, or `"h3"`.
41
52
  attr_accessor :version
42
-
43
- # The request headers, contains metadata associated with the request such as the user agent, accept (content type), accept-language, etc.
53
+
54
+ # @attribute [Headers] the request headers, usually containing metadata associated with the request such as the `"user-agent"`, `"accept"` (content type), `"accept-language"`, etc.
44
55
  attr_accessor :headers
45
-
46
- # The request body, an instance of Protocol::HTTP::Body::Readable or similar.
56
+
57
+ # @attribute [Body::Readable] the request body. It should only be read once (it may not be idempotent).
47
58
  attr_accessor :body
48
59
 
49
- # The request protocol, usually empty, but occasionally "websocket" or "webtransport", can be either single value `String` or multi-value `Array` of `String` instances. In HTTP/1, it is used to request a connection upgrade, and in HTTP/2 it is used to indicate a specfic protocol for the stream.
60
+ # @attribute [String | Array(String) | Nil] the request protocol, usually empty, but occasionally `"websocket"` or `"webtransport"`. In HTTP/1, it is used to request a connection upgrade, and in HTTP/2 it is used to indicate a specfic protocol for the stream.
50
61
  attr_accessor :protocol
51
62
 
52
63
  # Send the request to the given connection.
@@ -54,14 +65,22 @@ module Protocol
54
65
  connection.call(self)
55
66
  end
56
67
 
68
+ # Whether this is a HEAD request: no body is expected in the response.
57
69
  def head?
58
70
  @method == Methods::HEAD
59
71
  end
60
72
 
73
+ # Whether this is a CONNECT request: typically used to establish a tunnel.
61
74
  def connect?
62
75
  @method == Methods::CONNECT
63
76
  end
64
77
 
78
+ # A short-cut method which exposes the main request variables that you'd typically care about.
79
+ #
80
+ # @parameter method [String] The HTTP method, e.g. `"GET"`, `"POST"`, etc.
81
+ # @parameter path [String] The path, e.g. `"/index.html"`, `"/search?q=hello"`, etc.
82
+ # @parameter headers [Hash] The headers, e.g. `{"accept" => "text/html"}`, etc.
83
+ # @parameter body [String | Array(String) | Body::Readable] The body, e.g. `"Hello, World!"`, etc. See {Body::Buffered.wrap} for more information about .
65
84
  def self.[](method, path, headers = nil, body = nil)
66
85
  body = Body::Buffered.wrap(body)
67
86
  headers = ::Protocol::HTTP::Headers[headers]
@@ -69,6 +88,7 @@ module Protocol
69
88
  self.new(nil, nil, method, path, nil, headers, body)
70
89
  end
71
90
 
91
+ # Whether the request can be replayed without side-effects.
72
92
  def idempotent?
73
93
  @method != Methods::POST && (@body.nil? || @body.empty?)
74
94
  end
@@ -1,16 +1,34 @@
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
 
6
6
  require_relative 'body/buffered'
7
7
  require_relative 'body/reader'
8
8
 
9
9
  module Protocol
10
10
  module HTTP
11
+ # Represents an HTTP response which can be used both server and client-side.
12
+ #
13
+ # ~~~ ruby
14
+ # require 'protocol/http'
15
+ #
16
+ # # Long form:
17
+ # Protocol::HTTP::Response.new("http/1.1", 200, Protocol::HTTP::Headers[["content-type", "text/html"]], Protocol::HTTP::Body::Buffered.wrap("Hello, World!"))
18
+ #
19
+ # # Short form:
20
+ # Protocol::HTTP::Response[200, {"content-type" => "text/html"}, ["Hello, World!"]]
21
+ # ~~~
11
22
  class Response
12
23
  prepend Body::Reader
13
24
 
25
+ # Create a new response.
26
+ #
27
+ # @parameter version [String | Nil] The HTTP version, e.g. `"HTTP/1.1"`. If `nil`, the version may be provided by the server sending the response.
28
+ # @parameter status [Integer] The HTTP status code, e.g. `200`, `404`, etc.
29
+ # @parameter headers [Hash] The headers, e.g. `{"content-type" => "text/html"}`, etc.
30
+ # @parameter body [Body::Readable] The body, e.g. `"Hello, World!"`, etc.
31
+ # @parameter protocol [String | Array(String)] The protocol, e.g. `"websocket"`, etc.
14
32
  def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)
15
33
  @version = version
16
34
  @status = status
@@ -19,12 +37,22 @@ module Protocol
19
37
  @protocol = protocol
20
38
  end
21
39
 
40
+ # @attribute [String | Nil] The HTTP version, usually one of `"HTTP/1.1"`, `"HTTP/2"`, etc.
22
41
  attr_accessor :version
42
+
43
+ # @attribute [Integer] The HTTP status code, e.g. `200`, `404`, etc.
23
44
  attr_accessor :status
45
+
46
+ # @attribute [Hash] The headers, e.g. `{"content-type" => "text/html"}`, etc.
24
47
  attr_accessor :headers
48
+
49
+ # @attribute [Body::Readable] The body, e.g. `"Hello, World!"`, etc.
25
50
  attr_accessor :body
51
+
52
+ # @attribute [String | Array(String) | Nil] The protocol, e.g. `"websocket"`, etc.
26
53
  attr_accessor :protocol
27
54
 
55
+ # Whether the response is considered a hijack: the connection has been taken over by the application and the server should not send any more data.
28
56
  def hijack?
29
57
  false
30
58
  end
@@ -93,6 +121,15 @@ module Protocol
93
121
  # @deprecated Use {#internal_server_error?} instead.
94
122
  alias server_failure? internal_server_error?
95
123
 
124
+ # A short-cut method which exposes the main response variables that you'd typically care about. It follows the same order as the `Rack` response tuple, but also includes the protocol.
125
+ #
126
+ # ~~~ ruby
127
+ # Response[200, {"content-type" => "text/html"}, ["Hello, World!"]]
128
+ # ~~~
129
+ #
130
+ # @parameter status [Integer] The HTTP status code, e.g. `200`, `404`, etc.
131
+ # @parameter headers [Hash] The headers, e.g. `{"content-type" => "text/html"}`, etc.
132
+ # @parameter body [String | Array(String) | Body::Readable] The body, e.g. `"Hello, World!"`, etc. See {Body::Buffered.wrap} for more information about .
96
133
  def self.[](status, headers = nil, body = nil, protocol = nil)
97
134
  body = Body::Buffered.wrap(body)
98
135
  headers = ::Protocol::HTTP::Headers[headers]
@@ -100,6 +137,9 @@ module Protocol
100
137
  self.new(nil, status, headers, body, protocol)
101
138
  end
102
139
 
140
+ # Create a response for the given exception.
141
+ #
142
+ # @parameter exception [Exception] The exception to generate the response for.
103
143
  def self.for_exception(exception)
104
144
  Response[500, Headers['content-type' => 'text/plain'], ["#{exception.class}: #{exception.message}"]]
105
145
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module HTTP
8
- VERSION = "0.26.4"
8
+ VERSION = "0.26.6"
9
9
  end
10
10
  end
data/lib/protocol/http.rb CHANGED
@@ -4,3 +4,8 @@
4
4
  # Copyright, 2018-2023, by Samuel Williams.
5
5
 
6
6
  require_relative "http/version"
7
+
8
+ require_relative 'http/headers'
9
+ require_relative 'http/request'
10
+ require_relative 'http/response'
11
+ require_relative 'http/middleware'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.4
4
+ version: 0.26.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -47,7 +47,7 @@ cert_chain:
47
47
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
48
48
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
49
49
  -----END CERTIFICATE-----
50
- date: 2024-04-16 00:00:00.000000000 Z
50
+ date: 2024-06-24 00:00:00.000000000 Z
51
51
  dependencies: []
52
52
  description:
53
53
  email:
@@ -98,6 +98,7 @@ licenses:
98
98
  - MIT
99
99
  metadata:
100
100
  documentation_uri: https://socketry.github.io/protocol-http/
101
+ source_code_uri: https://github.com/socketry/protocol-http.git
101
102
  post_install_message:
102
103
  rdoc_options: []
103
104
  require_paths:
@@ -106,14 +107,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
107
  requirements:
107
108
  - - ">="
108
109
  - !ruby/object:Gem::Version
109
- version: '3.0'
110
+ version: '3.1'
110
111
  required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  requirements:
112
113
  - - ">="
113
114
  - !ruby/object:Gem::Version
114
115
  version: '0'
115
116
  requirements: []
116
- rubygems_version: 3.5.3
117
+ rubygems_version: 3.5.11
117
118
  signing_key:
118
119
  specification_version: 4
119
120
  summary: Provides abstractions to handle HTTP protocols.
metadata.gz.sig CHANGED
Binary file