h1p 0.6 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +23 -6
- data/ext/h1p/h1p.c +3 -2
- data/lib/h1p/version.rb +1 -1
- data/test/test_h1p.rb +33 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96197142deeb30d27fe9b3fc9de21a07ed1de8f0a1d3db9b8d967310056bdd12
|
4
|
+
data.tar.gz: aa71893e95f7a7e8ba8de8123987445262edd6dbcad7efba12337091a2421d14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9380e218a2433f61a88676fb807ecb742391dff2c6d7e4937d24ff1385839ed897eaf81eb3d8d1f916bcf53f30cd2fd9c31f0c78fcd6c0e35d3753dc1d3a1252
|
7
|
+
data.tar.gz: 2ce69a5e542390018f779e9ba0a73263b362b3a6d69838494da73d18cb6f84a3262ed98fd086bb098ffa253f264db4d3e1d40e5ae8f9757ca1928c36ce9f02ce
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
279
|
+
# 3
|
280
|
+
# foo
|
281
|
+
#
|
267
282
|
|
268
283
|
H1P.send_body_chunk(socket, nil)
|
269
|
-
|
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
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', '
|
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:
|
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', '
|
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:
|
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:
|
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-
|
11
|
+
date: 2023-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|