daphne/channels/request.py
2015-12-02 12:54:52 -08:00

70 lines
2.2 KiB
Python

from django.http import HttpRequest
from django.http.request import QueryDict
from django.utils.datastructures import MultiValueDict
def encode_request(request):
"""
Encodes a request to JSON-compatible datastructures
"""
# TODO: More stuff
value = {
"get": dict(request.GET.lists()),
"post": dict(request.POST.lists()),
"cookies": request.COOKIES,
"headers": {
k[5:].lower(): v
for k, v in request.META.items()
if k.lower().startswith("http_")
},
"path": request.path,
"method": request.method,
"reply_channel": request.reply_channel,
"server": [
request.META.get("SERVER_NAME", None),
request.META.get("SERVER_PORT", None),
],
"client": [
request.META.get("REMOTE_ADDR", None),
request.META.get("REMOTE_PORT", None),
],
}
return value
def decode_request(value):
"""
Decodes a request JSONish value to a HttpRequest object.
"""
request = HttpRequest()
request.GET = CustomQueryDict(value['get'])
request.POST = CustomQueryDict(value['post'])
request.COOKIES = value['cookies']
request.path = value['path']
request.method = value['method']
request.reply_channel = value['reply_channel']
# Channels requests are more high-level than the dumping ground that is
# META; re-combine back into it
request.META = {
"REQUEST_METHOD": value["method"],
"SERVER_NAME": value["server"][0],
"SERVER_PORT": value["server"][1],
"REMOTE_ADDR": value["client"][0],
"REMOTE_HOST": value["client"][0], # Not the DNS name, hopefully fine.
}
for header, header_value in value.get("headers", {}).items():
request.META["HTTP_%s" % header.upper()] = header_value
# We don't support non-/ script roots
request.path_info = value['path']
return request
class CustomQueryDict(QueryDict):
"""
Custom override of QueryDict that sets things directly.
"""
def __init__(self, values, mutable=False, encoding=None):
""" mutable and encoding are ignored :( """
MultiValueDict.__init__(self, values)