2005-12-17 06:46:23 +00:00
|
|
|
#!/usr/bin/env ruby
|
2005-07-24 20:53:54 +00:00
|
|
|
|
|
|
|
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
|
|
|
|
|
|
|
require 'test/unit'
|
|
|
|
require 'rex/proto/http'
|
|
|
|
|
2005-12-02 02:35:30 +00:00
|
|
|
class Rex::Proto::Http::Response::UnitTest < Test::Unit::TestCase
|
2005-07-24 20:53:54 +00:00
|
|
|
|
|
|
|
Klass = Rex::Proto::Http::Response
|
|
|
|
|
* add junk pipelined request support
* fix socket creation on pipelined requests
* when a server says that the connection should be closed (Connection: closed), then close the connection, since its going to regardless, and we don't want to loose our state
* support non-standard line termination in headers. ie \n instead of \r\n
* add junk headers (X-rand: rand)
* add header folding (for evasion)
* add parse_header_re (still leaving parse_header around, though its dead code ATM) that does the right thing on non-standard line endings
* move 'gzip' to a 'compression' option
* add 'deflate' compression option (really, just raw zlib, and only firefox does deflate right)
* fix a bunch of TE:chunked decoding bugs based based on the fact that Apache doesn't always close chunks appropriately
* modify parse_body to not return state, since it doesn't always do that, and the return isn't used... self.state is.
* add TE:chunked request support
* normalize URIs in requests before saving them
* Move params out of the URI, but when the uri is requested, and the method is GET, and there are params, return a URI that has the params that are approrpiately encoded (needed for junk_params, see below)
* move request.to_s support of params to use the request params array when a POST, allows use of junk params support (see below). NOTE: If the body is provided, use the body instead of params, in case you want to hardcode the params in a POST request, eg: php_xmlrpc_eval.rb
* Add junk params when building a param list, eg: a=b becomes asdfasdf=asdrt32a&asdfad=okhgasd&a=b&hjklasdf=hkasgd
* add URI junk slash support (eg: /////foo.html)
* param splitting now supports both '&', and ';', which CGI.pm and PHP both allow
* add URI junk directory support, eg: /asdf/../foo.html
* add param encoding support, eg: param A with value '=' is A=%3d
* add URI junk self referring directory support, eg: /././foo.html
git-svn-id: file:///home/svn/incoming/trunk@3457 4d416f70-5f16-0410-b530-b9f4589650da
2006-01-27 21:57:44 +00:00
|
|
|
def test_deflate
|
|
|
|
h = Klass.new
|
|
|
|
h.body = 'hi mom'
|
|
|
|
h.compress = 'deflate'
|
|
|
|
assert_equal(
|
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Content-Encoding: deflate\r\n" +
|
|
|
|
"Content-Length: 14\r\n\r\n" +
|
|
|
|
"x\234\313\310T\310\315\317\005\000\a\225\002;",
|
|
|
|
h.to_s, 'deflate'
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_gzip
|
|
|
|
h = Klass.new
|
|
|
|
h.body = 'hi mom'
|
|
|
|
h.compress = 'gzip'
|
|
|
|
srand(0)
|
|
|
|
|
|
|
|
response = h.to_s
|
|
|
|
|
|
|
|
http_header = response.slice!(0,63)
|
|
|
|
|
|
|
|
assert_equal(
|
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Content-Encoding: gzip\r\n" +
|
|
|
|
"Content-Length: 26\r\n\r\n",
|
|
|
|
http_header, 'http headers'
|
|
|
|
)
|
|
|
|
|
|
|
|
assert_equal("\x1f\x8b\x08\x00", response.slice!(0,4), 'gzip headers')
|
|
|
|
|
|
|
|
# skip the next 6 bytes as it is host & time specific (zlib's example gun does, so why not us too?)
|
|
|
|
response.slice!(0,6)
|
|
|
|
|
|
|
|
assert_equal("\xcb\xc8\x54\xc8\xcd\xcf\x05\x00\x68\xa4\x1c\xf0\x06\x00\x00\x00", response, 'gzip data')
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2005-07-24 20:53:54 +00:00
|
|
|
def test_to_s
|
|
|
|
h = Klass.new
|
|
|
|
|
|
|
|
h.headers['Foo'] = 'Fishing'
|
|
|
|
h.headers['Chicken'] = 47
|
|
|
|
|
|
|
|
assert_equal(
|
2005-12-02 02:35:30 +00:00
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
2005-07-24 20:53:54 +00:00
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Content-Length: 0\r\n" +
|
2006-01-05 22:20:28 +00:00
|
|
|
"Chicken: 47\r\n\r\n", h.to_s, 'to_s w/o body')
|
|
|
|
|
2006-01-27 05:33:08 +00:00
|
|
|
h.body = 'hi mom'
|
|
|
|
assert_equal(
|
2006-01-05 22:20:28 +00:00
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Content-Length: 6\r\n" +
|
|
|
|
"Chicken: 47\r\n\r\nhi mom", h.to_s, 'to_s w/ body')
|
2005-07-24 20:53:54 +00:00
|
|
|
end
|
|
|
|
|
2006-01-05 22:20:28 +00:00
|
|
|
|
2006-01-27 05:33:08 +00:00
|
|
|
def test_chunked
|
2006-01-05 22:20:28 +00:00
|
|
|
h = Klass.new
|
|
|
|
|
|
|
|
h.headers['Foo'] = 'Fishing'
|
|
|
|
h.headers['Chicken'] = 47
|
2006-01-27 05:33:08 +00:00
|
|
|
h.auto_cl = false
|
2006-01-05 22:20:28 +00:00
|
|
|
h.transfer_chunked = true
|
|
|
|
|
|
|
|
|
|
|
|
assert_equal(
|
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Transfer-Encoding: chunked\r\n" +
|
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Chicken: 47\r\n\r\n0\r\n\r\n", h.to_s, 'chunked w/o body'
|
2006-01-27 05:33:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
srand(0)
|
|
|
|
h.body = Rex::Text.rand_text_alphanumeric(100)
|
|
|
|
assert_equal(
|
2006-01-05 22:20:28 +00:00
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Transfer-Encoding: chunked\r\n" +
|
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Chicken: 47\r\n\r\n" +
|
2006-01-27 05:33:08 +00:00
|
|
|
"5\r\nsv1AD\r\n7\r\n7DnJTVy\r\n5\r\nkXGYY\r\n5\r\nM6Bmn\r\n4\r\nXuYR\r\n5\r\nlZNIJ\r\n5\r\nUzQzF\r\n9\r\nPvASjYxzd\r\n5\r\nTTOng\r\n4\r\nBJ5g\r\n8\r\nfK0XjLy3\r\n6\r\nciAAk1\r\n6\r\nFmo0RP\r\n1\r\nE\r\n2\r\npq\r\n6\r\n6f4BBn\r\n4\r\np5jm\r\n1\r\n3\r\n6\r\nLuSbAO\r\n1\r\nj\r\n2\r\n1M\r\n3\r\n5qU\r\n0\r\n\r\n",
|
|
|
|
h.to_s, 'random chunk sizes'
|
|
|
|
)
|
|
|
|
|
|
|
|
h.chunk_max_size = 1
|
|
|
|
h.body = 'hi mom'
|
|
|
|
assert_equal(
|
2006-01-05 22:20:28 +00:00
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Transfer-Encoding: chunked\r\n" +
|
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Chicken: 47\r\n\r\n" +
|
2006-01-27 05:33:08 +00:00
|
|
|
"1\r\nh\r\n1\r\ni\r\n1\r\n \r\n1\r\nm\r\n1\r\no\r\n1\r\nm\r\n0\r\n\r\n",
|
|
|
|
h.to_s, '1 byte chunks'
|
|
|
|
)
|
|
|
|
|
|
|
|
h.chunk_min_size = 2
|
|
|
|
assert_equal(
|
|
|
|
"HTTP/1.1 200 OK\r\n" +
|
|
|
|
"Transfer-Encoding: chunked\r\n" +
|
|
|
|
"Foo: Fishing\r\n" +
|
|
|
|
"Chicken: 47\r\n\r\n" +
|
|
|
|
"2\r\nhi\r\n2\r\n m\r\n2\r\nom\r\n0\r\n\r\n",
|
|
|
|
h.to_s, '2 byte chunks'
|
|
|
|
)
|
|
|
|
|
|
|
|
h = Klass.new(200, 'OK', '1.0')
|
|
|
|
h.body = 'hi mom'
|
|
|
|
h.auto_cl = false
|
|
|
|
h.transfer_chunked = true
|
|
|
|
assert_raise(Rex::RuntimeError, 'chunked encoding via 1.0') {
|
|
|
|
h.to_s
|
|
|
|
}
|
|
|
|
|
|
|
|
end
|
2006-01-05 22:20:28 +00:00
|
|
|
|
2005-07-24 20:53:54 +00:00
|
|
|
def test_from_s
|
|
|
|
h = Klass.new
|
|
|
|
|
|
|
|
h.from_s(
|
|
|
|
"HTTP/1.0 404 File not found\r\n" +
|
|
|
|
"Lucifer: Beast\r\n" +
|
|
|
|
"HoHo: Satan\r\n" +
|
|
|
|
"Eat: Babies\r\n" +
|
|
|
|
"\r\n")
|
|
|
|
|
2005-12-02 02:35:30 +00:00
|
|
|
assert_equal(404, h.code)
|
2005-07-24 20:53:54 +00:00
|
|
|
assert_equal('File not found', h.message)
|
|
|
|
assert_equal('1.0', h.proto)
|
|
|
|
assert_equal("HTTP/1.0 404 File not found\r\n", h.cmd_string)
|
|
|
|
h.code = 470
|
|
|
|
assert_equal("HTTP/1.0 470 File not found\r\n", h.cmd_string)
|
|
|
|
assert_equal('Babies', h['Eat'])
|
|
|
|
end
|
|
|
|
|
2008-10-19 21:03:39 +00:00
|
|
|
end
|