Open-Source Wikis

/

Django

/

Systems

/

HTTP

django/django

HTTP

The HTTP layer is split between django/http/ (request and response objects) and django/core/handlers/ (the WSGI/ASGI gateways that bridge a server's protocol to Django's request lifecycle).

Purpose

Translate the network-side representation (a WSGI environ dict, an ASGI scope dict, a chunked stream of bytes) into a Python object Django can dispatch on, run it through middleware and a view, and translate the resulting HttpResponse back into bytes the server can transmit. The layer is protocol-aware enough to handle multipart parsing, streaming responses, file uploads, range requests, and WebSocket-adjacent ASGI semantics.

Directory layout

django/http/
├── __init__.py
├── cookie.py                 # SimpleCookie wrapper
├── multipartparser.py        # streaming multipart/form-data parser
├── request.py                # HttpRequest, QueryDict
└── response.py               # HttpResponse, StreamingHttpResponse, FileResponse, JsonResponse

django/core/handlers/
├── __init__.py
├── base.py                   # BaseHandler: middleware compilation, get_response()
├── wsgi.py                   # WSGIHandler, WSGIRequest
├── asgi.py                   # ASGIHandler, ASGIRequest
└── exception.py              # convert_exception_to_response, response_for_exception

Key abstractions

Type File Role
HttpRequest django/http/request.py The base request; subclassed for WSGI/ASGI
QueryDict django/http/request.py Multi-valued mutable mapping for GET/POST data
MultiPartParser django/http/multipartparser.py Streaming parser for multipart/form-data
HttpResponse django/http/response.py Standard response with content, headers, cookies
StreamingHttpResponse django/http/response.py Iterator-based response for large/long-lived bodies
FileResponse django/http/response.py Serves a file-like object; supports range requests
JsonResponse django/http/response.py Pre-encoded application/json response
HttpResponseRedirect, HttpResponseNotFound, … django/http/response.py Status-code-specific subclasses
BaseHandler django/core/handlers/base.py Middleware compilation and request dispatch
WSGIHandler django/core/handlers/wsgi.py WSGI gateway
ASGIHandler django/core/handlers/asgi.py ASGI gateway

How it works

sequenceDiagram
    participant Server as gunicorn / uvicorn
    participant Handler as WSGIHandler / ASGIHandler
    participant Request as HttpRequest
    participant MW as middleware chain
    participant View

    Server->>Handler: environ / scope + receive
    Handler->>Request: build (lazy body, lazy POST)
    Handler->>Handler: compile middleware (cached)
    Handler->>MW: get_response(request)
    MW->>View: view(request, ...)
    View-->>MW: HttpResponse
    MW-->>Handler: HttpResponse
    Handler->>Server: status, headers, body

HttpRequest

HttpRequest exposes:

  • method, path, path_info, META (WSGI environ).
  • GET, POST, FILES, COOKIESQueryDict instances.
  • body (lazy, raw bytes), body_size.
  • scheme, is_secure, get_host(), get_full_path(), build_absolute_uri().
  • user, session — set by AuthenticationMiddleware and SessionMiddleware.
  • resolver_match — populated by the URL resolver after routing.
  • Async cousins: arequest.body is implicitly available; aread() for streaming reads.

QueryDict is the multi-valued dict used for GET/POST and parsed query strings. MultiPartParser populates POST and FILES lazily — the parser only runs when one of those attributes is first accessed.

HttpResponse and friends

The response classes have a small inheritance hierarchy:

HttpResponseBase
├── HttpResponse              # bytes content, set in __init__
└── StreamingHttpResponse     # iterator-based content
    └── FileResponse          # adds Range support, streams from a file-like

HttpResponse mostly stores headers, cookies, and a content buffer. StreamingHttpResponse exposes streaming_content — an iterator that the server consumes lazily. FileResponse adds:

  • Automatic Content-Type sniffing (via mimetypes).
  • Content-Disposition for downloadable files.
  • Range request support (HTTP/1.1 206 Partial Content).
  • Async iteration when needed.

BaseHandler

BaseHandler compiles the middleware chain once at startup. The compilation:

  1. Iterates MIDDLEWARE in reverse (innermost-first).
  2. For each entry, imports the middleware factory, instantiates it with the next-in-chain callable as get_response, and stores the resulting middleware instance.
  3. Determines whether the chain is fully sync, fully async, or mixed (async-capable). The result determines whether get_response() runs sync or hops via async_to_sync.

load_middleware() caches _middleware_chain for the life of the handler. Per-request, get_response() simply calls the chain.

WSGI

WSGIHandler.__call__(environ, start_response) is the WSGI entry point. It:

  1. Builds a WSGIRequest from environ.
  2. Calls self.get_response(request).
  3. Converts the response into (status, headers) and returns the body iterator.

Synchronous-only middleware that doesn't have an async path is wrapped via sync_to_async if a request comes through ASGI; for WSGI the path is straightforward.

ASGI

ASGIHandler.__call__(scope, receive, send) is the ASGI entry point. It:

  1. Validates that scope["type"] == "http" (websocket and lifespan are not handled here — use a separate ASGI app or channels).
  2. Builds an ASGIRequest. The body is read lazily via receive().
  3. Calls await self.get_response_async(request).
  4. Sends http.response.start and http.response.body events.

The async path closely mirrors the sync one. Async-only middleware sees the request directly; sync-only middleware is bridged via async_to_sync.

Exception handling

django/core/handlers/exception.py provides convert_exception_to_response, a decorator wrapped around the inner middleware chain. It converts any uncaught exception to an HttpResponse:

  • Http404 → 404 page (via views.defaults.page_not_found).
  • PermissionDenied → 403.
  • MultiPartParserError, SuspiciousOperation → 400.
  • Anything else → 500 (with the technical 500 page in DEBUG, plain 500 page in production).

The exception handlers can be customised via the handler400/handler403/handler404/handler500 URLconf hooks.

Multipart parsing

MultiPartParser is a streaming parser. It consumes the request body in chunks, dispatches form fields and file uploads to handlers, and never holds the whole body in memory. File handlers (MemoryFileUploadHandler, TemporaryFileUploadHandler, defined in django/core/files/uploadhandler.py) decide where the data lands — small files go in memory, large ones spill to disk.

The default upload handlers are configured via FILE_UPLOAD_HANDLERS. Settings like DATA_UPLOAD_MAX_MEMORY_SIZE and FILE_UPLOAD_MAX_MEMORY_SIZE cap behaviour to defend against DoS via huge uploads.

Integration points

  • Middleware (middleware) — wraps the response cycle, depends on HttpRequest/HttpResponse shapes.
  • URL routing (urls) — middleware calls resolve(request.path_info); the resolver attaches a ResolverMatch to the request.
  • Views (views) — receive the request, return a response.
  • Authentication (contrib, auth) — AuthenticationMiddleware populates request.user.
  • Sessions (contrib/sessions) — populate request.session.
  • Templates (templates) — render(request, ...) shorthand uses HttpResponse.

Entry points for modification

  • Custom request attribute: add to WSGIRequest/ASGIRequest, or write a middleware that sets it.
  • New response type: subclass HttpResponseBase or StreamingHttpResponse.
  • File upload handler: subclass FileUploadHandler in django/core/files/uploadhandler.py.
  • Custom multipart behavior: rare; subclass MultiPartParser or replace parse_file_upload.

Key source files

File Purpose
django/http/request.py HttpRequest, QueryDict
django/http/response.py HttpResponse, StreamingHttpResponse, FileResponse, JsonResponse
django/http/multipartparser.py Streaming multipart parser
django/http/cookie.py SimpleCookie wrapper
django/core/handlers/base.py BaseHandler, middleware compilation
django/core/handlers/wsgi.py WSGI gateway
django/core/handlers/asgi.py ASGI gateway
django/core/handlers/exception.py Exception → response conversion
django/core/files/uploadhandler.py File upload handlers

Where to read tests

  • tests/requests/, tests/test_client/ — request and client behaviour.
  • tests/responses/ — response classes.
  • tests/file_uploads/ — multipart parsing and upload handlers.
  • tests/asgi/, tests/handlers/ — handler behaviour.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

HTTP – Django wiki | Factory