move 100-continue processing into Rex, fixes #3109

git-svn-id: file:///home/svn/framework3/trunk@10919 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Joshua Drake 2010-11-05 16:20:13 +00:00
parent f638b3d386
commit 8353bf7bf3
2 changed files with 15 additions and 61 deletions

View File

@ -226,12 +226,7 @@ module Exploit::Remote::HttpClient
begin
c = connect(opts)
r = c.request_raw(opts)
resp = c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
while(resp and resp.code == 100)
print_status("Got a 100 response, trying to read again")
resp = c.read_response(opts[:timeout] ? opts[:timeout] : timeout)
end
resp
c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
nil
end
@ -246,12 +241,7 @@ module Exploit::Remote::HttpClient
begin
c = connect(opts)
r = c.request_cgi(opts)
resp = c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
while(resp and resp.code == 100)
print_status("Got a 100 response, trying to read again")
resp = c.read_response(opts[:timeout] ? opts[:timeout] : timeout)
end
resp
c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
nil
end
@ -290,9 +280,6 @@ module Exploit::Remote::HttpClient
return [nil,nil]
end
return [nil,nil] if resp.code == 404
while(resp and resp.code == 100)
resp = c.reread_response(resp, to)
end
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
# Get the challenge and craft the response
@ -316,9 +303,6 @@ module Exploit::Remote::HttpClient
return [nil,nil]
end
return [nil,nil] if resp.code == 404
while(resp and resp.code == 100)
resp = c.reread_response(resp, to)
end
return [resp,c]
rescue ::Errno::EPIPE, ::Timeout::Error

View File

@ -363,7 +363,7 @@ class Client
)
begin
buff = conn.get_once(-1, 1)
rv = resp.parse( buff || '')
rv = resp.parse( buff || '' )
##########################################################################
# XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception"
@ -390,7 +390,7 @@ class Client
rblob = rbody.to_s + rbufq.to_s
tries = 0
begin
# XXX This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
# XXX: This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i
buff = conn.get_once(-1, 0.05)
break if not buff
@ -405,50 +405,20 @@ class Client
end
end
end
resp
end
#
# Read a response from the server (starting with existing data)
#
def reread_response(resp, t = -1)
return resp if not resp
resp.max_data = config['read_max_data']
resp.reset_except_queue
resp.parse('')
# Wait at most t seconds for the full response to be read in. We only
# do this if t was specified as a negative value indicating an infinite
# wait cycle. If t were specified as nil it would indicate that no
# response parsing is required.
return resp if not t
Timeout.timeout((t < 0) ? nil : t) do
rv = resp.state
while (
rv != Packet::ParseCode::Completed and
rv != Packet::ParseCode::Error
)
begin
buff = conn.get
rv = resp.parse( buff || '')
# Handle unexpected disconnects
rescue ::Errno::EPIPE, ::EOFError, ::IOError
case resp.state
when Packet::ParseState::ProcessingHeader
resp = nil
when Packet::ParseState::ProcessingBody
# truncated request, good enough
resp.error = :truncated
end
break
end
end
# As a last minute hack, we check to see if we're dealing with a 100 Continue here.
if resp.proto == '1.1' and resp.code == 100
# If so, our real response becaome the body, so we re-parse it.
body = resp.body
resp = Response.new
resp.max_data = config['read_max_data']
rv = resp.parse(body)
# XXX: At some point, this may benefit from processing post-completion code
# as seen above.
end
resp
end