
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <nginx.h>


static char error_tail[] =
"<hr><center>" NGINX_VER "</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;


static char msie_stub[] =
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
;


static char error_301_page[] =
"<html>" CRLF
"<head><title>301 Moved Permanently</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>301 Moved Permanently</h1></center>" CRLF
;


static char error_302_page[] =
"<html>" CRLF
"<head><title>302 Found</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>302 Found</h1></center>" CRLF
;


static char error_400_page[] =
"<html>" CRLF
"<head><title>400 Bad Request</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
;


static char error_403_page[] =
"<html>" CRLF
"<head><title>403 Forbidden</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>403 Forbidden</h1></center>" CRLF
;


static char error_404_page[] =
"<html>" CRLF
"<head><title>404 Not Found</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>404 Not Found</h1></center>" CRLF
;


static char error_405_page[] =
"<html>" CRLF
"<head><title>405 Not Allowed</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>405 Not Allowed</h1></center>" CRLF
;


static char error_408_page[] =
"<html>" CRLF
"<head><title>408 Request Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>408 Request Time-out</h1></center>" CRLF
;


static char error_413_page[] =
"<html>" CRLF
"<head><title>413 Request Entity Too Large</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>413 Request Entity Too Large</h1></center>" CRLF
;


static char error_414_page[] =
"<html>" CRLF
"<head><title>414 Request-URI Too Large</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>414 Request-URI Too Large</h1></center>" CRLF
;


static char error_416_page[] =
"<html>" CRLF
"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF
;


static char error_500_page[] =
"<html>" CRLF
"<head><title>500 Internal Server Error</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>500 Internal Server Error</h1></center>" CRLF
;


static char error_502_page[] =
"<html>" CRLF
"<head><title>502 Bad Gateway</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>502 Bad Gateway</h1></center>" CRLF
;


static char error_503_page[] =
"<html>" CRLF
"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF
;


static char error_504_page[] =
"<html>" CRLF
"<head><title>504 Gateway Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>504 Gateway Time-out</h1></center>" CRLF
;


static ngx_str_t error_pages[] = {
 /* ngx_null_string, */          /* 300 */
    ngx_string(error_301_page),
    ngx_string(error_302_page),
    ngx_null_string,             /* 303 */

    ngx_string(error_400_page),
    ngx_null_string,             /* 401 */
    ngx_null_string,             /* 402 */
    ngx_string(error_403_page),
    ngx_string(error_404_page),
    ngx_string(error_405_page),
    ngx_null_string,             /* 406 */
    ngx_null_string,             /* 407 */
    ngx_string(error_408_page),
    ngx_null_string,             /* 409 */
    ngx_null_string,             /* 410 */
    ngx_null_string,             /* 411 */
    ngx_null_string,             /* 412 */
    ngx_string(error_413_page),
    ngx_string(error_414_page),
    ngx_null_string,             /* 415 */
    ngx_string(error_416_page),

    ngx_string(error_500_page),
    ngx_null_string,             /* 501 */
    ngx_string(error_502_page),
    ngx_string(error_503_page),
    ngx_string(error_504_page)
};


int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
{
    int                        err, rc;
    ngx_hunk_t                *h;
    ngx_chain_t               *out, **ll, *cl;
    ngx_http_core_loc_conf_t  *clcf;

    rc = ngx_http_discard_body(r);

    if (rc != NGX_OK) {
        return rc;
    }

    r->headers_out.status = error;

    if (error < NGX_HTTP_BAD_REQUEST) {
        /* 3XX */
        err = error - NGX_HTTP_MOVED_PERMANENTLY;

    } else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR) {
        /* 4XX */
        err = error - NGX_HTTP_BAD_REQUEST + 3;

    } else {
        /* 5XX */
        err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 3 + 17;
    }

    if (r->keepalive != 0) {
        switch (error) {
            case NGX_HTTP_BAD_REQUEST:
            case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE:
            case NGX_HTTP_REQUEST_URI_TOO_LARGE:
            case NGX_HTTP_INTERNAL_SERVER_ERROR:
                r->keepalive = 0;
        }
    }

    if (r->lingering_close == 1) {
        switch (error) {
            case NGX_HTTP_BAD_REQUEST:
            case NGX_HTTP_REQUEST_URI_TOO_LARGE:
            case NGX_HTTP_INTERNAL_SERVER_ERROR:
                r->lingering_close = 0;
        }
    }

    if (error_pages[err].len) {
        r->headers_out.content_length_n = error_pages[err].len
                                          + sizeof(error_tail) - 1
                                          + sizeof(msie_stub) - 1;

        ngx_test_null(r->headers_out.content_type,
                      ngx_push_table(r->headers_out.headers),
                      NGX_HTTP_INTERNAL_SERVER_ERROR);

        r->headers_out.content_type->key.len = 12;
        r->headers_out.content_type->key.data = "Content-Type";
        r->headers_out.content_type->value.len = 9;
        r->headers_out.content_type->value.data = "text/html";

    } else {
        r->headers_out.content_length_n = -1;
        r->headers_out.content_length = NULL;
    }

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || r->header_only) {
        return rc;
    }

    if (error_pages[err].len == 0) {
        return NGX_OK;
    }

    out = NULL;
    ll = NULL;

    ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
    h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
    h->pos = error_pages[err].data;
    h->last = error_pages[err].data + error_pages[err].len;

    ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
    ngx_chain_add_link(out, ll, cl);


    ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
    h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
    h->pos = error_tail;
    h->last = error_tail + sizeof(error_tail) - 1;

    ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
    ngx_chain_add_link(out, ll, cl);

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    if (clcf->msie_padding
        && r->http_version >= NGX_HTTP_VERSION_10
        && error >= NGX_HTTP_BAD_REQUEST
        && error != NGX_HTTP_REQUEST_URI_TOO_LARGE
       )
    {
        ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
        h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
        h->pos = msie_stub;
        h->last = msie_stub + sizeof(msie_stub) - 1;

        ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
        ngx_chain_add_link(out, ll, cl);
    }

    h->type |= NGX_HUNK_LAST;

    return ngx_http_output_filter(r, out);
}
