kcar 0.1.1 → 0.1.2
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.
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +2 -1
- data/ext/kcar/kcar.rl +7 -1
- data/lib/kcar.rb +2 -2
- data/lib/kcar/response.rb +3 -1
- data/test/test_parser.rb +1 -1
- data/test/test_response.rb +32 -0
- metadata +4 -4
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
|
@@ -5,6 +5,7 @@ RAKE = rake
|
|
|
5
5
|
RAGEL = ragel
|
|
6
6
|
GIT_URL = git://git.bogomips.org/kcar.git
|
|
7
7
|
RLFLAGS = -G2
|
|
8
|
+
RSYNC = rsync
|
|
8
9
|
|
|
9
10
|
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
|
10
11
|
@./GIT-VERSION-GEN
|
|
@@ -183,7 +184,7 @@ publish_doc:
|
|
|
183
184
|
TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css
|
|
184
185
|
$(MAKE) doc_gz
|
|
185
186
|
chmod 644 $$(find doc -type f)
|
|
186
|
-
|
|
187
|
+
$(RSYNC) -av doc/ dcvr:/srv/bogomips/kcar/
|
|
187
188
|
git ls-files | xargs touch
|
|
188
189
|
|
|
189
190
|
# Create gzip variants of the same timestamp as the original so nginx
|
data/ext/kcar/kcar.rl
CHANGED
|
@@ -42,6 +42,7 @@ DEF_MAX_LENGTH(REASON, 256);
|
|
|
42
42
|
#define UH_FL_INTRAILER 0x10
|
|
43
43
|
#define UH_FL_INCHUNK 0x20
|
|
44
44
|
#define UH_FL_KEEPALIVE 0x40
|
|
45
|
+
#define UH_FL_HASHEADER 0x80
|
|
45
46
|
|
|
46
47
|
struct http_parser {
|
|
47
48
|
int cs; /* Ragel internal state */
|
|
@@ -178,6 +179,8 @@ static void write_value(VALUE hdr, struct http_parser *hp,
|
|
|
178
179
|
const char *vptr;
|
|
179
180
|
long vlen;
|
|
180
181
|
|
|
182
|
+
HP_FL_SET(hp, HASHEADER);
|
|
183
|
+
|
|
181
184
|
/* Rack does not like Status headers, so we never send them */
|
|
182
185
|
if (CSTR_CASE_EQ(fptr, flen, "status")) {
|
|
183
186
|
hp->cont = Qnil;
|
|
@@ -534,6 +537,9 @@ static VALUE body_eof(VALUE self)
|
|
|
534
537
|
{
|
|
535
538
|
struct http_parser *hp = data_get(self);
|
|
536
539
|
|
|
540
|
+
if (!HP_FL_TEST(hp, HASHEADER) && HP_FL_ALL(hp, KEEPALIVE))
|
|
541
|
+
return Qtrue;
|
|
542
|
+
|
|
537
543
|
if (HP_FL_TEST(hp, CHUNKED))
|
|
538
544
|
return chunked_eof(hp) ? Qtrue : Qfalse;
|
|
539
545
|
|
|
@@ -560,7 +566,7 @@ static VALUE keepalive(VALUE self)
|
|
|
560
566
|
struct http_parser *hp = data_get(self);
|
|
561
567
|
|
|
562
568
|
if (HP_FL_ALL(hp, KEEPALIVE)) {
|
|
563
|
-
if ( HP_FL_TEST(hp, HASBODY) ) {
|
|
569
|
+
if (HP_FL_TEST(hp, HASHEADER) && HP_FL_TEST(hp, HASBODY) ) {
|
|
564
570
|
if (HP_FL_TEST(hp, CHUNKED) || (hp->len.content >= 0))
|
|
565
571
|
return Qtrue;
|
|
566
572
|
|
data/lib/kcar.rb
CHANGED
data/lib/kcar/response.rb
CHANGED
|
@@ -62,7 +62,9 @@ class Response < Struct.new(:sock, :hdr, :unchunk, :buf, :parser)
|
|
|
62
62
|
# body. It may only be called once (usually by a Rack server) as it streams
|
|
63
63
|
# the response body off the our socket object.
|
|
64
64
|
def each(&block)
|
|
65
|
-
|
|
65
|
+
if parser.body_eof?
|
|
66
|
+
return
|
|
67
|
+
end
|
|
66
68
|
if unchunk
|
|
67
69
|
parser.chunked? ? each_unchunk(&block) : each_identity(&block)
|
|
68
70
|
else
|
data/test/test_parser.rb
CHANGED
|
@@ -32,7 +32,7 @@ class TestParser < Test::Unit::TestCase
|
|
|
32
32
|
response = @hp.headers(hdr, buf)
|
|
33
33
|
assert_equal(["200 OK", hdr], response)
|
|
34
34
|
assert hdr.empty?
|
|
35
|
-
assert
|
|
35
|
+
assert @hp.keepalive? # no content-length
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def test_parser_status_with_content_length
|
data/test/test_response.rb
CHANGED
|
@@ -4,12 +4,44 @@ require 'pp'
|
|
|
4
4
|
require 'socket'
|
|
5
5
|
require 'kcar'
|
|
6
6
|
require 'digest/sha1'
|
|
7
|
+
$stderr.sync = true
|
|
7
8
|
|
|
8
9
|
class TestSession < Test::Unit::TestCase
|
|
9
10
|
def setup
|
|
10
11
|
@s, @c = UNIXSocket.pair
|
|
11
12
|
end
|
|
12
13
|
|
|
14
|
+
def test_http_status_only_pipelined
|
|
15
|
+
resp = "HTTP/1.1 404 Not Found\r\n\r\n" \
|
|
16
|
+
"HTTP/1.1 404 Not Found\r\n\r\n"
|
|
17
|
+
pid = fork do
|
|
18
|
+
@s << resp
|
|
19
|
+
@s.close
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@s.close
|
|
23
|
+
@response = Kcar::Response.new(@c)
|
|
24
|
+
status, headers, body = @response.rack
|
|
25
|
+
assert_equal status, "404 Not Found"
|
|
26
|
+
assert_equal({}, headers)
|
|
27
|
+
tmp = []
|
|
28
|
+
assert_nothing_raised { body.each { |chunk| tmp << chunk.dup } }
|
|
29
|
+
assert_equal [], tmp
|
|
30
|
+
assert @response.parser.keepalive?
|
|
31
|
+
body.close
|
|
32
|
+
|
|
33
|
+
status, headers, body = @response.rack
|
|
34
|
+
assert_equal status, "404 Not Found"
|
|
35
|
+
assert_equal({},headers)
|
|
36
|
+
tmp = []
|
|
37
|
+
assert_nothing_raised { body.each { |chunk| tmp << chunk.dup } }
|
|
38
|
+
assert_equal [], tmp
|
|
39
|
+
|
|
40
|
+
_, status = Process.waitpid2(pid)
|
|
41
|
+
assert status.success?
|
|
42
|
+
body.close
|
|
43
|
+
end
|
|
44
|
+
|
|
13
45
|
def test_http_small_pipelined_identity
|
|
14
46
|
resp = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world\n" \
|
|
15
47
|
"HTTP/1.1 200 OK\r\nContent-Length: 14\r\n\r\ngoodbye world\n"
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kcar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 31
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 1
|
|
9
|
-
-
|
|
10
|
-
version: 0.1.
|
|
9
|
+
- 2
|
|
10
|
+
version: 0.1.2
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- kcar hackers
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2010-
|
|
18
|
+
date: 2010-11-30 00:00:00 +00:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies: []
|
|
21
21
|
|