2015-09-15 17:12:15 +00:00
|
|
|
from __future__ import absolute_import, print_function, division
|
|
|
|
|
|
|
|
from ... import utils
|
2015-09-17 00:39:42 +00:00
|
|
|
import itertools
|
2015-09-15 17:12:15 +00:00
|
|
|
from ...exceptions import HttpException
|
|
|
|
from .. import CONTENT_MISSING
|
|
|
|
|
|
|
|
|
|
|
|
def assemble_request(request):
|
2015-09-25 22:39:04 +00:00
|
|
|
if request.content == CONTENT_MISSING:
|
2015-09-15 17:12:15 +00:00
|
|
|
raise HttpException("Cannot assemble flow with CONTENT_MISSING")
|
|
|
|
head = assemble_request_head(request)
|
2015-09-25 22:39:04 +00:00
|
|
|
body = b"".join(assemble_body(request.headers, [request.data.content]))
|
2015-09-18 16:05:50 +00:00
|
|
|
return head + body
|
2015-09-15 17:12:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
def assemble_request_head(request):
|
2015-09-25 22:39:04 +00:00
|
|
|
first_line = _assemble_request_line(request.data)
|
|
|
|
headers = _assemble_request_headers(request.data)
|
2015-09-15 17:12:15 +00:00
|
|
|
return b"%s\r\n%s\r\n" % (first_line, headers)
|
|
|
|
|
|
|
|
|
|
|
|
def assemble_response(response):
|
2015-09-25 22:39:04 +00:00
|
|
|
if response.content == CONTENT_MISSING:
|
2015-09-15 17:12:15 +00:00
|
|
|
raise HttpException("Cannot assemble flow with CONTENT_MISSING")
|
|
|
|
head = assemble_response_head(response)
|
2015-09-25 22:39:04 +00:00
|
|
|
body = b"".join(assemble_body(response.headers, [response.content]))
|
2015-09-18 16:05:50 +00:00
|
|
|
return head + body
|
2015-09-15 17:12:15 +00:00
|
|
|
|
|
|
|
|
2015-09-17 00:39:42 +00:00
|
|
|
def assemble_response_head(response):
|
2015-09-15 17:12:15 +00:00
|
|
|
first_line = _assemble_response_line(response)
|
2015-09-17 00:39:42 +00:00
|
|
|
headers = _assemble_response_headers(response)
|
2015-09-15 17:12:15 +00:00
|
|
|
return b"%s\r\n%s\r\n" % (first_line, headers)
|
|
|
|
|
|
|
|
|
2015-09-17 00:39:42 +00:00
|
|
|
def assemble_body(headers, body_chunks):
|
2015-09-21 23:48:35 +00:00
|
|
|
if "chunked" in headers.get("transfer-encoding", "").lower():
|
2015-09-17 00:39:42 +00:00
|
|
|
for chunk in body_chunks:
|
|
|
|
if chunk:
|
|
|
|
yield b"%x\r\n%s\r\n" % (len(chunk), chunk)
|
|
|
|
yield b"0\r\n\r\n"
|
|
|
|
else:
|
|
|
|
for chunk in body_chunks:
|
|
|
|
yield chunk
|
|
|
|
|
|
|
|
|
2015-09-25 22:39:04 +00:00
|
|
|
def _assemble_request_line(request_data):
|
|
|
|
"""
|
|
|
|
Args:
|
|
|
|
request_data (netlib.http.request.RequestData)
|
|
|
|
"""
|
|
|
|
form = request_data.first_line_format
|
2015-09-15 17:12:15 +00:00
|
|
|
if form == "relative":
|
|
|
|
return b"%s %s %s" % (
|
2015-09-25 22:39:04 +00:00
|
|
|
request_data.method,
|
|
|
|
request_data.path,
|
|
|
|
request_data.http_version
|
2015-09-15 17:12:15 +00:00
|
|
|
)
|
|
|
|
elif form == "authority":
|
|
|
|
return b"%s %s:%d %s" % (
|
2015-09-25 22:39:04 +00:00
|
|
|
request_data.method,
|
|
|
|
request_data.host,
|
|
|
|
request_data.port,
|
|
|
|
request_data.http_version
|
2015-09-15 17:12:15 +00:00
|
|
|
)
|
|
|
|
elif form == "absolute":
|
2015-09-15 22:04:23 +00:00
|
|
|
return b"%s %s://%s:%d%s %s" % (
|
2015-09-25 22:39:04 +00:00
|
|
|
request_data.method,
|
|
|
|
request_data.scheme,
|
|
|
|
request_data.host,
|
|
|
|
request_data.port,
|
|
|
|
request_data.path,
|
|
|
|
request_data.http_version
|
2015-09-15 17:12:15 +00:00
|
|
|
)
|
2015-09-25 22:39:04 +00:00
|
|
|
else:
|
2015-09-15 17:12:15 +00:00
|
|
|
raise RuntimeError("Invalid request form")
|
|
|
|
|
|
|
|
|
2015-09-25 22:39:04 +00:00
|
|
|
def _assemble_request_headers(request_data):
|
|
|
|
"""
|
|
|
|
Args:
|
|
|
|
request_data (netlib.http.request.RequestData)
|
|
|
|
"""
|
|
|
|
headers = request_data.headers.copy()
|
|
|
|
if "host" not in headers and request_data.scheme and request_data.host and request_data.port:
|
2015-09-21 23:48:35 +00:00
|
|
|
headers["host"] = utils.hostport(
|
2015-09-25 22:39:04 +00:00
|
|
|
request_data.scheme,
|
|
|
|
request_data.host,
|
|
|
|
request_data.port
|
2015-09-15 17:12:15 +00:00
|
|
|
)
|
2015-09-15 22:04:23 +00:00
|
|
|
return bytes(headers)
|
2015-09-15 17:12:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _assemble_response_line(response):
|
2015-09-15 22:04:23 +00:00
|
|
|
return b"%s %d %s" % (
|
2015-09-17 13:16:12 +00:00
|
|
|
response.http_version,
|
2015-09-15 17:12:15 +00:00
|
|
|
response.status_code,
|
|
|
|
response.msg,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2015-09-17 00:39:42 +00:00
|
|
|
def _assemble_response_headers(response):
|
2015-09-18 16:05:50 +00:00
|
|
|
return bytes(response.headers)
|