aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework/response.py
diff options
context:
space:
mode:
Diffstat (limited to 'djangorestframework/response.py')
-rw-r--r--djangorestframework/response.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/djangorestframework/response.py b/djangorestframework/response.py
new file mode 100644
index 00000000..4f23bb0a
--- /dev/null
+++ b/djangorestframework/response.py
@@ -0,0 +1,125 @@
+from django.core.handlers.wsgi import STATUS_CODE_TEXT
+
+__all__ =['status', 'NoContent', 'Response', ]
+
+
+class Status(object):
+ """Descriptive HTTP status codes, for code readability.
+ See RFC 2616 - Sec 10: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"""
+
+ # Verbose format (I prefer this as it's more explicit)
+ HTTP_100_CONTINUE = 100
+ HTTP_101_SWITCHING_PROTOCOLS = 101
+ HTTP_200_OK = 200
+ HTTP_201_CREATED = 201
+ HTTP_202_ACCEPTED = 202
+ HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
+ HTTP_204_NO_CONTENT = 204
+ HTTP_205_RESET_CONTENT = 205
+ HTTP_206_PARTIAL_CONTENT = 206
+ HTTP_300_MULTIPLE_CHOICES = 300
+ HTTP_301_MOVED_PERMANENTLY = 301
+ HTTP_302_FOUND = 302
+ HTTP_303_SEE_OTHER = 303
+ HTTP_304_NOT_MODIFIED = 304
+ HTTP_305_USE_PROXY = 305
+ HTTP_306_RESERVED = 306
+ HTTP_307_TEMPORARY_REDIRECT = 307
+ HTTP_400_BAD_REQUEST = 400
+ HTTP_401_UNAUTHORIZED = 401
+ HTTP_402_PAYMENT_REQUIRED = 402
+ HTTP_403_FORBIDDEN = 403
+ HTTP_404_NOT_FOUND = 404
+ HTTP_405_METHOD_NOT_ALLOWED = 405
+ HTTP_406_NOT_ACCEPTABLE = 406
+ HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
+ HTTP_408_REQUEST_TIMEOUT = 408
+ HTTP_409_CONFLICT = 409
+ HTTP_410_GONE = 410
+ HTTP_411_LENGTH_REQUIRED = 411
+ HTTP_412_PRECONDITION_FAILED = 412
+ HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
+ HTTP_414_REQUEST_URI_TOO_LONG = 414
+ HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
+ HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
+ HTTP_417_EXPECTATION_FAILED = 417
+ HTTP_500_INTERNAL_SERVER_ERROR = 500
+ HTTP_501_NOT_IMPLEMENTED = 501
+ HTTP_502_BAD_GATEWAY = 502
+ HTTP_503_SERVICE_UNAVAILABLE = 503
+ HTTP_504_GATEWAY_TIMEOUT = 504
+ HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
+
+ # Short format
+ CONTINUE = 100
+ SWITCHING_PROTOCOLS = 101
+ OK = 200
+ CREATED = 201
+ ACCEPTED = 202
+ NON_AUTHORITATIVE_INFORMATION = 203
+ NO_CONTENT = 204
+ RESET_CONTENT = 205
+ PARTIAL_CONTENT = 206
+ MULTIPLE_CHOICES = 300
+ MOVED_PERMANENTLY = 301
+ FOUND = 302
+ SEE_OTHER = 303
+ NOT_MODIFIED = 304
+ USE_PROXY = 305
+ RESERVED = 306
+ TEMPORARY_REDIRECT = 307
+ BAD_REQUEST = 400
+ UNAUTHORIZED = 401
+ PAYMENT_REQUIRED = 402
+ FORBIDDEN = 403
+ NOT_FOUND = 404
+ METHOD_NOT_ALLOWED = 405
+ NOT_ACCEPTABLE = 406
+ PROXY_AUTHENTICATION_REQUIRED = 407
+ REQUEST_TIMEOUT = 408
+ CONFLICT = 409
+ GONE = 410
+ LENGTH_REQUIRED = 411
+ PRECONDITION_FAILED = 412
+ REQUEST_ENTITY_TOO_LARGE = 413
+ REQUEST_URI_TOO_LONG = 414
+ UNSUPPORTED_MEDIA_TYPE = 415
+ REQUESTED_RANGE_NOT_SATISFIABLE = 416
+ EXPECTATION_FAILED = 417
+ INTERNAL_SERVER_ERROR = 500
+ NOT_IMPLEMENTED = 501
+ BAD_GATEWAY = 502
+ SERVICE_UNAVAILABLE = 503
+ GATEWAY_TIMEOUT = 504
+ HTTP_VERSION_NOT_SUPPORTED = 505
+
+
+
+# This is simply stylistic, I think 'status.HTTP_200_OK' reads nicely.
+status = Status()
+
+
+class NoContent(object):
+ """Used to indicate no body in http response.
+ (We cannot just use None, as that is a valid, serializable response object.)"""
+ pass
+
+
+class Response(object):
+ def __init__(self, status, content=NoContent, headers={}):
+ self.status = status
+ self.has_content_body = not content is NoContent
+ self.raw_content = content # content prior to filtering
+ self.cleaned_content = content # content after filtering
+ self.headers = headers
+
+ @property
+ def status_text(self):
+ """Return reason text corrosponding to our HTTP response status code.
+ Provided for convienience."""
+ return STATUS_CODE_TEXT.get(self.status, '')
+
+
+class ResponseException(BaseException):
+ def __init__(self, status, content=NoContent, headers={}):
+ self.response = Response(status, content=content, headers=headers)