http_parser.rb 0.5.0-x86-mswin32-60

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.
Files changed (57) hide show
  1. data/.gitignore +11 -0
  2. data/.gitmodules +6 -0
  3. data/README.md +45 -0
  4. data/Rakefile +6 -0
  5. data/bench/thin.rb +57 -0
  6. data/ext/ruby_http_parser/.gitignore +1 -0
  7. data/ext/ruby_http_parser/RubyHttpParserService.java +18 -0
  8. data/ext/ruby_http_parser/ext_help.h +18 -0
  9. data/ext/ruby_http_parser/extconf.rb +16 -0
  10. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +403 -0
  11. data/ext/ruby_http_parser/ruby_http_parser.c +474 -0
  12. data/ext/ruby_http_parser/vendor/.gitkeep +0 -0
  13. data/ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS +4 -0
  14. data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +19 -0
  15. data/ext/ruby_http_parser/vendor/http-parser-java/README.md +171 -0
  16. data/ext/ruby_http_parser/vendor/http-parser-java/TODO +19 -0
  17. data/ext/ruby_http_parser/vendor/http-parser-java/compile +1 -0
  18. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +1590 -0
  19. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +167 -0
  20. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +7 -0
  21. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +90 -0
  22. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +31 -0
  23. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java +13 -0
  24. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java +5 -0
  25. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java +25 -0
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java +7 -0
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +1894 -0
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +78 -0
  29. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/Util.java +112 -0
  30. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +487 -0
  31. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +115 -0
  32. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +1865 -0
  33. data/ext/ruby_http_parser/vendor/http-parser-java/test_permutations +1 -0
  34. data/ext/ruby_http_parser/vendor/http-parser-java/test_unit +1 -0
  35. data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +539 -0
  36. data/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb +6 -0
  37. data/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb +13 -0
  38. data/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb +15 -0
  39. data/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb +33 -0
  40. data/ext/ruby_http_parser/vendor/http-parser/CONTRIBUTIONS +4 -0
  41. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +19 -0
  42. data/ext/ruby_http_parser/vendor/http-parser/README.md +171 -0
  43. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +1590 -0
  44. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +167 -0
  45. data/ext/ruby_http_parser/vendor/http-parser/test.c +1755 -0
  46. data/http_parser.rb.gemspec +15 -0
  47. data/lib/http/parser.rb +1 -0
  48. data/lib/http_parser.rb +4 -0
  49. data/lib/ruby_http_parser.rb +2 -0
  50. data/spec/parser_spec.rb +187 -0
  51. data/spec/spec_helper.rb +2 -0
  52. data/spec/support/requests.json +381 -0
  53. data/spec/support/responses.json +186 -0
  54. data/tasks/compile.rake +39 -0
  55. data/tasks/spec.rake +5 -0
  56. data/tasks/submodules.rake +7 -0
  57. metadata +124 -0
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "http_parser.rb"
3
+ s.version = "0.5.0"
4
+ s.summary = "Simple callback-based HTTP request/response parser"
5
+ s.description = "Ruby bindings to http://github.com/ry/http-parser and http://github.com/a2800276/http-parser.java"
6
+
7
+ s.authors = ["Marc-Andre Cournoyer", "Aman Gupta"]
8
+ s.email = ["macournoyer@gmail.com", "aman@tmm1.net"]
9
+
10
+ s.homepage = "http://github.com/tmm1/http_parser.rb"
11
+ s.files = `git ls-files`.split("\n") + Dir['ext/ruby_http_parser/vendor/**/*']
12
+
13
+ s.require_paths = ["lib"]
14
+ s.extensions = ["ext/ruby_http_parser/extconf.rb"]
15
+ end
@@ -0,0 +1 @@
1
+ require 'http_parser'
@@ -0,0 +1,4 @@
1
+ $:.unshift File.expand_path('../', __FILE__)
2
+ require 'ruby_http_parser'
3
+
4
+ Http = HTTP
@@ -0,0 +1,2 @@
1
+ RUBY_VERSION =~ /(\d+.\d+)/
2
+ require "#{$1}/ruby_http_parser"
@@ -0,0 +1,187 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe HTTP::Parser do
5
+ before do
6
+ @parser = HTTP::Parser.new
7
+
8
+ @headers = nil
9
+ @body = ""
10
+ @started = false
11
+ @done = false
12
+
13
+ @parser.on_message_begin = proc{ @started = true }
14
+ @parser.on_headers_complete = proc { |e| @headers = e }
15
+ @parser.on_body = proc { |chunk| @body << chunk }
16
+ @parser.on_message_complete = proc{ @done = true }
17
+ end
18
+
19
+ it "should have initial state" do
20
+ @parser.headers.should be_nil
21
+
22
+ @parser.http_version.should be_nil
23
+ @parser.http_method.should be_nil
24
+ @parser.status_code.should be_nil
25
+
26
+ @parser.request_url.should be_nil
27
+ @parser.request_path.should be_nil
28
+ @parser.query_string.should be_nil
29
+ @parser.fragment.should be_nil
30
+ end
31
+
32
+ it "should implement basic api" do
33
+ @parser <<
34
+ "GET /test?ok=1 HTTP/1.1\r\n" +
35
+ "User-Agent: curl/7.18.0\r\n" +
36
+ "Host: 0.0.0.0:5000\r\n" +
37
+ "Accept: */*\r\n" +
38
+ "Content-Length: 5\r\n" +
39
+ "\r\n" +
40
+ "World"
41
+
42
+ @started.should be_true
43
+ @done.should be_true
44
+
45
+ @parser.http_major.should == 1
46
+ @parser.http_minor.should == 1
47
+ @parser.http_version.should == [1,1]
48
+ @parser.http_method.should == 'GET'
49
+ @parser.status_code.should be_nil
50
+
51
+ @parser.request_url.should == '/test?ok=1'
52
+ @parser.request_path.should == '/test'
53
+ @parser.query_string.should == 'ok=1'
54
+ @parser.fragment.should be_empty
55
+
56
+ @parser.headers.should == @headers
57
+ @parser.headers['User-Agent'].should == 'curl/7.18.0'
58
+ @parser.headers['Host'].should == '0.0.0.0:5000'
59
+
60
+ @body.should == "World"
61
+ end
62
+
63
+ it "should raise errors on invalid data" do
64
+ proc{ @parser << "BLAH" }.should raise_error(HTTP::Parser::Error)
65
+ end
66
+
67
+ it "should abort parser via callback" do
68
+ @parser.on_headers_complete = proc { |e| @headers = e; :stop }
69
+
70
+ data =
71
+ "GET / HTTP/1.0\r\n" +
72
+ "Content-Length: 5\r\n" +
73
+ "\r\n" +
74
+ "World"
75
+
76
+ bytes = @parser << data
77
+
78
+ bytes.should == 37
79
+ data[bytes..-1].should == 'World'
80
+
81
+ @headers.should == {'Content-Length' => '5'}
82
+ @body.should be_empty
83
+ @done.should be_false
84
+ end
85
+
86
+ it "should reset to initial state" do
87
+ @parser << "GET / HTTP/1.0\r\n\r\n"
88
+
89
+ @parser.http_method.should == 'GET'
90
+ @parser.http_version.should == [1,0]
91
+
92
+ @parser.request_url.should == '/'
93
+ @parser.request_path.should == '/'
94
+ @parser.query_string.should == ''
95
+ @parser.fragment.should == ''
96
+
97
+ @parser.reset!.should be_true
98
+
99
+ @parser.http_version.should be_nil
100
+ @parser.http_method.should be_nil
101
+ @parser.status_code.should be_nil
102
+
103
+ @parser.request_url.should be_nil
104
+ @parser.request_path.should be_nil
105
+ @parser.query_string.should be_nil
106
+ @parser.fragment.should be_nil
107
+ end
108
+
109
+ it "should retain callbacks after reset" do
110
+ @parser.reset!.should be_true
111
+
112
+ @parser << "GET / HTTP/1.0\r\n\r\n"
113
+ @started.should be_true
114
+ @headers.should == {}
115
+ @done.should be_true
116
+ end
117
+
118
+ it "should handle multiple headers" do
119
+ @parser <<
120
+ "GET / HTTP/1.0\r\n" +
121
+ "Header: value 1\r\n" +
122
+ "Header: value 2\r\n" +
123
+ "\r\n"
124
+
125
+ @parser.headers.should == {
126
+ 'Header' => 'value 1, value 2'
127
+ }
128
+ end
129
+
130
+ it "should support alternative api" do
131
+ callbacks = double('callbacks')
132
+ callbacks.stub(:on_message_begin){ @started = true }
133
+ callbacks.stub(:on_headers_complete){ |e| @headers = e }
134
+ callbacks.stub(:on_body){ |chunk| @body << chunk }
135
+ callbacks.stub(:on_message_complete){ @done = true }
136
+
137
+ @parser = HTTP::Parser.new(callbacks)
138
+ @parser << "GET / HTTP/1.0\r\n\r\n"
139
+
140
+ @started.should be_true
141
+ @headers.should == {}
142
+ @body.should == ''
143
+ @done.should be_true
144
+ end
145
+
146
+ %w[ request response ].each do |type|
147
+ JSON.parse(File.read(File.expand_path("../support/#{type}s.json", __FILE__))).each do |test|
148
+ test['headers'] ||= {}
149
+
150
+ it "should parse #{type}: #{test['name']}" do
151
+ @parser << test['raw']
152
+
153
+ @parser.keep_alive?.should == test['should_keep_alive']
154
+ @parser.upgrade?.should == (test['upgrade']==1)
155
+ @parser.http_method.should == test['method']
156
+
157
+ fields = %w[
158
+ http_major
159
+ http_minor
160
+ ]
161
+
162
+ if test['type'] == 'HTTP_REQUEST'
163
+ fields += %w[
164
+ request_url
165
+ request_path
166
+ query_string
167
+ fragment
168
+ ]
169
+ else
170
+ fields += %w[
171
+ status_code
172
+ ]
173
+ end
174
+
175
+ fields.each do |field|
176
+ @parser.send(field).should == test[field]
177
+ end
178
+
179
+ @headers.size.should == test['num_headers']
180
+ @headers.should == test['headers']
181
+
182
+ @body.should == test['body']
183
+ @body.size.should == test['body_size'] if test['body_size']
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,2 @@
1
+ require "rubygems"
2
+ require "http_parser"
@@ -0,0 +1,381 @@
1
+ [
2
+ {
3
+ "name": "curl get",
4
+ "type": "HTTP_REQUEST",
5
+ "raw": "GET /test HTTP/1.1\r\nUser-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\nHost: 0.0.0.0=5000\r\nAccept: */*\r\n\r\n",
6
+ "should_keep_alive": true,
7
+ "message_complete_on_eof": false,
8
+ "http_major": 1,
9
+ "http_minor": 1,
10
+ "method": "GET",
11
+ "query_string": "",
12
+ "fragment": "",
13
+ "request_path": "/test",
14
+ "request_url": "/test",
15
+ "num_headers": 3,
16
+ "headers": {
17
+ "User-Agent": "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1",
18
+ "Host": "0.0.0.0=5000",
19
+ "Accept": "*/*"
20
+ },
21
+ "body": ""
22
+ },
23
+ {
24
+ "name": "firefox get",
25
+ "type": "HTTP_REQUEST",
26
+ "raw": "GET /favicon.ico HTTP/1.1\r\nHost: 0.0.0.0=5000\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nConnection: keep-alive\r\n\r\n",
27
+ "should_keep_alive": true,
28
+ "message_complete_on_eof": false,
29
+ "http_major": 1,
30
+ "http_minor": 1,
31
+ "method": "GET",
32
+ "query_string": "",
33
+ "fragment": "",
34
+ "request_path": "/favicon.ico",
35
+ "request_url": "/favicon.ico",
36
+ "num_headers": 8,
37
+ "headers": {
38
+ "Host": "0.0.0.0=5000",
39
+ "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0",
40
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
41
+ "Accept-Language": "en-us,en;q=0.5",
42
+ "Accept-Encoding": "gzip,deflate",
43
+ "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
44
+ "Keep-Alive": "300",
45
+ "Connection": "keep-alive"
46
+ },
47
+ "body": ""
48
+ },
49
+ {
50
+ "name": "dumbfuck",
51
+ "type": "HTTP_REQUEST",
52
+ "raw": "GET /dumbfuck HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n",
53
+ "should_keep_alive": true,
54
+ "message_complete_on_eof": false,
55
+ "http_major": 1,
56
+ "http_minor": 1,
57
+ "method": "GET",
58
+ "query_string": "",
59
+ "fragment": "",
60
+ "request_path": "/dumbfuck",
61
+ "request_url": "/dumbfuck",
62
+ "num_headers": 1,
63
+ "headers": {
64
+ "aaaaaaaaaaaaa": "++++++++++"
65
+ },
66
+ "body": ""
67
+ },
68
+ {
69
+ "name": "fragment in url",
70
+ "type": "HTTP_REQUEST",
71
+ "raw": "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n",
72
+ "should_keep_alive": true,
73
+ "message_complete_on_eof": false,
74
+ "http_major": 1,
75
+ "http_minor": 1,
76
+ "method": "GET",
77
+ "query_string": "page=1",
78
+ "fragment": "posts-17408",
79
+ "request_path": "/forums/1/topics/2375",
80
+ "request_url": "/forums/1/topics/2375?page=1#posts-17408",
81
+ "num_headers": 0,
82
+ "body": ""
83
+ },
84
+ {
85
+ "name": "get no headers no body",
86
+ "type": "HTTP_REQUEST",
87
+ "raw": "GET /get_no_headers_no_body/world HTTP/1.1\r\n\r\n",
88
+ "should_keep_alive": true,
89
+ "message_complete_on_eof": false,
90
+ "http_major": 1,
91
+ "http_minor": 1,
92
+ "method": "GET",
93
+ "query_string": "",
94
+ "fragment": "",
95
+ "request_path": "/get_no_headers_no_body/world",
96
+ "request_url": "/get_no_headers_no_body/world",
97
+ "num_headers": 0,
98
+ "body": ""
99
+ },
100
+ {
101
+ "name": "get one header no body",
102
+ "type": "HTTP_REQUEST",
103
+ "raw": "GET /get_one_header_no_body HTTP/1.1\r\nAccept: */*\r\n\r\n",
104
+ "should_keep_alive": true,
105
+ "message_complete_on_eof": false,
106
+ "http_major": 1,
107
+ "http_minor": 1,
108
+ "method": "GET",
109
+ "query_string": "",
110
+ "fragment": "",
111
+ "request_path": "/get_one_header_no_body",
112
+ "request_url": "/get_one_header_no_body",
113
+ "num_headers": 1,
114
+ "headers": {
115
+ "Accept": "*/*"
116
+ },
117
+ "body": ""
118
+ },
119
+ {
120
+ "name": "get funky content length body hello",
121
+ "type": "HTTP_REQUEST",
122
+ "raw": "GET /get_funky_content_length_body_hello HTTP/1.0\r\nconTENT-Length: 5\r\n\r\nHELLO",
123
+ "should_keep_alive": false,
124
+ "message_complete_on_eof": false,
125
+ "http_major": 1,
126
+ "http_minor": 0,
127
+ "method": "GET",
128
+ "query_string": "",
129
+ "fragment": "",
130
+ "request_path": "/get_funky_content_length_body_hello",
131
+ "request_url": "/get_funky_content_length_body_hello",
132
+ "num_headers": 1,
133
+ "headers": {
134
+ "conTENT-Length": "5"
135
+ },
136
+ "body": "HELLO"
137
+ },
138
+ {
139
+ "name": "post identity body world",
140
+ "type": "HTTP_REQUEST",
141
+ "raw": "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\nAccept: */*\r\nTransfer-Encoding: identity\r\nContent-Length: 5\r\n\r\nWorld",
142
+ "should_keep_alive": true,
143
+ "message_complete_on_eof": false,
144
+ "http_major": 1,
145
+ "http_minor": 1,
146
+ "method": "POST",
147
+ "query_string": "q=search",
148
+ "fragment": "hey",
149
+ "request_path": "/post_identity_body_world",
150
+ "request_url": "/post_identity_body_world?q=search#hey",
151
+ "num_headers": 3,
152
+ "headers": {
153
+ "Accept": "*/*",
154
+ "Transfer-Encoding": "identity",
155
+ "Content-Length": "5"
156
+ },
157
+ "body": "World"
158
+ },
159
+ {
160
+ "name": "post - chunked body: all your base are belong to us",
161
+ "type": "HTTP_REQUEST",
162
+ "raw": "POST /post_chunked_all_your_base HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n1e\r\nall your base are belong to us\r\n0\r\n\r\n",
163
+ "should_keep_alive": true,
164
+ "message_complete_on_eof": false,
165
+ "http_major": 1,
166
+ "http_minor": 1,
167
+ "method": "POST",
168
+ "query_string": "",
169
+ "fragment": "",
170
+ "request_path": "/post_chunked_all_your_base",
171
+ "request_url": "/post_chunked_all_your_base",
172
+ "num_headers": 1,
173
+ "headers": {
174
+ "Transfer-Encoding": "chunked"
175
+ },
176
+ "body": "all your base are belong to us"
177
+ },
178
+ {
179
+ "name": "two chunks ; triple zero ending",
180
+ "type": "HTTP_REQUEST",
181
+ "raw": "POST /two_chunks_mult_zero_end HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n6\r\n world\r\n000\r\n\r\n",
182
+ "should_keep_alive": true,
183
+ "message_complete_on_eof": false,
184
+ "http_major": 1,
185
+ "http_minor": 1,
186
+ "method": "POST",
187
+ "query_string": "",
188
+ "fragment": "",
189
+ "request_path": "/two_chunks_mult_zero_end",
190
+ "request_url": "/two_chunks_mult_zero_end",
191
+ "num_headers": 1,
192
+ "headers": {
193
+ "Transfer-Encoding": "chunked"
194
+ },
195
+ "body": "hello world"
196
+ },
197
+ {
198
+ "name": "chunked with trailing headers. blech.",
199
+ "type": "HTTP_REQUEST",
200
+ "raw": "POST /chunked_w_trailing_headers HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n6\r\n world\r\n0\r\nVary: *\r\nContent-Type: text/plain\r\n\r\n",
201
+ "should_keep_alive": true,
202
+ "message_complete_on_eof": false,
203
+ "http_major": 1,
204
+ "http_minor": 1,
205
+ "method": "POST",
206
+ "query_string": "",
207
+ "fragment": "",
208
+ "request_path": "/chunked_w_trailing_headers",
209
+ "request_url": "/chunked_w_trailing_headers",
210
+ "num_headers": 3,
211
+ "headers": {
212
+ "Transfer-Encoding": "chunked",
213
+ "Vary": "*",
214
+ "Content-Type": "text/plain"
215
+ },
216
+ "body": "hello world"
217
+ },
218
+ {
219
+ "name": "with bullshit after the length",
220
+ "type": "HTTP_REQUEST",
221
+ "raw": "POST /chunked_w_bullshit_after_length HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n6; blahblah; blah\r\n world\r\n0\r\n\r\n",
222
+ "should_keep_alive": true,
223
+ "message_complete_on_eof": false,
224
+ "http_major": 1,
225
+ "http_minor": 1,
226
+ "method": "POST",
227
+ "query_string": "",
228
+ "fragment": "",
229
+ "request_path": "/chunked_w_bullshit_after_length",
230
+ "request_url": "/chunked_w_bullshit_after_length",
231
+ "num_headers": 1,
232
+ "headers": {
233
+ "Transfer-Encoding": "chunked"
234
+ },
235
+ "body": "hello world"
236
+ },
237
+ {
238
+ "name": "with quotes",
239
+ "type": "HTTP_REQUEST",
240
+ "raw": "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n",
241
+ "should_keep_alive": true,
242
+ "message_complete_on_eof": false,
243
+ "http_major": 1,
244
+ "http_minor": 1,
245
+ "method": "GET",
246
+ "query_string": "foo=\"bar\"",
247
+ "fragment": "",
248
+ "request_path": "/with_\"stupid\"_quotes",
249
+ "request_url": "/with_\"stupid\"_quotes?foo=\"bar\"",
250
+ "num_headers": 0,
251
+ "headers": {
252
+
253
+ },
254
+ "body": ""
255
+ },
256
+ {
257
+ "name": "apachebench get",
258
+ "type": "HTTP_REQUEST",
259
+ "raw": "GET /test HTTP/1.0\r\nHost: 0.0.0.0:5000\r\nUser-Agent: ApacheBench/2.3\r\nAccept: */*\r\n\r\n",
260
+ "should_keep_alive": false,
261
+ "message_complete_on_eof": false,
262
+ "http_major": 1,
263
+ "http_minor": 0,
264
+ "method": "GET",
265
+ "query_string": "",
266
+ "fragment": "",
267
+ "request_path": "/test",
268
+ "request_url": "/test",
269
+ "num_headers": 3,
270
+ "headers": {
271
+ "Host": "0.0.0.0:5000",
272
+ "User-Agent": "ApacheBench/2.3",
273
+ "Accept": "*/*"
274
+ },
275
+ "body": ""
276
+ },
277
+ {
278
+ "name": "query url with question mark",
279
+ "type": "HTTP_REQUEST",
280
+ "raw": "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n",
281
+ "should_keep_alive": true,
282
+ "message_complete_on_eof": false,
283
+ "http_major": 1,
284
+ "http_minor": 1,
285
+ "method": "GET",
286
+ "query_string": "foo=bar?baz",
287
+ "fragment": "",
288
+ "request_path": "/test.cgi",
289
+ "request_url": "/test.cgi?foo=bar?baz",
290
+ "num_headers": 0,
291
+ "headers": {
292
+
293
+ },
294
+ "body": ""
295
+ },
296
+ {
297
+ "name": "newline prefix get",
298
+ "type": "HTTP_REQUEST",
299
+ "raw": "\r\nGET /test HTTP/1.1\r\n\r\n",
300
+ "should_keep_alive": true,
301
+ "message_complete_on_eof": false,
302
+ "http_major": 1,
303
+ "http_minor": 1,
304
+ "method": "GET",
305
+ "query_string": "",
306
+ "fragment": "",
307
+ "request_path": "/test",
308
+ "request_url": "/test",
309
+ "num_headers": 0,
310
+ "headers": {
311
+
312
+ },
313
+ "body": ""
314
+ },
315
+ {
316
+ "name": "upgrade request",
317
+ "type": "HTTP_REQUEST",
318
+ "raw": "GET /demo HTTP/1.1\r\nHost: example.com\r\nConnection: Upgrade\r\nSec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\nSec-WebSocket-Protocol: sample\r\nUpgrade: WebSocket\r\nSec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\nOrigin: http://example.com\r\n\r\n",
319
+ "should_keep_alive": true,
320
+ "message_complete_on_eof": false,
321
+ "http_major": 1,
322
+ "http_minor": 1,
323
+ "method": "GET",
324
+ "query_string": "",
325
+ "fragment": "",
326
+ "request_path": "/demo",
327
+ "request_url": "/demo",
328
+ "num_headers": 7,
329
+ "upgrade": 1,
330
+ "headers": {
331
+ "Host": "example.com",
332
+ "Connection": "Upgrade",
333
+ "Sec-WebSocket-Key2": "12998 5 Y3 1 .P00",
334
+ "Sec-WebSocket-Protocol": "sample",
335
+ "Upgrade": "WebSocket",
336
+ "Sec-WebSocket-Key1": "4 @1 46546xW%0l 1 5",
337
+ "Origin": "http://example.com"
338
+ },
339
+ "body": ""
340
+ },
341
+ {
342
+ "name": "connect request",
343
+ "type": "HTTP_REQUEST",
344
+ "raw": "CONNECT home.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n",
345
+ "should_keep_alive": false,
346
+ "message_complete_on_eof": false,
347
+ "http_major": 1,
348
+ "http_minor": 0,
349
+ "method": "CONNECT",
350
+ "query_string": "",
351
+ "fragment": "",
352
+ "request_path": "",
353
+ "request_url": "home.netscape.com:443",
354
+ "num_headers": 2,
355
+ "upgrade": 1,
356
+ "headers": {
357
+ "User-agent": "Mozilla/1.1N",
358
+ "Proxy-authorization": "basic aGVsbG86d29ybGQ="
359
+ },
360
+ "body": ""
361
+ },
362
+ {
363
+ "name": "report request",
364
+ "type": "HTTP_REQUEST",
365
+ "raw": "REPORT /test HTTP/1.1\r\n\r\n",
366
+ "should_keep_alive": true,
367
+ "message_complete_on_eof": false,
368
+ "http_major": 1,
369
+ "http_minor": 1,
370
+ "method": "REPORT",
371
+ "query_string": "",
372
+ "fragment": "",
373
+ "request_path": "/test",
374
+ "request_url": "/test",
375
+ "num_headers": 0,
376
+ "headers": {
377
+
378
+ },
379
+ "body": ""
380
+ }
381
+ ]