239 lines
5.9 KiB
Ruby
239 lines
5.9 KiB
Ruby
|
require 'em_test_helper'
|
||
|
|
||
|
class TestHttpClient < Test::Unit::TestCase
|
||
|
|
||
|
def setup
|
||
|
@port = next_port
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
def test_http_client
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
c.errback {EM.stop} # necessary, otherwise a failure blocks the test suite forever.
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
def test_http_client_1
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
c.errback {EM.stop}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
def test_http_client_2
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
c.errback {EM.stop}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
|
||
|
#-----------------------------------------
|
||
|
|
||
|
# Test a server that returns a page with a zero content-length.
|
||
|
# This caused an early version of the HTTP client not to generate a response,
|
||
|
# causing this test to hang. Observe, there was no problem with responses
|
||
|
# lacking a content-length, just when the content-length was zero.
|
||
|
#
|
||
|
class EmptyContent < EM::Connection
|
||
|
def initialize *args
|
||
|
super
|
||
|
end
|
||
|
def receive_data data
|
||
|
send_data "HTTP/1.0 404 ...\r\nContent-length: 0\r\n\r\n"
|
||
|
close_connection_after_writing
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_http_empty_content
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
EM.start_server "127.0.0.1", @port, EmptyContent
|
||
|
c = silent { EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => @port }
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
|
||
|
#---------------------------------------
|
||
|
|
||
|
class PostContent < EM::P::LineAndTextProtocol
|
||
|
def initialize *args
|
||
|
super
|
||
|
@lines = []
|
||
|
end
|
||
|
def receive_line line
|
||
|
if line.length > 0
|
||
|
@lines << line
|
||
|
else
|
||
|
process_headers
|
||
|
end
|
||
|
end
|
||
|
def receive_binary_data data
|
||
|
@post_content = data
|
||
|
send_response
|
||
|
end
|
||
|
def process_headers
|
||
|
if @lines.first =~ /\APOST ([^\s]+) HTTP\/1.1\Z/
|
||
|
@uri = $1.dup
|
||
|
else
|
||
|
raise "bad request"
|
||
|
end
|
||
|
|
||
|
@lines.each {|line|
|
||
|
if line =~ /\AContent-length:\s*(\d+)\Z/i
|
||
|
@content_length = $1.dup.to_i
|
||
|
elsif line =~ /\AContent-type:\s*(\d+)\Z/i
|
||
|
@content_type = $1.dup
|
||
|
end
|
||
|
}
|
||
|
|
||
|
raise "invalid content length" unless @content_length
|
||
|
set_binary_mode @content_length
|
||
|
end
|
||
|
def send_response
|
||
|
send_data "HTTP/1.1 200 ...\r\nConnection: close\r\nContent-length: 10\r\nContent-type: text/html\r\n\r\n0123456789"
|
||
|
close_connection_after_writing
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# TODO, this is WRONG. The handler is asserting an HTTP 1.1 request, but the client
|
||
|
# is sending a 1.0 request. Gotta fix the client
|
||
|
def test_post
|
||
|
response = nil
|
||
|
EM.run {
|
||
|
EM.start_server '127.0.0.1', @port, PostContent
|
||
|
setup_timeout(2)
|
||
|
c = silent { EM::P::HttpClient.request(
|
||
|
:host => '127.0.0.1',
|
||
|
:port => @port,
|
||
|
:method => :post,
|
||
|
:request => "/aaa",
|
||
|
:content => "XYZ",
|
||
|
:content_type => "text/plain"
|
||
|
)}
|
||
|
c.callback {|r|
|
||
|
response = r
|
||
|
EM.stop
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assert_equal( 200, response[:status] )
|
||
|
assert_equal( "0123456789", response[:content] )
|
||
|
end
|
||
|
|
||
|
|
||
|
# TODO, need a more intelligent cookie tester.
|
||
|
# In fact, this whole test-harness needs a beefier server implementation.
|
||
|
def test_cookie
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
c = silent { EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb" }
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
c.errback {EM.stop}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
# We can tell the client to send an HTTP/1.0 request (default is 1.1).
|
||
|
# This is useful for suppressing chunked responses until those are working.
|
||
|
def test_version_1_0
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
c = silent { EM::P::HttpClient.request(
|
||
|
:host => "www.google.com",
|
||
|
:port => 80,
|
||
|
:version => "1.0"
|
||
|
)}
|
||
|
c.callback {
|
||
|
ok = true
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
c.errback {EM.stop}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
#-----------------------------------------
|
||
|
|
||
|
# Test a server that returns chunked encoding
|
||
|
#
|
||
|
class ChunkedEncodingContent < EventMachine::Connection
|
||
|
def initialize *args
|
||
|
super
|
||
|
end
|
||
|
def receive_data data
|
||
|
send_data ["HTTP/1.1 200 OK",
|
||
|
"Server: nginx/0.7.67",
|
||
|
"Date: Sat, 23 Oct 2010 16:41:32 GMT",
|
||
|
"Content-Type: application/json",
|
||
|
"Transfer-Encoding: chunked",
|
||
|
"Connection: keep-alive",
|
||
|
"",
|
||
|
"1800",
|
||
|
"chunk1" * 1024,
|
||
|
"5a",
|
||
|
"chunk2" * 15,
|
||
|
"0",
|
||
|
""].join("\r\n")
|
||
|
close_connection_after_writing
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_http_chunked_encoding_content
|
||
|
ok = false
|
||
|
EM.run {
|
||
|
EM.start_server "127.0.0.1", @port, ChunkedEncodingContent
|
||
|
c = silent { EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => @port }
|
||
|
c.callback { |result|
|
||
|
if result[:content] == "chunk1" * 1024 + "chunk2" * 15
|
||
|
ok = true
|
||
|
end
|
||
|
c.close_connection
|
||
|
EM.stop
|
||
|
}
|
||
|
}
|
||
|
assert ok
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
|