blob: 280a1e982861aa10b9e8624ac1358c509769fdaf [file] [log] [blame]
# Copyright 2012 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Convenience functions for testing against Django."""
from __future__ import (
absolute_import,
print_function,
unicode_literals,
)
str = None
__metaclass__ = type
__all__ = []
from io import BytesIO
import os
from django.core.files.uploadhandler import MemoryFileUploadHandler
from django.http.multipartparser import MultiPartParser
from maasserver.utils import ignore_unused
def parse_headers_and_body_with_django(headers, body):
"""Parse `headers` and `body` with Django's :class:`MultiPartParser`.
`MultiPartParser` is a curiously ugly and RFC non-compliant concoction.
Amongst other things, it coerces all field names, field data, and
filenames into Unicode strings using the "replace" error strategy, so be
warned that your data may be silently mangled.
It also, in 1.3.1 at least, does not recognise any transfer encodings at
*all* because its header parsing code was broken.
I'm also fairly sure that it'll fall over on headers than span more than
one line.
In short, it's a piece of code that inspires little confidence, yet we
must work with it, hence we need to round-trip test multipart handling
with it.
"""
handler = MemoryFileUploadHandler()
meta = {
"HTTP_CONTENT_TYPE": headers["Content-Type"],
"HTTP_CONTENT_LENGTH": headers["Content-Length"],
}
parser = MultiPartParser(
META=meta, input_data=BytesIO(body),
upload_handlers=[handler])
return parser.parse()
def parse_headers_and_body_with_mimer(headers, body):
"""Use piston's Mimer functionality to handle the content.
:return: The value of 'request.data' after using Piston's translate_mime on
the input.
"""
# JAM 2012-10-09 Importing emitters has a side effect of registering mime
# type handlers with utils.translate_mime. So we must import it, even
# though we don't use it. However, piston loads Django's QuerySet code
# which fails if you don't have a settings.py available. Which we don't
# during 'test.pserv'. So we import this late.
from piston import emitters
ignore_unused(emitters)
from piston.utils import translate_mime
environ = {'wsgi.input': BytesIO(body)}
for name, value in headers.items():
environ[name.upper().replace('-', '_')] = value
environ['REQUEST_METHOD'] = 'POST'
environ['SCRIPT_NAME'] = ''
environ['PATH_INFO'] = ''
# Django 1.6 needs DJANGO_SETTINGS_MODULE to be defined
# when importing WSGIRequest.
os.environ['DJANGO_SETTINGS_MODULE'] = 'maas.development'
from django.core.handlers.wsgi import WSGIRequest
request = WSGIRequest(environ)
translate_mime(request)
return request.data