move 100-continue processing into Rex, fixes #3109
git-svn-id: file:///home/svn/framework3/trunk@10919 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
f638b3d386
commit
8353bf7bf3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue