websocket 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/Gemfile +1 -0
- data/README.md +1 -0
- data/lib/websocket.rb +15 -4
- data/lib/websocket/error.rb +85 -0
- data/lib/websocket/exception_handler.rb +36 -0
- data/lib/websocket/frame/base.rb +13 -16
- data/lib/websocket/frame/data.rb +1 -1
- data/lib/websocket/frame/handler/base.rb +6 -2
- data/lib/websocket/frame/handler/handler03.rb +49 -55
- data/lib/websocket/frame/handler/handler04.rb +1 -3
- data/lib/websocket/frame/handler/handler05.rb +2 -6
- data/lib/websocket/frame/handler/handler07.rb +5 -7
- data/lib/websocket/frame/handler/handler75.rb +15 -19
- data/lib/websocket/frame/incoming.rb +2 -1
- data/lib/websocket/frame/incoming/client.rb +1 -3
- data/lib/websocket/frame/incoming/server.rb +1 -3
- data/lib/websocket/frame/outgoing.rb +3 -2
- data/lib/websocket/frame/outgoing/client.rb +1 -3
- data/lib/websocket/frame/outgoing/server.rb +1 -3
- data/lib/websocket/handshake/base.rb +9 -5
- data/lib/websocket/handshake/client.rb +13 -12
- data/lib/websocket/handshake/handler/base.rb +10 -2
- data/lib/websocket/handshake/handler/client.rb +3 -5
- data/lib/websocket/handshake/handler/client01.rb +2 -4
- data/lib/websocket/handshake/handler/client04.rb +6 -8
- data/lib/websocket/handshake/handler/client75.rb +4 -6
- data/lib/websocket/handshake/handler/client76.rb +3 -5
- data/lib/websocket/handshake/handler/server.rb +1 -3
- data/lib/websocket/handshake/handler/server04.rb +7 -5
- data/lib/websocket/handshake/handler/server75.rb +3 -5
- data/lib/websocket/handshake/handler/server76.rb +9 -11
- data/lib/websocket/handshake/server.rb +49 -10
- data/lib/websocket/version.rb +1 -1
- data/spec/frame/incoming_03_spec.rb +3 -3
- data/spec/frame/incoming_04_spec.rb +3 -3
- data/spec/frame/incoming_05_spec.rb +3 -3
- data/spec/frame/incoming_07_spec.rb +3 -3
- data/spec/frame/incoming_75_spec.rb +2 -2
- data/spec/handshake/client_04_spec.rb +3 -3
- data/spec/handshake/client_76_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- data/spec/support/all_server_drafts.rb +33 -0
- data/spec/support/frames_base.rb +1 -3
- data/spec/support/incoming_frames.rb +26 -1
- data/spec/support/overwrites.rb +9 -0
- data/websocket.gemspec +0 -2
- metadata +29 -53
@@ -1,9 +1,7 @@
|
|
1
1
|
module WebSocket
|
2
2
|
module Handshake
|
3
3
|
module Handler
|
4
|
-
|
5
|
-
|
6
|
-
include Client
|
4
|
+
class Client75 < Client
|
7
5
|
|
8
6
|
private
|
9
7
|
|
@@ -13,10 +11,10 @@ module WebSocket
|
|
13
11
|
["Upgrade", "WebSocket"],
|
14
12
|
["Connection", "Upgrade"]
|
15
13
|
]
|
16
|
-
host = @host
|
17
|
-
host += ":#{@port}" if @port
|
14
|
+
host = @handshake.host
|
15
|
+
host += ":#{@handshake.port}" if @handshake.port
|
18
16
|
keys << ["Host", host]
|
19
|
-
keys << ["Origin", @origin] if @origin
|
17
|
+
keys << ["Origin", @handshake.origin] if @handshake.origin
|
20
18
|
keys
|
21
19
|
end
|
22
20
|
|
@@ -3,9 +3,7 @@ require 'digest/md5'
|
|
3
3
|
module WebSocket
|
4
4
|
module Handshake
|
5
5
|
module Handler
|
6
|
-
|
7
|
-
|
8
|
-
include Client75
|
6
|
+
class Client76 < Client75
|
9
7
|
|
10
8
|
# @see WebSocket::Handshake::Base#valid?
|
11
9
|
def valid?
|
@@ -65,7 +63,7 @@ module WebSocket
|
|
65
63
|
# Verify if challenge sent by server match generated one
|
66
64
|
# @return [Boolena] True if challenge matches, false otherwise(sets appropriate error)
|
67
65
|
def verify_challenge
|
68
|
-
|
66
|
+
raise WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.instance_variable_get('@leftovers') == challenge
|
69
67
|
true
|
70
68
|
end
|
71
69
|
|
@@ -94,7 +92,7 @@ module WebSocket
|
|
94
92
|
|
95
93
|
# Generate third key
|
96
94
|
def generate_key3
|
97
|
-
|
95
|
+
[rand(0x100000000)].pack("N") + [rand(0x100000000)].pack("N")
|
98
96
|
end
|
99
97
|
|
100
98
|
end
|
@@ -4,13 +4,11 @@ require 'base64'
|
|
4
4
|
module WebSocket
|
5
5
|
module Handshake
|
6
6
|
module Handler
|
7
|
-
|
8
|
-
|
9
|
-
include Server
|
7
|
+
class Server04 < Server
|
10
8
|
|
11
9
|
# @see WebSocket::Handshake::Base#valid?
|
12
10
|
def valid?
|
13
|
-
super &&
|
11
|
+
super && verify_key
|
14
12
|
end
|
15
13
|
|
16
14
|
private
|
@@ -32,11 +30,15 @@ module WebSocket
|
|
32
30
|
# Signature of response, created from client request Sec-WebSocket-Key
|
33
31
|
# @return [String] signature
|
34
32
|
def signature
|
35
|
-
return unless key = @headers['sec-websocket-key']
|
33
|
+
return unless key = @handshake.headers['sec-websocket-key']
|
36
34
|
string_to_sign = "#{key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
37
35
|
Base64.encode64(Digest::SHA1.digest(string_to_sign)).chomp
|
38
36
|
end
|
39
37
|
|
38
|
+
def verify_key
|
39
|
+
(@handshake.headers['sec-websocket-key'] ? true : raise(WebSocket::Error::Handshake::InvalidAuthentication))
|
40
|
+
end
|
41
|
+
|
40
42
|
end
|
41
43
|
end
|
42
44
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module WebSocket
|
2
2
|
module Handshake
|
3
3
|
module Handler
|
4
|
-
|
5
|
-
|
6
|
-
include Server
|
4
|
+
class Server75 < Server
|
7
5
|
|
8
6
|
private
|
9
7
|
|
@@ -17,8 +15,8 @@ module WebSocket
|
|
17
15
|
[
|
18
16
|
["Upgrade", "WebSocket"],
|
19
17
|
["Connection", "Upgrade"],
|
20
|
-
["WebSocket-Origin", @headers['origin']],
|
21
|
-
["WebSocket-Location", uri]
|
18
|
+
["WebSocket-Origin", @handshake.headers['origin']],
|
19
|
+
["WebSocket-Location", @handshake.uri]
|
22
20
|
]
|
23
21
|
end
|
24
22
|
|
@@ -3,9 +3,7 @@ require 'digest/md5'
|
|
3
3
|
module WebSocket
|
4
4
|
module Handshake
|
5
5
|
module Handler
|
6
|
-
|
7
|
-
|
8
|
-
include Server
|
6
|
+
class Server76 < Server
|
9
7
|
|
10
8
|
# @see WebSocket::Handshake::Base#valid?
|
11
9
|
def valid?
|
@@ -29,8 +27,8 @@ module WebSocket
|
|
29
27
|
[
|
30
28
|
["Upgrade", "WebSocket"],
|
31
29
|
["Connection", "Upgrade"],
|
32
|
-
["Sec-WebSocket-Origin", @headers['origin']],
|
33
|
-
["Sec-WebSocket-Location", uri]
|
30
|
+
["Sec-WebSocket-Origin", @handshake.headers['origin']],
|
31
|
+
["Sec-WebSocket-Location", @handshake.uri]
|
34
32
|
]
|
35
33
|
end
|
36
34
|
|
@@ -45,9 +43,9 @@ module WebSocket
|
|
45
43
|
# @return [String] Challenge response or nil if error occured
|
46
44
|
def challenge_response
|
47
45
|
# Refer to 5.2 4-9 of the draft 76
|
48
|
-
first = numbers_over_spaces(@headers['sec-websocket-key1'])
|
49
|
-
second = numbers_over_spaces(@headers['sec-websocket-key2'])
|
50
|
-
third = @leftovers.strip
|
46
|
+
first = numbers_over_spaces(@handshake.headers['sec-websocket-key1'].to_s)
|
47
|
+
second = numbers_over_spaces(@handshake.headers['sec-websocket-key2'].to_s)
|
48
|
+
third = @handshake.instance_variable_get('@leftovers').strip
|
51
49
|
|
52
50
|
sum = [first].pack("N*") +
|
53
51
|
[second].pack("N*") +
|
@@ -63,14 +61,14 @@ module WebSocket
|
|
63
61
|
|
64
62
|
spaces = string.scan(/ /).size
|
65
63
|
# As per 5.2.5, abort the connection if spaces are zero.
|
66
|
-
|
64
|
+
raise WebSocket::Error::Handshake::InvalidAuthentication if spaces == 0
|
67
65
|
|
68
66
|
# As per 5.2.6, abort if numbers is not an integral multiple of spaces
|
69
|
-
|
67
|
+
raise WebSocket::Error::Handshake::InvalidAuthentication if numbers % spaces != 0
|
70
68
|
|
71
69
|
quotient = numbers / spaces
|
72
70
|
|
73
|
-
|
71
|
+
raise WebSocket::Error::Handshake::InvalidAuthentication if quotient > 2**32-1
|
74
72
|
|
75
73
|
return quotient
|
76
74
|
end
|
@@ -65,6 +65,48 @@ module WebSocket
|
|
65
65
|
set_version
|
66
66
|
end
|
67
67
|
end
|
68
|
+
rescue_method :<<
|
69
|
+
|
70
|
+
# Parse the request from a rack environment
|
71
|
+
# @param env Rack Environment
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# @handshake.from_rack(env)
|
75
|
+
def from_rack(env)
|
76
|
+
@headers = env.select {|key, value|
|
77
|
+
key =~ /\AHTTP_/
|
78
|
+
}.inject({}) {|memo, tuple|
|
79
|
+
key, value = tuple
|
80
|
+
memo[key.gsub(/\AHTTP_/, '').gsub('_', '-').downcase] = value
|
81
|
+
memo
|
82
|
+
}
|
83
|
+
|
84
|
+
@path = env["REQUEST_PATH"]
|
85
|
+
@query = env["QUERY_STRING"]
|
86
|
+
@leftovers = env['rack.input'].read
|
87
|
+
|
88
|
+
set_version
|
89
|
+
@state = :finished
|
90
|
+
end
|
91
|
+
|
92
|
+
# Parse the request from hash
|
93
|
+
# @param hash Hash to import data
|
94
|
+
# @option hash [Hash] :headers HTTP headers of request, downcased
|
95
|
+
# @option hash [String] :path Path for request(without host and query string)
|
96
|
+
# @option hash [String] :query Query string for request
|
97
|
+
# @option hash [String] :body Body of request(if exists)
|
98
|
+
#
|
99
|
+
# @example
|
100
|
+
# @handshake.from_hash(hash)
|
101
|
+
def from_hash(hash)
|
102
|
+
@headers = hash[:headers] || {}
|
103
|
+
@path = hash[:path] || "/"
|
104
|
+
@query = hash[:query] || ""
|
105
|
+
@leftovers = hash[:body]
|
106
|
+
|
107
|
+
set_version
|
108
|
+
@state = :finished
|
109
|
+
end
|
68
110
|
|
69
111
|
# Should send content to client after finished parsing?
|
70
112
|
# @return [Boolean] true
|
@@ -98,13 +140,12 @@ module WebSocket
|
|
98
140
|
# Include set of methods for selected protocol version
|
99
141
|
# @return [Boolean] false if protocol number is unknown, otherwise true
|
100
142
|
def include_version
|
101
|
-
case @version
|
102
|
-
when 75 then
|
103
|
-
when 76, 0..3 then
|
104
|
-
when 4..13 then
|
105
|
-
else
|
143
|
+
@handler = case @version
|
144
|
+
when 75 then Handler::Server75.new(self)
|
145
|
+
when 76, 0..3 then Handler::Server76.new(self)
|
146
|
+
when 4..13 then Handler::Server04.new(self)
|
147
|
+
else raise WebSocket::Error::Handshake::UnknownVersion
|
106
148
|
end
|
107
|
-
return true
|
108
149
|
end
|
109
150
|
|
110
151
|
PATH = /^(\w+) (\/[^\s]*) HTTP\/1\.1$/
|
@@ -114,14 +155,12 @@ module WebSocket
|
|
114
155
|
# @return [Boolean] True if parsed correctly. False otherwise
|
115
156
|
def parse_first_line(line)
|
116
157
|
line_parts = line.match(PATH)
|
117
|
-
|
158
|
+
raise WebSocket::Error::Handshake::InvalidHeader unless line_parts
|
118
159
|
method = line_parts[1].strip
|
119
|
-
|
160
|
+
raise WebSocket::Error::Handshake::GetRequestRequired unless method == "GET"
|
120
161
|
|
121
162
|
resource_name = line_parts[2].strip
|
122
163
|
@path, @query = resource_name.split('?', 2)
|
123
|
-
|
124
|
-
return true
|
125
164
|
end
|
126
165
|
|
127
166
|
end
|
data/lib/websocket/version.rb
CHANGED
@@ -94,7 +94,7 @@ describe 'Incoming frame draft 03' do
|
|
94
94
|
context "should raise error with invalid opcode" do
|
95
95
|
let(:encoded_text) { "\x09\x05Hello" }
|
96
96
|
let(:decoded_text) { nil }
|
97
|
-
let(:error) {
|
97
|
+
let(:error) { WebSocket::Error::Frame::UnknownOpcode }
|
98
98
|
|
99
99
|
it_should_behave_like 'valid_incoming_frame'
|
100
100
|
end
|
@@ -102,7 +102,7 @@ describe 'Incoming frame draft 03' do
|
|
102
102
|
context "should raise error with too long frame" do
|
103
103
|
let(:encoded_text) { "\x04\x7F" + "a" * WebSocket.max_frame_size }
|
104
104
|
let(:decoded_text) { nil }
|
105
|
-
let(:error) {
|
105
|
+
let(:error) { WebSocket::Error::Frame::TooLong }
|
106
106
|
|
107
107
|
it_should_behave_like 'valid_incoming_frame'
|
108
108
|
end
|
@@ -110,7 +110,7 @@ describe 'Incoming frame draft 03' do
|
|
110
110
|
context "should raise error with continuation frame without more frame earlier" do
|
111
111
|
let(:encoded_text) { "\x00\x05Hello" }
|
112
112
|
let(:decoded_text) { nil }
|
113
|
-
let(:error) {
|
113
|
+
let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
|
114
114
|
|
115
115
|
it_should_behave_like 'valid_incoming_frame'
|
116
116
|
end
|
@@ -94,7 +94,7 @@ describe 'Incoming frame draft 04' do
|
|
94
94
|
context "should raise error with invalid opcode" do
|
95
95
|
let(:encoded_text) { "\x89\x05Hello" }
|
96
96
|
let(:decoded_text) { nil }
|
97
|
-
let(:error) {
|
97
|
+
let(:error) { WebSocket::Error::Frame::UnknownOpcode }
|
98
98
|
|
99
99
|
it_should_behave_like 'valid_incoming_frame'
|
100
100
|
end
|
@@ -102,7 +102,7 @@ describe 'Incoming frame draft 04' do
|
|
102
102
|
context "should raise error with too long frame" do
|
103
103
|
let(:encoded_text) { "\x84\x7F" + "a" * WebSocket.max_frame_size }
|
104
104
|
let(:decoded_text) { nil }
|
105
|
-
let(:error) {
|
105
|
+
let(:error) { WebSocket::Error::Frame::TooLong }
|
106
106
|
|
107
107
|
it_should_behave_like 'valid_incoming_frame'
|
108
108
|
end
|
@@ -110,7 +110,7 @@ describe 'Incoming frame draft 04' do
|
|
110
110
|
context "should raise error with continuation frame without more frame earlier" do
|
111
111
|
let(:encoded_text) { "\x80\x05Hello" }
|
112
112
|
let(:decoded_text) { nil }
|
113
|
-
let(:error) {
|
113
|
+
let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
|
114
114
|
|
115
115
|
it_should_behave_like 'valid_incoming_frame'
|
116
116
|
end
|
@@ -110,7 +110,7 @@ describe 'Incoming frame draft 05' do
|
|
110
110
|
context "should raise error with invalid opcode" do
|
111
111
|
let(:encoded_text) { "\x89\x05Hello" }
|
112
112
|
let(:decoded_text) { nil }
|
113
|
-
let(:error) {
|
113
|
+
let(:error) { WebSocket::Error::Frame::UnknownOpcode }
|
114
114
|
|
115
115
|
it_should_behave_like 'valid_incoming_frame'
|
116
116
|
end
|
@@ -118,7 +118,7 @@ describe 'Incoming frame draft 05' do
|
|
118
118
|
context "should raise error with too long frame" do
|
119
119
|
let(:encoded_text) { "\x84\x7F" + "a" * WebSocket.max_frame_size }
|
120
120
|
let(:decoded_text) { nil }
|
121
|
-
let(:error) {
|
121
|
+
let(:error) { WebSocket::Error::Frame::TooLong }
|
122
122
|
|
123
123
|
it_should_behave_like 'valid_incoming_frame'
|
124
124
|
end
|
@@ -126,7 +126,7 @@ describe 'Incoming frame draft 05' do
|
|
126
126
|
context "should raise error with continuation frame without more frame earlier" do
|
127
127
|
let(:encoded_text) { "\x80\x05Hello" }
|
128
128
|
let(:decoded_text) { nil }
|
129
|
-
let(:error) {
|
129
|
+
let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
|
130
130
|
|
131
131
|
it_should_behave_like 'valid_incoming_frame'
|
132
132
|
end
|
@@ -110,7 +110,7 @@ describe 'Incoming frame draft 07' do
|
|
110
110
|
context "should raise error with invalid opcode" do
|
111
111
|
let(:encoded_text) { "\x85\x05Hello" }
|
112
112
|
let(:decoded_text) { nil }
|
113
|
-
let(:error) {
|
113
|
+
let(:error) { WebSocket::Error::Frame::UnknownOpcode }
|
114
114
|
|
115
115
|
it_should_behave_like 'valid_incoming_frame'
|
116
116
|
end
|
@@ -118,7 +118,7 @@ describe 'Incoming frame draft 07' do
|
|
118
118
|
context "should raise error with too long frame" do
|
119
119
|
let(:encoded_text) { "\x81\x7F" + "a" * WebSocket.max_frame_size }
|
120
120
|
let(:decoded_text) { nil }
|
121
|
-
let(:error) {
|
121
|
+
let(:error) { WebSocket::Error::Frame::TooLong }
|
122
122
|
|
123
123
|
it_should_behave_like 'valid_incoming_frame'
|
124
124
|
end
|
@@ -126,7 +126,7 @@ describe 'Incoming frame draft 07' do
|
|
126
126
|
context "should raise error with continuation frame without more frame earlier" do
|
127
127
|
let(:encoded_text) { "\x80\x05Hello" }
|
128
128
|
let(:decoded_text) { nil }
|
129
|
-
let(:error) {
|
129
|
+
let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
|
130
130
|
|
131
131
|
it_should_behave_like 'valid_incoming_frame'
|
132
132
|
end
|
@@ -45,14 +45,14 @@ describe 'Incoming frame draft 75' do
|
|
45
45
|
|
46
46
|
context "with invalid frame" do
|
47
47
|
let(:encoded_text) { "invalid" }
|
48
|
-
let(:error) {
|
48
|
+
let(:error) { WebSocket::Error::Frame::Invalid }
|
49
49
|
|
50
50
|
it_should_behave_like 'valid_incoming_frame'
|
51
51
|
end
|
52
52
|
|
53
53
|
context "with too long frame" do
|
54
54
|
let(:encoded_text) { "\x00" + "a" * WebSocket.max_frame_size + "\xFF" }
|
55
|
-
let(:error) {
|
55
|
+
let(:error) { WebSocket::Error::Frame::TooLong }
|
56
56
|
|
57
57
|
it_should_behave_like 'valid_incoming_frame'
|
58
58
|
end
|
@@ -4,8 +4,8 @@ describe 'Client draft 4 handshake' do
|
|
4
4
|
let(:handshake) { WebSocket::Handshake::Client.new({ :uri => 'ws://example.com/demo', :origin => 'http://example.com', :version => version }.merge(@request_params || {})) }
|
5
5
|
|
6
6
|
let(:version) { 4 }
|
7
|
-
let(:client_request) { client_handshake_04({ :key => handshake.send(:key), :version => version }.merge(@request_params || {})) }
|
8
|
-
let(:server_response) { server_handshake_04({ :accept => handshake.send(:accept) }.merge(@request_params || {})) }
|
7
|
+
let(:client_request) { client_handshake_04({ :key => handshake.handler.send(:key), :version => version }.merge(@request_params || {})) }
|
8
|
+
let(:server_response) { server_handshake_04({ :accept => handshake.handler.send(:accept) }.merge(@request_params || {})) }
|
9
9
|
|
10
10
|
it_should_behave_like 'all client drafts'
|
11
11
|
|
@@ -15,6 +15,6 @@ describe 'Client draft 4 handshake' do
|
|
15
15
|
|
16
16
|
handshake.should be_finished
|
17
17
|
handshake.should_not be_valid
|
18
|
-
handshake.error.should eql(:
|
18
|
+
handshake.error.should eql(:invalid_handshake_authentication)
|
19
19
|
end
|
20
20
|
end
|
@@ -4,8 +4,8 @@ describe 'Client draft 76 handshake' do
|
|
4
4
|
let(:handshake) { WebSocket::Handshake::Client.new({ :uri => 'ws://example.com/demo', :origin => 'http://example.com', :version => version }.merge(@request_params || {})) }
|
5
5
|
|
6
6
|
let(:version) { 76 }
|
7
|
-
let(:client_request) { client_handshake_76({ :key1 => handshake.send(:key1), :key2 => handshake.send(:key2), :key3 => handshake.send(:key3) }.merge(@request_params || {})) }
|
8
|
-
let(:server_response) { server_handshake_76({ :challenge => handshake.send(:challenge) }.merge(@request_params || {})) }
|
7
|
+
let(:client_request) { client_handshake_76({ :key1 => handshake.handler.send(:key1), :key2 => handshake.handler.send(:key2), :key3 => handshake.handler.send(:key3) }.merge(@request_params || {})) }
|
8
|
+
let(:server_response) { server_handshake_76({ :challenge => handshake.handler.send(:challenge) }.merge(@request_params || {})) }
|
9
9
|
|
10
10
|
it_should_behave_like 'all client drafts'
|
11
11
|
|
@@ -15,6 +15,6 @@ describe 'Client draft 76 handshake' do
|
|
15
15
|
|
16
16
|
handshake.should be_finished
|
17
17
|
handshake.should_not be_valid
|
18
|
-
handshake.error.should eql(:
|
18
|
+
handshake.error.should eql(:invalid_handshake_authentication)
|
19
19
|
end
|
20
20
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -83,4 +83,37 @@ shared_examples_for 'all server drafts' do
|
|
83
83
|
handshake.should_not be_valid
|
84
84
|
handshake.error.should eql(:get_request_required)
|
85
85
|
end
|
86
|
+
|
87
|
+
it "should parse a rack request" do
|
88
|
+
request = WEBrick::HTTPRequest.new( :ServerSoftware => "rspec" )
|
89
|
+
request.parse(StringIO.new(client_request)).should be_true
|
90
|
+
rest = client_request.slice((request.to_s.length..-1))
|
91
|
+
|
92
|
+
handshake.from_rack(request.meta_vars.merge(
|
93
|
+
"rack.input" => StringIO.new(rest)
|
94
|
+
))
|
95
|
+
validate_request
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should parse a hash request" do
|
99
|
+
request = WEBrick::HTTPRequest.new( :ServerSoftware => "rspec" )
|
100
|
+
request.parse(StringIO.new(client_request)).should be_true
|
101
|
+
body = client_request.slice((request.to_s.length..-1))
|
102
|
+
|
103
|
+
path = request.path
|
104
|
+
query = request.query_string
|
105
|
+
headers = request.header.inject({}) do |hash, header|
|
106
|
+
hash[header[0]] = header[1].first if header[0] && header[1]
|
107
|
+
hash
|
108
|
+
end
|
109
|
+
|
110
|
+
handshake.from_hash({
|
111
|
+
:headers => headers,
|
112
|
+
:path => path,
|
113
|
+
:query => query,
|
114
|
+
:body => body
|
115
|
+
})
|
116
|
+
|
117
|
+
validate_request
|
118
|
+
end
|
86
119
|
end
|