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 );
+}
+
/**
* @}
*/