h1p 0.6 → 0.6.1

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: 90f7937fd6bcefdd1627c208bf73054fb3fb03a855666c7247f04aac4398d280
4
- data.tar.gz: ab6a866b843beaf92137b991048db9af006f4cb5e510e211dc6ba6652bbc84a2
3
+ metadata.gz: 96197142deeb30d27fe9b3fc9de21a07ed1de8f0a1d3db9b8d967310056bdd12
4
+ data.tar.gz: aa71893e95f7a7e8ba8de8123987445262edd6dbcad7efba12337091a2421d14
5
5
  SHA512:
6
- metadata.gz: 101e6e13aeed0cf2250dbe962c0c9c9edc5bf69e6ff2a59ee0d02018992c9b76dcaa4be3ddb44bbcb2272e355278a0b717c51050a2786cc95c00fbdb23bc40fa
7
- data.tar.gz: 2d3130c067d51f173873d6181b76999dd897c241dcafc5fa3f69ec0837404b2fd7e292cadc2fbf9e27003e3dfd933dc394799abf03f12187d6c80e4f2dab83d6
6
+ metadata.gz: 9380e218a2433f61a88676fb807ecb742391dff2c6d7e4937d24ff1385839ed897eaf81eb3d8d1f916bcf53f30cd2fd9c31f0c78fcd6c0e35d3753dc1d3a1252
7
+ data.tar.gz: 2ce69a5e542390018f779e9ba0a73263b362b3a6d69838494da73d18cb6f84a3262ed98fd086bb098ffa253f264db4d3e1d40e5ae8f9757ca1928c36ce9f02ce
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.6.1 2023-05-28
2
+
3
+ - Fix sending response with frozen headers hash
4
+
1
5
  ## 0.6 2023-01-05
2
6
 
3
7
  - Add documentation
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- h1p (0.6)
4
+ h1p (0.6.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -230,15 +230,22 @@ arbitrary IO instances. To write a response with or without a body, use
230
230
 
231
231
  ```ruby
232
232
  H1P.send_response(socket, { 'Some-Header' => 'header value'}, 'foobar')
233
- #=> "HTTP/1.1 200 OK\r\nSome-Header: header value\r\n\r\nfoobar"
233
+ # HTTP/1.1 200 OK
234
+ # Some-Header: header value
235
+ #
236
+ # foobar
234
237
 
235
238
  # The :protocol pseudo header sets the protocol in the status line:
236
239
  H1P.send_response(socket, { ':protocol' => 'HTTP/0.9' })
237
- #=> "HTTP/0.9 200 OK\r\n\r\n"
240
+ # HTTP/0.9 200 OK
241
+ #
242
+ #
238
243
 
239
244
  # The :status pseudo header sets the response status:
240
245
  H1P.send_response(socket, { ':status' => '418 I\'m a teapot' })
241
- #=> "HTTP/1.1 418 I'm a teapot\r\n\r\n"
246
+ # HTTP/1.1 418 I'm a teapot
247
+ #
248
+ #
242
249
  ```
243
250
 
244
251
  To send responses using chunked transfer encoding use
@@ -246,7 +253,13 @@ To send responses using chunked transfer encoding use
246
253
 
247
254
  ```ruby
248
255
  H1P.send_chunked_response(socket, {}, "foobar")
249
- #=> "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n6\r\nfoobar\r\n0\r\n\r\n"
256
+ # HTTP/1.1 200 OK
257
+ # Transfer-Encoding: chunked
258
+ # 6
259
+ # foobar
260
+ # 0
261
+ #
262
+ #
250
263
  ```
251
264
 
252
265
  You can also call `H1P.send_chunked_response` with a block that provides the
@@ -263,10 +276,14 @@ To send individual chunks use `H1P.send_body_chunk`:
263
276
 
264
277
  ```ruby
265
278
  H1P.send_body_chunk(socket, 'foo')
266
- #=> "3\r\nfoo\r\n"
279
+ # 3
280
+ # foo
281
+ #
267
282
 
268
283
  H1P.send_body_chunk(socket, nil)
269
- #=> "0\r\n\r\n"
284
+ # 0
285
+ #
286
+ #
270
287
  ```
271
288
 
272
289
  ## Parser Design
data/ext/h1p/h1p.c CHANGED
@@ -1236,10 +1236,11 @@ VALUE H1P_send_response(int argc,VALUE *argv, VALUE self) {
1236
1236
 
1237
1237
  bodyptr = RSTRING_PTR(body);
1238
1238
  bodylen = RSTRING_LEN(body);
1239
- rb_hash_aset(headers, STR_content_length_capitalized, INT2FIX(bodylen));
1239
+ // rb_hash_aset(headers, STR_content_length_capitalized, INT2FIX(bodylen));
1240
1240
  }
1241
1241
 
1242
1242
  rb_hash_foreach(headers, send_response_write_header, (VALUE)&ctx);
1243
+ send_response_write_header(STR_content_length_capitalized, INT2FIX(bodylen), (VALUE)&ctx);
1243
1244
 
1244
1245
  char *endptr = ctx.buffer_ptr + ctx.buffer_len;
1245
1246
  endptr[0] = '\r';
@@ -1309,8 +1310,8 @@ VALUE H1P_send_chunked_response(VALUE self, VALUE io, VALUE headers) {
1309
1310
  if (status == Qnil) status = STR_pseudo_status_default;
1310
1311
  send_response_write_status_line(&ctx, protocol, status);
1311
1312
 
1312
- rb_hash_aset(headers, STR_transfer_encoding_capitalized, STR_chunked);
1313
1313
  rb_hash_foreach(headers, send_response_write_header, (VALUE)&ctx);
1314
+ send_response_write_header(STR_transfer_encoding_capitalized, STR_chunked, (VALUE)&ctx);
1314
1315
 
1315
1316
  ctx.buffer_ptr[ctx.buffer_len] = '\r';
1316
1317
  ctx.buffer_ptr[ctx.buffer_len + 1] = '\n';
data/lib/h1p/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module H1P
4
- VERSION = '0.6'
4
+ VERSION = '0.6.1'
5
5
  end
data/test/test_h1p.rb CHANGED
@@ -9,30 +9,30 @@ class SendResponseTest < MiniTest::Test
9
9
  H1P.send_response(o, { ':status' => '418 I\'m a teapot' })
10
10
  o.close
11
11
  response = i.read
12
- assert_equal "HTTP/1.1 418 I'm a teapot\r\n\r\n", response
12
+ assert_equal "HTTP/1.1 418 I'm a teapot\r\nContent-Length: 0\r\n\r\n", response
13
13
 
14
14
  i, o = IO.pipe
15
15
  count = H1P.send_response(o, { ':protocol' => 'HTTP/1.0' })
16
16
  o.close
17
17
  response = i.read
18
- assert_equal "HTTP/1.0 200 OK\r\n\r\n", response
19
- assert_equal "HTTP/1.0 200 OK\r\n\r\n".bytesize, count
18
+ assert_equal "HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n", response
19
+ assert_equal "HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n".bytesize, count
20
20
  end
21
21
 
22
22
  def test_send_response_string_headers
23
23
  i, o = IO.pipe
24
- H1P.send_response(o, { 'Foo' => 'Bar', 'Content-Length' => '123' })
24
+ H1P.send_response(o, { 'Foo' => 'Bar', 'X-Blah' => '123' })
25
25
  o.close
26
26
  response = i.read
27
- assert_equal "HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 123\r\n\r\n", response
27
+ assert_equal "HTTP/1.1 200 OK\r\nFoo: Bar\r\nX-Blah: 123\r\nContent-Length: 0\r\n\r\n", response
28
28
  end
29
29
 
30
30
  def test_send_response_non_string_headers
31
31
  i, o = IO.pipe
32
- H1P.send_response(o, { :Foo => 'Bar', 'Content-Length' => 123 })
32
+ H1P.send_response(o, { :Foo => 'Bar', 'X-Blah' => 123 })
33
33
  o.close
34
34
  response = i.read
35
- assert_equal "HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 123\r\n\r\n", response
35
+ assert_equal "HTTP/1.1 200 OK\r\nFoo: Bar\r\nX-Blah: 123\r\nContent-Length: 0\r\n\r\n", response
36
36
  end
37
37
 
38
38
  def test_send_response_with_body
@@ -43,6 +43,15 @@ class SendResponseTest < MiniTest::Test
43
43
  assert_equal "HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nfoobar", response
44
44
  end
45
45
 
46
+ def test_send_response_with_frozen_headers_hash
47
+ i, o = IO.pipe
48
+ h = {Foo: 'bar'}.freeze
49
+ H1P.send_response(o, h, 'foo')
50
+ o.close
51
+ response = i.read
52
+ assert_equal "HTTP/1.1 200 OK\r\nFoo: bar\r\nContent-Length: 3\r\n\r\nfoo", response
53
+ end
54
+
46
55
  def test_send_response_with_big_body
47
56
  i, o = IO.pipe
48
57
  body = "abcdefg" * 10000
@@ -111,4 +120,21 @@ class SendChunkedResponseTest < MiniTest::Test
111
120
  assert_equal "HTTP/1.1 200 OK\r\nFoo: bar\r\nTransfer-Encoding: chunked\r\n\r\n3\r\nfoo\r\n3\r\nbar\r\n3\r\nbaz\r\n0\r\n\r\n", response
112
121
  assert_equal len, response.bytesize
113
122
  end
123
+
124
+ def test_send_chunked_response_with_frozen_headers_hash
125
+ isrc, osrc = IO.pipe
126
+ osrc << 'foobarbaz'
127
+ osrc.close
128
+
129
+ i, o = IO.pipe
130
+ h = { 'Foo' => 'bar' }.freeze
131
+ len = H1P.send_chunked_response(o, h) do
132
+ isrc.read(3)
133
+ end
134
+ o.close
135
+
136
+ response = i.read
137
+ assert_equal "HTTP/1.1 200 OK\r\nFoo: bar\r\nTransfer-Encoding: chunked\r\n\r\n3\r\nfoo\r\n3\r\nbar\r\n3\r\nbaz\r\n0\r\n\r\n", response
138
+ assert_equal len, response.bytesize
139
+ end
114
140
  end
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.6'
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-05 00:00:00.000000000 Z
11
+ date: 2023-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler