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
|
begin
|
||||||
c = connect(opts)
|
c = connect(opts)
|
||||||
r = c.request_raw(opts)
|
r = c.request_raw(opts)
|
||||||
resp = c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
|
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
|
|
||||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -246,12 +241,7 @@ module Exploit::Remote::HttpClient
|
||||||
begin
|
begin
|
||||||
c = connect(opts)
|
c = connect(opts)
|
||||||
r = c.request_cgi(opts)
|
r = c.request_cgi(opts)
|
||||||
resp = c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
|
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
|
|
||||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -290,9 +280,6 @@ module Exploit::Remote::HttpClient
|
||||||
return [nil,nil]
|
return [nil,nil]
|
||||||
end
|
end
|
||||||
return [nil,nil] if resp.code == 404
|
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']
|
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
|
||||||
|
|
||||||
# Get the challenge and craft the response
|
# Get the challenge and craft the response
|
||||||
|
@ -316,9 +303,6 @@ module Exploit::Remote::HttpClient
|
||||||
return [nil,nil]
|
return [nil,nil]
|
||||||
end
|
end
|
||||||
return [nil,nil] if resp.code == 404
|
return [nil,nil] if resp.code == 404
|
||||||
while(resp and resp.code == 100)
|
|
||||||
resp = c.reread_response(resp, to)
|
|
||||||
end
|
|
||||||
return [resp,c]
|
return [resp,c]
|
||||||
|
|
||||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||||
|
|
|
@ -363,7 +363,7 @@ class Client
|
||||||
)
|
)
|
||||||
begin
|
begin
|
||||||
buff = conn.get_once(-1, 1)
|
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"
|
# XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception"
|
||||||
|
@ -390,7 +390,7 @@ class Client
|
||||||
rblob = rbody.to_s + rbufq.to_s
|
rblob = rbody.to_s + rbufq.to_s
|
||||||
tries = 0
|
tries = 0
|
||||||
begin
|
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
|
while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i
|
||||||
buff = conn.get_once(-1, 0.05)
|
buff = conn.get_once(-1, 0.05)
|
||||||
break if not buff
|
break if not buff
|
||||||
|
@ -405,50 +405,20 @@ class Client
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
resp
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
return resp if not resp
|
||||||
# Read a response from the server (starting with existing data)
|
|
||||||
#
|
|
||||||
def reread_response(resp, t = -1)
|
|
||||||
|
|
||||||
|
# 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']
|
resp.max_data = config['read_max_data']
|
||||||
resp.reset_except_queue
|
rv = resp.parse(body)
|
||||||
resp.parse('')
|
# XXX: At some point, this may benefit from processing post-completion code
|
||||||
|
# as seen above.
|
||||||
# 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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resp
|
resp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue