diff --git a/include/libcgi/cgi.h b/include/libcgi/cgi.h index e3eda36..0e5679e 100644 --- a/include/libcgi/cgi.h +++ b/include/libcgi/cgi.h @@ -34,6 +34,58 @@ #define CGI_DEPRECATED #endif +/** + * HTTP status codes. + * + * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + */ +enum cgi_http_status_code { + HTTP_STATUS_CONTINUE = 100, + HTTP_STATUS_SWITCHING_PROTOCOLS = 101, + + HTTP_STATUS_OK = 200, + HTTP_STATUS_CREATED = 201, + HTTP_STATUS_ACCEPTED = 202, + HTTP_STATUS_NON_AUTH_INFO = 203, + HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_RESET_CONTENT = 205, + HTTP_STATUS_PARTIAL_CONTENT = 206, + + HTTP_STATUS_MULTIPLE_CHOICES = 300, + HTTP_STATUS_MOVED_PERMANENTLY = 301, + HTTP_STATUS_FOUND = 302, + HTTP_STATUS_SEE_OTHER = 303, + HTTP_STATUS_NOT_MODIFIED = 304, + HTTP_STATUS_USE_PROXY = 305, + HTTP_STATUS_TEMPORARY_REDIRECT = 307, + + HTTP_STATUS_BAD_REQUEST = 400, + HTTP_STATUS_UNAUTHORIZED = 401, + HTTP_STATUS_PAYMENT_REQUIRED = 402, + HTTP_STATUS_FORBIDDEN = 403, + HTTP_STATUS_NOT_FOUND = 404, + HTTP_STATUS_METHOD_NOT_ALLOWED = 405, + HTTP_STATUS_NOT_ACCEPTABLE = 406, + HTTP_STATUS_PROXY_AUTH_REQUIRED = 407, + HTTP_STATUS_REQUEST_TIMEOUT = 408, + HTTP_STATUS_CONFLICT = 409, + HTTP_STATUS_GONE = 410, + HTTP_STATUS_LENGTH_REQUIRED = 411, + HTTP_STATUS_PRECONDITION_FAILED = 412, + HTTP_STATUS_REQ_ENT_TOO_LARGE = 413, + HTTP_STATUS_REQ_URI_TOO_LONG = 414, + HTTP_STATUS_UNSUPP_MEDIA_TYPE = 415, + HTTP_STATUS_REQ_RANGE_NOT_SATIS = 416, + HTTP_STATUS_EXPECTATION_FAILED = 417, + + HTTP_STATUS_INTERNAL_SERVER_ERR = 500, + HTTP_STATUS_NOT_IMPLEMENTED = 501, + HTTP_STATUS_BAD_GATEWAY = 502, + HTTP_STATUS_SERVICE_UNAVAILABLE = 503, + HTTP_STATUS_GATEWAY_TIMEOUT = 504, + HTTP_STATUS_HTTP_VER_NOT_SUPP = 505, +}; + #ifdef __cplusplus extern "C" { #endif @@ -57,7 +109,7 @@ extern int cgi_display_errors; // General purpose cgi functions extern void cgi_init_headers(void); -extern void cgi_redirect(char *url); +CGI_DEPRECATED void cgi_redirect(char *url); extern void cgi_fatal(const char *error); extern char *cgi_unescape_special_chars(const char *str); extern char *cgi_escape_special_chars(const char *str); @@ -143,6 +195,20 @@ void cgi_session_free( void ); */ const char *cgi_version( void ); +/** + * Send a HTTP header 'Location:' with the uri provided together with a + * pseudo header 'Status:' with some HTTP status code. See RFC 3875, + * section 6.3 (Response Header Fields) for details on how this is + * supposed to work. + * + * @see https://tools.ietf.org/html/rfc3875#section-6.3 + * + * @param[in] status_code HTTP status code number, pick it from our enum type + * @param[in] uri URI to be sent with the Location: header + */ +void cgi_redirect_status( enum cgi_http_status_code status_code, + const char *uri ); + #ifdef __cplusplus } #endif diff --git a/src/cgi.c b/src/cgi.c index 2fadbbe..13f993e 100644 --- a/src/cgi.c +++ b/src/cgi.c @@ -560,6 +560,22 @@ const char *cgi_version( void ) return CGI_VERSION; } +void cgi_redirect_status( enum cgi_http_status_code status_code, + const char *uri ) +{ + if ( headers_initialized ) + { + libcgi_error( E_WARNING, + "
Cannot redirect. Headers already sent
" ); + return; + } + + printf( "Status: %i\r\n" + "Location: %s\r\n" + "\r\n", + status_code, uri ); +} + /** * @} */