1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
require 'spec_helper'
describe Connection do
before do
allow(EventMachine).to receive(:send_data)
@connection = Connection.new(double('EM').as_null_object)
@connection.post_init
@connection.backend = double("backend", :ssl? => false)
@connection.app = proc do |env|
[200, {}, ['body']]
end
end
it "should parse on receive_data" do
expect(@connection.request).to receive(:parse).with('GET')
@connection.receive_data('GET')
end
it "should make a valid response on bad request" do
allow(@connection.request).to receive(:parse).and_raise(InvalidRequest)
expect(@connection).to receive(:post_process).with(Response::BAD_REQUEST)
@connection.receive_data('')
end
it "should close connection on InvalidRequest error in receive_data" do
allow(@connection.request).to receive(:parse).and_raise(InvalidRequest)
allow(@connection.response).to receive(:persistent?) { false }
@connection.can_persist!
expect(@connection).to receive(:terminate_request)
@connection.receive_data('')
end
it "should process when parsing complete" do
expect(@connection.request).to receive(:parse).and_return(true)
expect(@connection).to receive(:process)
@connection.receive_data('GET')
end
it "should process at most once when request is larger than expected" do
expect(@connection).to receive(:process).at_most(1)
@connection.receive_data("POST / HTTP/1.1\r\nHost: localhost:3000\r\nContent-Length: 300\r\n\r\n")
10.times { @connection.receive_data('X' * 1_000) }
end
it "should process" do
@connection.process
end
it "should rescue error in process" do
expect(@connection.app).to receive(:call).and_raise(StandardError)
allow(@connection.response).to receive(:persistent?) { false }
expect(@connection).to receive(:terminate_request)
@connection.process
end
it "should make response on error" do
expect(@connection.app).to receive(:call).and_raise(StandardError)
expect(@connection).to receive(:post_process).with(Response::ERROR)
@connection.process
end
it "should not close persistent connection on error" do
expect(@connection.app).to receive(:call).and_raise(StandardError)
allow(@connection.response).to receive(:persistent?) { true }
@connection.can_persist!
expect(@connection).to receive(:teminate_request).never
@connection.process
end
it "should rescue Timeout error in process" do
expect(@connection.app).to receive(:call).and_raise(Timeout::Error.new("timeout error not rescued"))
@connection.process
end
it "should not return HTTP_X_FORWARDED_FOR as remote_address" do
@connection.request.env['HTTP_X_FORWARDED_FOR'] = '1.2.3.4'
allow(@connection).to receive(:socket_address) { "127.0.0.1" }
expect(@connection.remote_address).to eq("127.0.0.1")
end
it "should return nil on error retrieving remote_address" do
allow(@connection).to receive(:get_peername).and_raise(RuntimeError)
expect(@connection.remote_address).to be_nil
end
it "should return nil on nil get_peername" do
allow(@connection).to receive(:get_peername) { nil }
expect(@connection.remote_address).to be_nil
end
it "should return nil on empty get_peername" do
allow(@connection).to receive(:get_peername) { '' }
expect(@connection.remote_address).to be_nil
end
it "should return remote_address" do
allow(@connection).to receive(:get_peername) do
Socket.pack_sockaddr_in(3000, '127.0.0.1')
end
expect(@connection.remote_address).to eq('127.0.0.1')
end
it "should not be persistent" do
expect(@connection).not_to be_persistent
end
it "should be persistent when response is and allowed" do
allow(@connection.response).to receive(:persistent?) { true }
@connection.can_persist!
expect(@connection).to be_persistent
end
it "should not be persistent when response is but not allowed" do
@connection.response.persistent!
expect(@connection).not_to be_persistent
end
it "should return empty body on HEAD request" do
expect(@connection.request).to receive(:head?).and_return(true)
expect(@connection).to receive(:send_data).once # Only once for the headers
@connection.process
end
it "should set request env as rack.multithread" do
expect(EventMachine).to receive(:defer)
@connection.threaded = true
@connection.process
expect(@connection.request.env["rack.multithread"]).to eq(true)
end
it "should set as threaded when app.deferred? is true" do
expect(@connection.app).to receive(:deferred?).and_return(true)
expect(@connection).to be_threaded
end
it "should not set as threaded when app.deferred? is false" do
expect(@connection.app).to receive(:deferred?).and_return(false)
expect(@connection).not_to be_threaded
end
it "should not set as threaded when app do not respond to deferred?" do
expect(@connection).not_to be_threaded
end
it "should have correct SERVER_PORT when using ssl" do
@connection.backend = double("backend", :ssl? => true, :port => 443)
@connection.process
expect(@connection.request.env["SERVER_PORT"]).to eq("443")
end
end
|