static ngx_buf_t *
ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries)
{
    u_char                         *last, scale;
    off_t                           length;
    size_t                          len, char_len, escape_html;
    ngx_tm_t                        tm;
    ngx_buf_t                      *b;
    ngx_int_t                       size;
    ngx_uint_t                      i, utf8;
    ngx_time_t                     *tp;
    ngx_http_autoindex_entry_t     *entry;
    ngx_http_autoindex_loc_conf_t  *alcf;
    static u_char  title[] =
        "<html>" CRLF
        "<head><title>Index of "
    ;
    static u_char  header[] =
        "</title></head>" CRLF
        "<body>" CRLF
        "<h1>Index of "
    ;
    static u_char  tail[] =
        "</body>" CRLF
        "</html>" CRLF
    ;
    static char  *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    if (r->headers_out.charset.len == 5
        && ngx_strncasecmp(r->headers_out.charset.data, (u_char *) "utf-8", 5)
           == 0)
    {
        utf8 = 1;
    } else {
        utf8 = 0;
    }
    escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);
    len = sizeof(title) - 1
          + r->uri.len + escape_html
          + sizeof(header) - 1
          + r->uri.len + escape_html
          + sizeof("</h1>") - 1
          + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1
          + sizeof("</pre><hr>") - 1
          + sizeof(tail) - 1;
    entry = entries->elts;
    for (i = 0; i < entries->nelts; i++) {
        entry[i].escape = 2 * ngx_escape_uri(NULL, entry[i].name.data,
                                             entry[i].name.len,
                                             NGX_ESCAPE_URI_COMPONENT);
        entry[i].escape_html = ngx_escape_html(NULL, entry[i].name.data,
                                               entry[i].name.len);
        if (utf8) {
            entry[i].utf_len = ngx_utf8_length(entry[i].name.data,
                                               entry[i].name.len);
        } else {
            entry[i].utf_len = entry[i].name.len;
        }
        len += sizeof("<a href=\"") - 1
            + entry[i].name.len + entry[i].escape
            + 1
            + sizeof("\">") - 1
            + entry[i].name.len - entry[i].utf_len
            + entry[i].escape_html
            + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
            + sizeof("</a>") - 1
            + sizeof(" 28-Sep-1970 12:00 ") - 1
            + 20
            + 2;
    }
    b = ngx_create_temp_buf(r->pool, len);
    if (b == NULL) {
        return NULL;
    }
    b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
    if (escape_html) {
        b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
        b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
        b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
    } else {
        b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
        b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
        b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
    }
    b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);
    b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF,
                         sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1);
    alcf = ngx_http_get_module_loc_conf(r, ngx_http_autoindex_module);
    tp = ngx_timeofday();
    for (i = 0; i < entries->nelts; i++) {
        b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1);
        if (entry[i].escape) {
            ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
                           NGX_ESCAPE_URI_COMPONENT);
            b->last += entry[i].name.len + entry[i].escape;
        } else {
            b->last = ngx_cpymem(b->last, entry[i].name.data,
                                 entry[i].name.len);
        }
        if (entry[i].dir) {
            *b->last++ = '/';
        }
        *b->last++ = '"';
        *b->last++ = '>';
        len = entry[i].utf_len;
        if (entry[i].name.len != len) {
            if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
            } else {
                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
            }
            last = b->last;
            b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
                                       char_len, entry[i].name.len + 1);
            if (entry[i].escape_html) {
                b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
                                                     b->last - last);
            }
            last = b->last;
        } else {
            if (entry[i].escape_html) {
                if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
                    char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
                } else {
                    char_len = len;
                }
                b->last = (u_char *) ngx_escape_html(b->last,
                                                  entry[i].name.data, char_len);
                last = b->last;
            } else {
                b->last = ngx_cpystrn(b->last, entry[i].name.data,
                                      NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
                last = b->last - 3;
            }
        }
        if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
            b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1);
        } else {
            if (entry[i].dir && NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
                *b->last++ = '/';
                len++;
            }
            b->last = ngx_cpymem(b->last, "</a>", sizeof("</a>") - 1);
            if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
                ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
                b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
            }
        }
        *b->last++ = ' ';
        ngx_gmtime(entry[i].mtime + tp->gmtoff * 60 * alcf->localtime, &tm);
        b->last = ngx_sprintf(b->last, "%02d-%s-%d %02d:%02d ",
                              tm.ngx_tm_mday,
                              months[tm.ngx_tm_mon - 1],
                              tm.ngx_tm_year,
                              tm.ngx_tm_hour,
                              tm.ngx_tm_min);
        if (alcf->exact_size) {
            if (entry[i].dir) {
                b->last = ngx_cpymem(b->last,  "                  -",
                                     sizeof("                  -") - 1);
            } else {
                b->last = ngx_sprintf(b->last, "%19O", entry[i].size);
            }
        } else {
            if (entry[i].dir) {
                b->last = ngx_cpymem(b->last,  "      -",
                                     sizeof("      -") - 1);
            } else {
                length = entry[i].size;
                if (length > 1024 * 1024 * 1024 - 1) {
                    size = (ngx_int_t) (length / (1024 * 1024 * 1024));
                    if ((length % (1024 * 1024 * 1024))
                                                > (1024 * 1024 * 1024 / 2 - 1))
                    {
                        size++;
                    }
                    scale = 'G';
                } else if (length > 1024 * 1024 - 1) {
                    size = (ngx_int_t) (length / (1024 * 1024));
                    if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) {
                        size++;
                    }
                    scale = 'M';
                } else if (length > 9999) {
                    size = (ngx_int_t) (length / 1024);
                    if (length % 1024 > 511) {
                        size++;
                    }
                    scale = 'K';
                } else {
                    size = (ngx_int_t) length;
                    scale = '\0';
                }
                if (scale) {
                    b->last = ngx_sprintf(b->last, "%6i%c", size, scale);
                } else {
                    b->last = ngx_sprintf(b->last, " %6i", size);
                }
            }
        }
        *b->last++ = CR;
        *b->last++ = LF;
    }
    b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
    b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);
    return b;
}
['static ngx_buf_t *\nngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries)\n{\n    u_char                         *last, scale;\n    off_t                           length;\n    size_t                          len, char_len, escape_html;\n    ngx_tm_t                        tm;\n    ngx_buf_t                      *b;\n    ngx_int_t                       size;\n    ngx_uint_t                      i, utf8;\n    ngx_time_t                     *tp;\n    ngx_http_autoindex_entry_t     *entry;\n    ngx_http_autoindex_loc_conf_t  *alcf;\n    static u_char  title[] =\n        "<html>" CRLF\n        "<head><title>Index of "\n    ;\n    static u_char  header[] =\n        "</title></head>" CRLF\n        "<body>" CRLF\n        "<h1>Index of "\n    ;\n    static u_char  tail[] =\n        "</body>" CRLF\n        "</html>" CRLF\n    ;\n    static char  *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",\n                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };\n    if (r->headers_out.charset.len == 5\n        && ngx_strncasecmp(r->headers_out.charset.data, (u_char *) "utf-8", 5)\n           == 0)\n    {\n        utf8 = 1;\n    } else {\n        utf8 = 0;\n    }\n    escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);\n    len = sizeof(title) - 1\n          + r->uri.len + escape_html\n          + sizeof(header) - 1\n          + r->uri.len + escape_html\n          + sizeof("</h1>") - 1\n          + sizeof("<hr><pre><a href=\\"../\\">../</a>" CRLF) - 1\n          + sizeof("</pre><hr>") - 1\n          + sizeof(tail) - 1;\n    entry = entries->elts;\n    for (i = 0; i < entries->nelts; i++) {\n        entry[i].escape = 2 * ngx_escape_uri(NULL, entry[i].name.data,\n                                             entry[i].name.len,\n                                             NGX_ESCAPE_URI_COMPONENT);\n        entry[i].escape_html = ngx_escape_html(NULL, entry[i].name.data,\n                                               entry[i].name.len);\n        if (utf8) {\n            entry[i].utf_len = ngx_utf8_length(entry[i].name.data,\n                                               entry[i].name.len);\n        } else {\n            entry[i].utf_len = entry[i].name.len;\n        }\n        len += sizeof("<a href=\\"") - 1\n            + entry[i].name.len + entry[i].escape\n            + 1\n            + sizeof("\\">") - 1\n            + entry[i].name.len - entry[i].utf_len\n            + entry[i].escape_html\n            + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2\n            + sizeof("</a>") - 1\n            + sizeof(" 28-Sep-1970 12:00 ") - 1\n            + 20\n            + 2;\n    }\n    b = ngx_create_temp_buf(r->pool, len);\n    if (b == NULL) {\n        return NULL;\n    }\n    b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);\n    if (escape_html) {\n        b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);\n        b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);\n        b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);\n    } else {\n        b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);\n        b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);\n        b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);\n    }\n    b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);\n    b->last = ngx_cpymem(b->last, "<hr><pre><a href=\\"../\\">../</a>" CRLF,\n                         sizeof("<hr><pre><a href=\\"../\\">../</a>" CRLF) - 1);\n    alcf = ngx_http_get_module_loc_conf(r, ngx_http_autoindex_module);\n    tp = ngx_timeofday();\n    for (i = 0; i < entries->nelts; i++) {\n        b->last = ngx_cpymem(b->last, "<a href=\\"", sizeof("<a href=\\"") - 1);\n        if (entry[i].escape) {\n            ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,\n                           NGX_ESCAPE_URI_COMPONENT);\n            b->last += entry[i].name.len + entry[i].escape;\n        } else {\n            b->last = ngx_cpymem(b->last, entry[i].name.data,\n                                 entry[i].name.len);\n        }\n        if (entry[i].dir) {\n            *b->last++ = \'/\';\n        }\n        *b->last++ = \'"\';\n        *b->last++ = \'>\';\n        len = entry[i].utf_len;\n        if (entry[i].name.len != len) {\n            if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {\n                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;\n            } else {\n                char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;\n            }\n            last = b->last;\n            b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,\n                                       char_len, entry[i].name.len + 1);\n            if (entry[i].escape_html) {\n                b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,\n                                                     b->last - last);\n            }\n            last = b->last;\n        } else {\n            if (entry[i].escape_html) {\n                if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {\n                    char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;\n                } else {\n                    char_len = len;\n                }\n                b->last = (u_char *) ngx_escape_html(b->last,\n                                                  entry[i].name.data, char_len);\n                last = b->last;\n            } else {\n                b->last = ngx_cpystrn(b->last, entry[i].name.data,\n                                      NGX_HTTP_AUTOINDEX_NAME_LEN + 1);\n                last = b->last - 3;\n            }\n        }\n        if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {\n            b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1);\n        } else {\n            if (entry[i].dir && NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {\n                *b->last++ = \'/\';\n                len++;\n            }\n            b->last = ngx_cpymem(b->last, "</a>", sizeof("</a>") - 1);\n            if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {\n                ngx_memset(b->last, \' \', NGX_HTTP_AUTOINDEX_NAME_LEN - len);\n                b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;\n            }\n        }\n        *b->last++ = \' \';\n        ngx_gmtime(entry[i].mtime + tp->gmtoff * 60 * alcf->localtime, &tm);\n        b->last = ngx_sprintf(b->last, "%02d-%s-%d %02d:%02d ",\n                              tm.ngx_tm_mday,\n                              months[tm.ngx_tm_mon - 1],\n                              tm.ngx_tm_year,\n                              tm.ngx_tm_hour,\n                              tm.ngx_tm_min);\n        if (alcf->exact_size) {\n            if (entry[i].dir) {\n                b->last = ngx_cpymem(b->last,  "                  -",\n                                     sizeof("                  -") - 1);\n            } else {\n                b->last = ngx_sprintf(b->last, "%19O", entry[i].size);\n            }\n        } else {\n            if (entry[i].dir) {\n                b->last = ngx_cpymem(b->last,  "      -",\n                                     sizeof("      -") - 1);\n            } else {\n                length = entry[i].size;\n                if (length > 1024 * 1024 * 1024 - 1) {\n                    size = (ngx_int_t) (length / (1024 * 1024 * 1024));\n                    if ((length % (1024 * 1024 * 1024))\n                                                > (1024 * 1024 * 1024 / 2 - 1))\n                    {\n                        size++;\n                    }\n                    scale = \'G\';\n                } else if (length > 1024 * 1024 - 1) {\n                    size = (ngx_int_t) (length / (1024 * 1024));\n                    if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) {\n                        size++;\n                    }\n                    scale = \'M\';\n                } else if (length > 9999) {\n                    size = (ngx_int_t) (length / 1024);\n                    if (length % 1024 > 511) {\n                        size++;\n                    }\n                    scale = \'K\';\n                } else {\n                    size = (ngx_int_t) length;\n                    scale = \'\\0\';\n                }\n                if (scale) {\n                    b->last = ngx_sprintf(b->last, "%6i%c", size, scale);\n                } else {\n                    b->last = ngx_sprintf(b->last, " %6i", size);\n                }\n            }\n        }\n        *b->last++ = CR;\n        *b->last++ = LF;\n    }\n    b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);\n    b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);\n    return b;\n}']