Permalink
Browse files

parser: HTTP_STATUS_MAP(XX) and enum http_status

This patch provides an enum for the standardized HTTP status codes.
Additionally, the HTTP_STATUS_MAP(XX) can be used for other purposes as
well, such as code-to-name lookups and code-based switch statements.

PR-URL: #337
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent feae95a commit 335850f6b868d3411968cbf5a4d59fe619dee36f @npmccallum npmccallum committed with indutny Oct 6, 2016
Showing with 70 additions and 0 deletions.
  1. +70 −0 http_parser.h
View
@@ -90,6 +90,76 @@ typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
+/* Status Codes */
+#define HTTP_STATUS_MAP(XX) \
+ XX(100, CONTINUE, Continue) \
+ XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
+ XX(102, PROCESSING, Processing) \
+ XX(200, OK, OK) \
+ XX(201, CREATED, Created) \
+ XX(202, ACCEPTED, Accepted) \
+ XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
+ XX(204, NO_CONTENT, No Content) \
+ XX(205, RESET_CONTENT, Reset Content) \
+ XX(206, PARTIAL_CONTENT, Partial Content) \
+ XX(207, MULTI_STATUS, Multi-Status) \
+ XX(208, ALREADY_REPORTED, Already Reported) \
+ XX(226, IM_USED, IM Used) \
+ XX(300, MULTIPLE_CHOICES, Multiple Choices) \
+ XX(301, MOVED_PERMANENTLY, Moved Permanently) \
+ XX(302, FOUND, Found) \
+ XX(303, SEE_OTHER, See Other) \
+ XX(304, NOT_MODIFIED, Not Modified) \
+ XX(305, USE_PROXY, Use Proxy) \
+ XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
+ XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
+ XX(400, BAD_REQUEST, Bad Request) \
+ XX(401, UNAUTHORIZED, Unauthorized) \
+ XX(402, PAYMENT_REQUIRED, Payment Required) \
+ XX(403, FORBIDDEN, Forbidden) \
+ XX(404, NOT_FOUND, Not Found) \
+ XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
+ XX(406, NOT_ACCEPTABLE, Not Acceptable) \
+ XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
+ XX(408, REQUEST_TIMEOUT, Request Timeout) \
+ XX(409, CONFLICT, Conflict) \
+ XX(410, GONE, Gone) \
+ XX(411, LENGTH_REQUIRED, Length Required) \
+ XX(412, PRECONDITION_FAILED, Precondition Failed) \
+ XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
+ XX(414, URI_TOO_LONG, URI Too Long) \
+ XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
+ XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
+ XX(417, EXPECTATION_FAILED, Expectation Failed) \
+ XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
+ XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
+ XX(423, LOCKED, Locked) \
+ XX(424, FAILED_DEPENDENCY, Failed Dependency) \
+ XX(426, UPGRADE_REQUIRED, Upgrade Required) \
+ XX(428, PRECONDITION_REQUIRED, Precondition Required) \
+ XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
+ XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
+ XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
+ XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
+ XX(501, NOT_IMPLEMENTED, Not Implemented) \
+ XX(502, BAD_GATEWAY, Bad Gateway) \
+ XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
+ XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
+ XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
+ XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
+ XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
+ XX(508, LOOP_DETECTED, Loop Detected) \
+ XX(510, NOT_EXTENDED, Not Extended) \
+ XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
+
+enum http_status
+ {
+#define XX(num, name, string) HTTP_STATUS_##name = num,
+ HTTP_STATUS_MAP(XX)
+#undef XX
+ };
+
+
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \

6 comments on commit 335850f

@AaronCAlbers

Perhaps this function should be added as well?

const char *
http_status_str (enum http_status s)
{
  switch (s) {
#define XX(num, name, string) case num : return #string;
      HTTP_STATUS_MAP(XX)
#undef XX
  }
  return "<unknown>";
}

It compliments the http_method_str() function and I find it most useful.

@indutny
Member

@AaronCAlbers possibly

@npmccallum
Contributor
npmccallum commented on 335850f Oct 25, 2016 edited

@AaronCAlbers, some compilers will complain about the lack of a default. This version will avoid that problem:

const char *
http_status_str (enum http_status s)
{
  switch (s) {
#define XX(num, name, string) case num : return #string;
      HTTP_STATUS_MAP(XX)
#undef XX
      default: return "<unknown>";
  }
}

There is also the question of being able to detect an error condition: should you return "<unknown>" or NULL?

I suspect that since the consumer of this API has all the tools to make this same function, that the consumer should implement it based on the properties they need.

@AaronCAlbers

@npmccallum, the same could be said about http_method_str(). Where do we draw the line? I think a default implementation makes the library balanced. As you said all the tools are readily available (as long as you know how to use them) to build your own if the consumer needs a custom method.

@npmccallum
Contributor

Well, I think we draw the line at having more complexity than a single switch statement. :) But I don't really have a strong opinion. I just know that some people will want "<unknown>" and some people will want NULL.

@AaronCAlbers

@npmccallum, If we were to choose we would want to make it consistent with http_method_str() which currently returns "<unknown>" when an unknown enum http_method is encountered.

Please sign in to comment.