1
0
mirror of https://github.com/bitwarden/help synced 2025-12-27 21:53:15 +00:00

Promote to Master (#748)

* initial commit

* adding quotes for the array error

* Create Gemfile

* Create Gemfile.lock

* add .nvmrc and .node-version

* removed /article from URL

* update links to work with netlify

* more fixed links

* link fixes

* update bad links

* Update netlify.toml

toml test for redirects

* article redirect

* link fixes

* Update index.html

* Update netlify.toml

* Update _config.yml

* Update netlify.toml

* Update netlify.toml

* Update netlify.toml

* Update netlify.toml

* Update netlify.toml

* add article back into URL for launch

* Update netlify.toml

* Update netlify.toml

* add order to categories front matter

* Update netlify.toml

* update

* sidemenu update

* Revert "sidemenu update"

This reverts commit 5441c3d35c.

* update order prop

* Navbar updates per Gary and compiler warnings

* font/style tweaks

* Update sidebar.html

* Stage Release Documentation (#739)

* initial drafts

* rewrite Custom Fields article to prioritize new context-menu option & better organize ancillary information

* edit

* edit

* Custom Field Context Menu & CAPTCHA item in release notes

* SSO relink event

* update rn

* small edits

* improve release notes titles

* fix side menu

* Edits courtest of mportune!

* update order

* link fixes

* link cleanup

* image updates and a link

* fix trailing slash

Co-authored-by: DanHillesheim <79476558+DanHillesheim@users.noreply.github.com>
This commit is contained in:
fred_the_tech_writer
2021-09-21 13:21:11 -04:00
committed by GitHub
parent 63f78e8979
commit 906e2ca0dd
3304 changed files with 386714 additions and 8864 deletions

View File

@@ -0,0 +1,350 @@
require "spec_helper"
require "json"
describe HTTP::Parser do
before do
@parser = HTTP::Parser.new
@headers = nil
@body = ""
@started = false
@done = false
@parser.on_message_begin = proc{ @started = true }
@parser.on_headers_complete = proc { |e| @headers = e }
@parser.on_body = proc { |chunk| @body << chunk }
@parser.on_message_complete = proc{ @done = true }
end
it "should have initial state" do
@parser.headers.should be_nil
@parser.http_version.should be_nil
@parser.http_method.should be_nil
@parser.status_code.should be_nil
@parser.request_url.should be_nil
@parser.header_value_type.should == :mixed
end
it "should allow us to set the header value type" do
[:mixed, :arrays, :strings].each do |type|
@parser.header_value_type = type
@parser.header_value_type.should == type
parser_tmp = HTTP::Parser.new(nil, type)
parser_tmp.header_value_type.should == type
end
end
it "should allow us to set the default header value type" do
[:mixed, :arrays, :strings].each do |type|
HTTP::Parser.default_header_value_type = type
parser = HTTP::Parser.new
parser.header_value_type.should == type
end
end
it "should throw an Argument Error if header value type is invalid" do
proc{ @parser.header_value_type = 'bob' }.should raise_error(ArgumentError)
end
it "should throw an Argument Error if default header value type is invalid" do
proc{ HTTP::Parser.default_header_value_type = 'bob' }.should raise_error(ArgumentError)
end
it "should implement basic api" do
@parser <<
"GET /test?ok=1 HTTP/1.1\r\n" +
"User-Agent: curl/7.18.0\r\n" +
"Host: 0.0.0.0:5000\r\n" +
"Accept: */*\r\n" +
"Content-Length: 5\r\n" +
"\r\n" +
"World"
@started.should be_true
@done.should be_true
@parser.http_major.should == 1
@parser.http_minor.should == 1
@parser.http_version.should == [1,1]
@parser.http_method.should == 'GET'
@parser.status_code.should be_nil
@parser.request_url.should == '/test?ok=1'
@parser.headers.should == @headers
@parser.headers['User-Agent'].should == 'curl/7.18.0'
@parser.headers['Host'].should == '0.0.0.0:5000'
@body.should == "World"
end
it "should raise errors on invalid data" do
proc{ @parser << "BLAH" }.should raise_error(HTTP::Parser::Error)
end
it "should abort parser via callback" do
@parser.on_headers_complete = proc { |e| @headers = e; :stop }
data =
"GET / HTTP/1.0\r\n" +
"Content-Length: 5\r\n" +
"\r\n" +
"World"
bytes = @parser << data
bytes.should == 37
data[bytes..-1].should == 'World'
@headers.should == {'Content-Length' => '5'}
@body.should be_empty
@done.should be_false
end
it "should reset to initial state" do
@parser << "GET / HTTP/1.0\r\n\r\n"
@parser.http_method.should == 'GET'
@parser.http_version.should == [1,0]
@parser.request_url.should == '/'
@parser.reset!.should be_true
@parser.http_version.should be_nil
@parser.http_method.should be_nil
@parser.status_code.should be_nil
@parser.request_url.should be_nil
end
it "should optionally reset parser state on no-body responses" do
@parser.reset!.should be_true
@head, @complete = 0, 0
@parser.on_headers_complete = proc {|h| @head += 1; :reset }
@parser.on_message_complete = proc { @complete += 1 }
@parser.on_body = proc {|b| fail }
head_response = "HTTP/1.1 200 OK\r\nContent-Length:10\r\n\r\n"
@parser << head_response
@head.should == 1
@complete.should == 1
@parser << head_response
@head.should == 2
@complete.should == 2
end
it "should retain callbacks after reset" do
@parser.reset!.should be_true
@parser << "GET / HTTP/1.0\r\n\r\n"
@started.should be_true
@headers.should == {}
@done.should be_true
end
it "should parse headers incrementally" do
request =
"GET / HTTP/1.0\r\n" +
"Header1: value 1\r\n" +
"Header2: value 2\r\n" +
"\r\n"
while chunk = request.slice!(0,2) and !chunk.empty?
@parser << chunk
end
@parser.headers.should == {
'Header1' => 'value 1',
'Header2' => 'value 2'
}
end
it "should handle multiple headers using strings" do
@parser.header_value_type = :strings
@parser <<
"GET / HTTP/1.0\r\n" +
"Set-Cookie: PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com\r\n" +
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
"\r\n"
@parser.headers["Set-Cookie"].should == "PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com, NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
end
it "should handle multiple headers using strings" do
@parser.header_value_type = :arrays
@parser <<
"GET / HTTP/1.0\r\n" +
"Set-Cookie: PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com\r\n" +
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
"\r\n"
@parser.headers["Set-Cookie"].should == [
"PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com",
"NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
]
end
it "should handle multiple headers using mixed" do
@parser.header_value_type = :mixed
@parser <<
"GET / HTTP/1.0\r\n" +
"Set-Cookie: PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com\r\n" +
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
"\r\n"
@parser.headers["Set-Cookie"].should == [
"PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com",
"NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
]
end
it "should handle a single cookie using mixed" do
@parser.header_value_type = :mixed
@parser <<
"GET / HTTP/1.0\r\n" +
"Set-Cookie: PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com\r\n" +
"\r\n"
@parser.headers["Set-Cookie"].should == "PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com"
end
it "should support alternative api" do
callbacks = double('callbacks')
callbacks.stub(:on_message_begin){ @started = true }
callbacks.stub(:on_headers_complete){ |e| @headers = e }
callbacks.stub(:on_body){ |chunk| @body << chunk }
callbacks.stub(:on_message_complete){ @done = true }
@parser = HTTP::Parser.new(callbacks)
@parser << "GET / HTTP/1.0\r\n\r\n"
@started.should be_true
@headers.should == {}
@body.should == ''
@done.should be_true
end
it "should ignore extra content beyond specified length" do
@parser <<
"GET / HTTP/1.0\r\n" +
"Content-Length: 5\r\n" +
"\r\n" +
"hello" +
" \n"
@body.should == 'hello'
@done.should be_true
end
it 'sets upgrade_data if available' do
@parser <<
"GET /demo HTTP/1.1\r\n" +
"Connection: Upgrade\r\n" +
"Upgrade: WebSocket\r\n\r\n" +
"third key data"
@parser.upgrade?.should be_true
@parser.upgrade_data.should == 'third key data'
end
it 'sets upgrade_data to blank if un-available' do
@parser <<
"GET /demo HTTP/1.1\r\n" +
"Connection: Upgrade\r\n" +
"Upgrade: WebSocket\r\n\r\n"
@parser.upgrade?.should be_true
@parser.upgrade_data.should == ''
end
it 'should stop parsing headers when instructed' do
request = "GET /websocket HTTP/1.1\r\n" +
"host: localhost\r\n" +
"connection: Upgrade\r\n" +
"upgrade: websocket\r\n" +
"sec-websocket-key: SD6/hpYbKjQ6Sown7pBbWQ==\r\n" +
"sec-websocket-version: 13\r\n" +
"\r\n"
@parser.on_headers_complete = proc { |e| :stop }
offset = (@parser << request)
@parser.upgrade?.should be_true
@parser.upgrade_data.should == ''
offset.should == request.length
end
it "should execute on_body on requests with no content-length" do
@parser.reset!.should be_true
@head, @complete, @body = 0, 0, 0
@parser.on_headers_complete = proc {|h| @head += 1 }
@parser.on_message_complete = proc { @complete += 1 }
@parser.on_body = proc {|b| @body += 1 }
head_response = "HTTP/1.1 200 OK\r\n\r\nstuff"
@parser << head_response
@parser << ''
@head.should == 1
@complete.should == 1
@body.should == 1
end
%w[ request response ].each do |type|
JSON.parse(File.read(File.expand_path("../support/#{type}s.json", __FILE__))).each do |test|
test['headers'] ||= {}
next if !defined?(JRUBY_VERSION) and HTTP::Parser.strict? != test['strict']
it "should parse #{type}: #{test['name']}" do
@parser << test['raw']
@parser.http_method.should == test['method']
@parser.keep_alive?.should == test['should_keep_alive']
if test.has_key?('upgrade') and test['upgrade'] != 0
@parser.upgrade?.should be_true
@parser.upgrade_data.should == test['upgrade']
end
fields = %w[
http_major
http_minor
]
if test['type'] == 'HTTP_REQUEST'
fields += %w[
request_url
]
else
fields += %w[
status_code
]
end
fields.each do |field|
@parser.send(field).should == test[field]
end
@headers.size.should == test['num_headers']
@headers.should == test['headers']
@body.should == test['body']
@body.size.should == test['body_size'] if test['body_size']
end
end
end
end

View File

@@ -0,0 +1 @@
require "http_parser"

View File

@@ -0,0 +1,612 @@
[
{
"name": "curl get",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/test",
"request_url": "/test",
"num_headers": 3,
"headers": {
"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",
"Host": "0.0.0.0=5000",
"Accept": "*/*"
},
"body": "",
"strict": true
},
{
"name": "firefox get",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/favicon.ico",
"request_url": "/favicon.ico",
"num_headers": 8,
"headers": {
"Host": "0.0.0.0=5000",
"User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-us,en;q=0.5",
"Accept-Encoding": "gzip,deflate",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
"Keep-Alive": "300",
"Connection": "keep-alive"
},
"body": "",
"strict": true
},
{
"name": "dumbfuck",
"type": "HTTP_REQUEST",
"raw": "GET /dumbfuck HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/dumbfuck",
"request_url": "/dumbfuck",
"num_headers": 1,
"headers": {
"aaaaaaaaaaaaa": "++++++++++"
},
"body": "",
"strict": true
},
{
"name": "fragment in url",
"type": "HTTP_REQUEST",
"raw": "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "page=1",
"fragment": "posts-17408",
"request_path": "/forums/1/topics/2375",
"request_url": "/forums/1/topics/2375?page=1#posts-17408",
"num_headers": 0,
"body": "",
"strict": true
},
{
"name": "get no headers no body",
"type": "HTTP_REQUEST",
"raw": "GET /get_no_headers_no_body/world HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/get_no_headers_no_body/world",
"request_url": "/get_no_headers_no_body/world",
"num_headers": 0,
"body": "",
"strict": true
},
{
"name": "get one header no body",
"type": "HTTP_REQUEST",
"raw": "GET /get_one_header_no_body HTTP/1.1\r\nAccept: */*\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/get_one_header_no_body",
"request_url": "/get_one_header_no_body",
"num_headers": 1,
"headers": {
"Accept": "*/*"
},
"body": "",
"strict": true
},
{
"name": "get funky content length body hello",
"type": "HTTP_REQUEST",
"raw": "GET /get_funky_content_length_body_hello HTTP/1.0\r\nconTENT-Length: 5\r\n\r\nHELLO",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/get_funky_content_length_body_hello",
"request_url": "/get_funky_content_length_body_hello",
"num_headers": 1,
"headers": {
"conTENT-Length": "5"
},
"body": "HELLO",
"strict": true
},
{
"name": "post identity body world",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "POST",
"query_string": "q=search",
"fragment": "hey",
"request_path": "/post_identity_body_world",
"request_url": "/post_identity_body_world?q=search#hey",
"num_headers": 3,
"headers": {
"Accept": "*/*",
"Transfer-Encoding": "identity",
"Content-Length": "5"
},
"body": "World",
"strict": true
},
{
"name": "post - chunked body: all your base are belong to us",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "POST",
"query_string": "",
"fragment": "",
"request_path": "/post_chunked_all_your_base",
"request_url": "/post_chunked_all_your_base",
"num_headers": 1,
"headers": {
"Transfer-Encoding": "chunked"
},
"body": "all your base are belong to us",
"strict": true
},
{
"name": "two chunks ; triple zero ending",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "POST",
"query_string": "",
"fragment": "",
"request_path": "/two_chunks_mult_zero_end",
"request_url": "/two_chunks_mult_zero_end",
"num_headers": 1,
"headers": {
"Transfer-Encoding": "chunked"
},
"body": "hello world",
"strict": true
},
{
"name": "chunked with trailing headers. blech.",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "POST",
"query_string": "",
"fragment": "",
"request_path": "/chunked_w_trailing_headers",
"request_url": "/chunked_w_trailing_headers",
"num_headers": 3,
"headers": {
"Transfer-Encoding": "chunked",
"Vary": "*",
"Content-Type": "text/plain"
},
"body": "hello world",
"strict": true
},
{
"name": "with bullshit after the length",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "POST",
"query_string": "",
"fragment": "",
"request_path": "/chunked_w_bullshit_after_length",
"request_url": "/chunked_w_bullshit_after_length",
"num_headers": 1,
"headers": {
"Transfer-Encoding": "chunked"
},
"body": "hello world",
"strict": true
},
{
"name": "with quotes",
"type": "HTTP_REQUEST",
"raw": "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "foo=\"bar\"",
"fragment": "",
"request_path": "/with_\"stupid\"_quotes",
"request_url": "/with_\"stupid\"_quotes?foo=\"bar\"",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "apachebench get",
"type": "HTTP_REQUEST",
"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",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/test",
"request_url": "/test",
"num_headers": 3,
"headers": {
"Host": "0.0.0.0:5000",
"User-Agent": "ApacheBench/2.3",
"Accept": "*/*"
},
"body": "",
"strict": true
},
{
"name": "query url with question mark",
"type": "HTTP_REQUEST",
"raw": "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "foo=bar?baz",
"fragment": "",
"request_path": "/test.cgi",
"request_url": "/test.cgi?foo=bar?baz",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "newline prefix get",
"type": "HTTP_REQUEST",
"raw": "\r\nGET /test HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/test",
"request_url": "/test",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "upgrade request",
"type": "HTTP_REQUEST",
"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\nHot diggity dogg",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/demo",
"request_url": "/demo",
"num_headers": 7,
"upgrade": "Hot diggity dogg",
"headers": {
"Host": "example.com",
"Connection": "Upgrade",
"Sec-WebSocket-Key2": "12998 5 Y3 1 .P00",
"Sec-WebSocket-Protocol": "sample",
"Upgrade": "WebSocket",
"Sec-WebSocket-Key1": "4 @1 46546xW%0l 1 5",
"Origin": "http://example.com"
},
"body": "",
"strict": true
},
{
"name": "connect request",
"type": "HTTP_REQUEST",
"raw": "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\nsome data\r\nand yet even more data",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"method": "CONNECT",
"query_string": "",
"fragment": "",
"request_path": "",
"request_url": "0-home0.netscape.com:443",
"num_headers": 2,
"upgrade": "some data\r\nand yet even more data",
"headers": {
"User-agent": "Mozilla/1.1N",
"Proxy-authorization": "basic aGVsbG86d29ybGQ="
},
"body": "",
"strict": true
},
{
"name": "report request",
"type": "HTTP_REQUEST",
"raw": "REPORT /test HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "REPORT",
"query_string": "",
"fragment": "",
"request_path": "/test",
"request_url": "/test",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "request with no http version",
"type": "HTTP_REQUEST",
"raw": "GET /\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 0,
"http_minor": 9,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/",
"request_url": "/",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "m-search request",
"type": "HTTP_REQUEST",
"raw": "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nST: \"ssdp:all\"\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "M-SEARCH",
"query_string": "",
"fragment": "",
"request_path": "*",
"request_url": "*",
"num_headers": 3,
"headers": {
"HOST": "239.255.255.250:1900",
"MAN": "\"ssdp:discover\"",
"ST": "\"ssdp:all\""
},
"body": "",
"strict": true
},
{
"name": "line folding in header value",
"type": "HTTP_REQUEST",
"raw": "GET / HTTP/1.1\r\nLine1: abc\r\n\tdef\r\n ghi\r\n\t\tjkl\r\n mno \r\n\t \tqrs\r\nLine2: \t line2\t\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "/",
"request_url": "/",
"num_headers": 2,
"headers": {
"Line1": "abcdefghijklmno qrs",
"Line2": "line2\t"
},
"body": "",
"strict": true
},
{
"name": "host terminated by a query string",
"type": "HTTP_REQUEST",
"raw": "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "hail=all",
"fragment": "",
"request_path": "",
"request_url": "http://hypnotoad.org?hail=all",
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "host:port terminated by a query string",
"type": "HTTP_REQUEST",
"raw": "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "hail=all",
"fragment": "",
"request_path": "",
"request_url": "http://hypnotoad.org:1234?hail=all",
"port": 1234,
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "host:port terminated by a space",
"type": "HTTP_REQUEST",
"raw": "GET http://hypnotoad.org:1234 HTTP/1.1\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "",
"fragment": "",
"request_path": "",
"request_url": "http://hypnotoad.org:1234",
"port": 1234,
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "PATCH request",
"type": "HTTP_REQUEST",
"raw": "PATCH /file.txt HTTP/1.1\r\nHost: www.example.com\r\nContent-Type: application/example\r\nIf-Match: \"e0023aa4e\"\r\nContent-Length: 10\r\n\r\ncccccccccc",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "PATCH",
"query_string": "",
"fragment": "",
"request_path": "/file.txt",
"request_url": "/file.txt",
"num_headers": 4,
"headers": {
"Host": "www.example.com",
"Content-Type": "application/example",
"If-Match": "\"e0023aa4e\"",
"Content-Length": "10"
},
"body": "cccccccccc",
"strict": true
},
{
"name": "connect caps request",
"type": "HTTP_REQUEST",
"raw": "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"method": "CONNECT",
"query_string": "",
"fragment": "",
"request_path": "",
"request_url": "HOME0.NETSCAPE.COM:443",
"num_headers": 2,
"upgrade": "",
"headers": {
"User-agent": "Mozilla/1.1N",
"Proxy-authorization": "basic aGVsbG86d29ybGQ="
},
"body": "",
"strict": true
},
{
"name": "utf-8 path request",
"type": "HTTP_REQUEST",
"strict": false,
"raw": "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\nHost: github.com\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"method": "GET",
"query_string": "q=1",
"fragment": "narf",
"request_path": "/δ¶/δt/pope",
"request_url": "/δ¶/δt/pope?q=1#narf",
"num_headers": 1,
"headers": {
"Host": "github.com"
},
"body": ""
},
{
"name": "hostname underscore",
"type": "HTTP_REQUEST",
"strict": false,
"raw": "CONNECT home_0.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"method": "CONNECT",
"query_string": "",
"fragment": "",
"request_path": "",
"request_url": "home_0.netscape.com:443",
"num_headers": 2,
"upgrade": "",
"headers": {
"User-agent": "Mozilla/1.1N",
"Proxy-authorization": "basic aGVsbG86d29ybGQ="
},
"body": ""
}
]

View File

@@ -0,0 +1,375 @@
[
{
"name": "google 301",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 26 Apr 2009 11:11:49 GMT\r\nExpires: Tue, 26 May 2009 11:11:49 GMT\r\nX-$PrototypeBI-Version: 1.6.0.3\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219 \r\n\r\n<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 301,
"num_headers": 8,
"headers": {
"Location": "http://www.google.com/",
"Content-Type": "text/html; charset=UTF-8",
"Date": "Sun, 26 Apr 2009 11:11:49 GMT",
"Expires": "Tue, 26 May 2009 11:11:49 GMT",
"X-$PrototypeBI-Version": "1.6.0.3",
"Cache-Control": "public, max-age=2592000",
"Server": "gws",
"Content-Length": "219 "
},
"body": "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n",
"strict": true
},
{
"name": "no content-length response",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nDate: Tue, 04 Aug 2009 07:59:32 GMT\r\nServer: Apache\r\nX-Powered-By: Servlet/2.5 JSP/2.1\r\nContent-Type: text/xml; charset=utf-8\r\nConnection: close\r\n\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <SOAP-ENV:Body>\n <SOAP-ENV:Fault>\n <faultcode>SOAP-ENV:Client</faultcode>\n <faultstring>Client Error</faultstring>\n </SOAP-ENV:Fault>\n </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 5,
"headers": {
"Date": "Tue, 04 Aug 2009 07:59:32 GMT",
"Server": "Apache",
"X-Powered-By": "Servlet/2.5 JSP/2.1",
"Content-Type": "text/xml; charset=utf-8",
"Connection": "close"
},
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <SOAP-ENV:Body>\n <SOAP-ENV:Fault>\n <faultcode>SOAP-ENV:Client</faultcode>\n <faultstring>Client Error</faultstring>\n </SOAP-ENV:Fault>\n </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>",
"strict": true
},
{
"name": "404 no headers no body",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 404 Not Found\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 404,
"num_headers": 0,
"headers": {
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "301 no response phrase",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 301\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 301,
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "200 trailing space on chunked body",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n25 \r\nThis is the data in the first chunk\r\n\r\n1C\r\nand this is the second one\r\n\r\n0 \r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 2,
"headers": {
"Content-Type": "text/plain",
"Transfer-Encoding": "chunked"
},
"body_size": 65,
"body": "This is the data in the first chunk\r\nand this is the second one\r\n",
"strict": true
},
{
"name": "no carriage ret",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nConnection: close\n\nthese headers are from http://news.ycombinator.com/",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 2,
"headers": {
"Content-Type": "text/html; charset=utf-8",
"Connection": "close"
},
"body": "these headers are from http://news.ycombinator.com/",
"strict": true
},
{
"name": "proxy connection",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 11\r\nProxy-Connection: close\r\nDate: Thu, 31 Dec 2009 20:55:48 +0000\r\n\r\nhello world",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 4,
"headers": {
"Content-Type": "text/html; charset=UTF-8",
"Content-Length": "11",
"Proxy-Connection": "close",
"Date": "Thu, 31 Dec 2009 20:55:48 +0000"
},
"body": "hello world",
"strict": true
},
{
"name": "underscore header key",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nServer: DCLK-AdSvr\r\nContent-Type: text/xml\r\nContent-Length: 0\r\nDCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 4,
"headers": {
"Server": "DCLK-AdSvr",
"Content-Type": "text/xml",
"Content-Length": "0",
"DCLK_imp": "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o"
},
"body": "",
"strict": true
},
{
"name": "bonjourmadame.fr",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.0 301 Moved Permanently\r\nDate: Thu, 03 Jun 2010 09:56:32 GMT\r\nServer: Apache/2.2.3 (Red Hat)\r\nCache-Control: public\r\nPragma: \r\nLocation: http://www.bonjourmadame.fr/\r\nVary: Accept-Encoding\r\nContent-Length: 0\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: keep-alive\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"status_code": 301,
"num_headers": 9,
"headers": {
"Date": "Thu, 03 Jun 2010 09:56:32 GMT",
"Server": "Apache/2.2.3 (Red Hat)",
"Cache-Control": "public",
"Pragma": "",
"Location": "http://www.bonjourmadame.fr/",
"Vary": "Accept-Encoding",
"Content-Length": "0",
"Content-Type": "text/html; charset=UTF-8",
"Connection": "keep-alive"
},
"body": "",
"strict": true
},
{
"name": "field underscore",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nDate: Tue, 28 Sep 2010 01:14:13 GMT\r\nServer: Apache\r\nCache-Control: no-cache, must-revalidate\r\nExpires: Mon, 26 Jul 1997 05:00:00 GMT\r\n.et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\nVary: Accept-Encoding\r\n_eep-Alive: timeout=45\r\n_onnection: Keep-Alive\r\nTransfer-Encoding: chunked\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n0\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 11,
"headers": {
"Date": "Tue, 28 Sep 2010 01:14:13 GMT",
"Server": "Apache",
"Cache-Control": "no-cache, must-revalidate",
"Expires": "Mon, 26 Jul 1997 05:00:00 GMT",
".et-Cookie": "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com",
"Vary": "Accept-Encoding",
"_eep-Alive": "timeout=45",
"_onnection": "Keep-Alive",
"Transfer-Encoding": "chunked",
"Content-Type": "text/html",
"Connection": "close"
},
"body": "",
"strict": true
},
{
"name": "non-ASCII in status line",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 500 Oriëntatieprobleem\r\nDate: Fri, 5 Nov 2010 23:07:12 GMT+2\r\nContent-Length: 0\r\nConnection: close\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 500,
"num_headers": 3,
"headers": {
"Date": "Fri, 5 Nov 2010 23:07:12 GMT+2",
"Content-Length": "0",
"Connection": "close"
},
"body": "",
"strict": true
},
{
"name": "http version 0.9",
"type": "HTTP_RESPONSE",
"raw": "HTTP/0.9 200 OK\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 0,
"http_minor": 9,
"status_code": 200,
"num_headers": 0,
"headers": {
},
"body": "",
"strict": true
},
{
"name": "neither content-length nor transfer-encoding response",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nhello world",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 1,
"headers": {
"Content-Type": "text/plain"
},
"body": "hello world",
"strict": true
},
{
"name": "HTTP/1.0 with keep-alive and EOF-terminated 200 status",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.0 200 OK\r\nConnection: keep-alive\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 0,
"status_code": 200,
"num_headers": 1,
"headers": {
"Connection": "keep-alive"
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "HTTP/1.0 with keep-alive and a 204 status",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.0 204 No content\r\nConnection: keep-alive\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 0,
"status_code": 204,
"num_headers": 1,
"headers": {
"Connection": "keep-alive"
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "HTTP/1.1 with an EOF-terminated 200 status",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": true,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 0,
"headers": {
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "HTTP/1.1 with a 204 status",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 204 No content\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 204,
"num_headers": 0,
"headers": {
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "HTTP/1.1 with a 204 status and keep-alive disabled",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 204 No content\r\nConnection: close\r\n\r\n",
"should_keep_alive": false,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 204,
"num_headers": 1,
"headers": {
"Connection": "close"
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "HTTP/1.1 with chunked endocing and a 200 response",
"type": "HTTP_RESPONSE",
"raw": "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 1,
"headers": {
"Transfer-Encoding": "chunked"
},
"body_size": 0,
"body": "",
"strict": true
},
{
"name": "field space",
"type": "HTTP_RESPONSE",
"strict": false,
"raw": "HTTP/1.1 200 OK\r\nServer: Microsoft-IIS/6.0\r\nX-Powered-By: ASP.NET\r\nen-US Content-Type: text/xml\r\nContent-Type: text/xml\r\nContent-Length: 16\r\nDate: Fri, 23 Jul 2010 18:45:38 GMT\r\nConnection: keep-alive\r\n\r\n<xml>hello</xml>",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
"http_minor": 1,
"status_code": 200,
"num_headers": 7,
"headers": {
"Server": "Microsoft-IIS/6.0",
"X-Powered-By": "ASP.NET",
"en-US Content-Type": "text/xml",
"Content-Type": "text/xml",
"Content-Length": "16",
"Date": "Fri, 23 Jul 2010 18:45:38 GMT",
"Connection": "keep-alive"
},
"body": "<xml>hello</xml>"
}
]