如何从 Nginx Autoindex 获取 JSON?

如何从 Nginx Autoindex 获取 JSON?

如何修改 Nginx 的自动索引,以便它生成索引的 JSON 版本而不是 HTML?或者是否有一个模块可以做到这一点?

我想要这个;

http://u.kodingen.com/ClrG

代替;

http://u.kodingen.com/Cls2N

这位博客作者似乎已经做到了;

http://u.kodingen.com/Clz3F

http://lamsonproject.net/blog/2009-08-03.html

但他并未提及具体方法。

答案1

从 1.7.9 版本开始您可以使用:

autoindex on;
autoindex_format json;

查看文档:http://nginx.org/r/autoindex_format

答案2

Zed(博客文章的所有者与我分享了他的代码,您需要重新编译自动索引模块,它就在那里。

“是的,就是这样。事实证明我使用了 netbsd pkgsrc,所以这是我为软件包构建制作的干净补丁。应该适用于 netbsd 版本 nginx-0.8.20。

—— Zed A. Shaw”

=== modified file 'src/http/modules/ngx_http_autoindex_module.c'
--- old/src/http/modules/ngx_http_autoindex_module.c    2009-07-28 22:17:45 +0000
+++ src/http/modules/ngx_http_autoindex_module.c    2009-07-29 06:16:22 +0000
@@ -1,6 +1,7 @@

 /*
  * Copyright (C) Igor Sysoev
+ * modified by Zed A. Shaw.
  */


@@ -44,11 +45,7 @@

 #define NGX_HTTP_AUTOINDEX_PREALLOCATE  50

-#define NGX_HTTP_AUTOINDEX_NAME_LEN     50
-
-
-static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
-    const void *two);
+
 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
     ngx_dir_t *dir, ngx_str_t *name);
 static ngx_int_t ngx_http_autoindex_init(ngx_conf_t *cf);
@@ -115,46 +112,93 @@
 };


-static u_char title[] =
-"<html>" CRLF
-"<head><title>Index of "
-;
-
-
-static u_char header[] =
-"</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<h1>Index of "
-;
-
-static u_char tail[] =
-"</body>" CRLF
-"</html>" CRLF
-;
+#define MAX_NAME_LEN 512
+
+static ngx_buf_t *
+autoindex_generate_html(ngx_http_request_t *r, ngx_array_t entries, 
+    ngx_http_autoindex_loc_conf_t  *alcf)
+{
+    size_t                          len = 0;
+    ngx_http_autoindex_entry_t     *entry;
+    ngx_uint_t                      i;
+    ngx_buf_t *b;
+
+    entry = entries.elts; 
+
+    len = MAX_NAME_LEN * entries.nelts + 1024;
+
+    b = ngx_create_temp_buf(r->pool, len);
+    if (b == NULL) return NULL;
+
+    *b->last++ = '[';
+    *b->last++ = '"';
+    b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+
+    *b->last++ = '"';
+    *b->last++ = ',';
+    *b->last++ = '[';
+
+    for (i = 0; i < entries.nelts; i++) {
+        if(entry[i].name.len >= MAX_NAME_LEN) {
+            // this name is too long, it's illegal
+            continue;
+        }
+
+        *b->last++ = '"';
+
+        if (entry[i].colon) {
+             *b->last++ = '.';
+             *b->last++ = '/';
+        }
+
+        if (entry[i].escape) {
+             ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
+                            NGX_ESCAPE_HTML);
+
+             b->last += entry[i].name.len + entry[i].escape;
+
+             // needs to be escaped
+        } else {
+             b->last = ngx_cpymem(b->last, entry[i].name.data,
+                                  entry[i].name.len);
+             // otherwise, it's done
+        }
+
+        if (entry[i].dir) {
+            *b->last++ = '/';
+        }
+
+        *b->last++ = '"';
+        
+        if(i < entries.nelts-1) {
+            *b->last++ = ',';
+        }
+    }
+
+    *b->last++ = ']';
+    *b->last++ = ']';
+
+    return b;
+}


 static ngx_int_t
 ngx_http_autoindex_handler(ngx_http_request_t *r)
 {
-    u_char                         *last, *filename, scale;
-    off_t                           length;
-    size_t                          len, utf_len, allocated, root;
-    ngx_tm_t                        tm;
+    u_char                         *last, *filename;
+    size_t                          len, allocated, root;
     ngx_err_t                       err;
     ngx_buf_t                      *b;
-    ngx_int_t                       rc, size;
+    ngx_int_t                       rc;
     ngx_str_t                       path;
     ngx_dir_t                       dir;
-    ngx_uint_t                      i, level, utf8;
+    ngx_uint_t                      level, utf8;
     ngx_pool_t                     *pool;
-    ngx_time_t                     *tp;
     ngx_chain_t                     out;
     ngx_array_t                     entries;
-    ngx_http_autoindex_entry_t     *entry;
     ngx_http_autoindex_loc_conf_t  *alcf;
+    ngx_http_autoindex_entry_t     *entry;

-    static char  *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

     if (r->uri.data[r->uri.len - 1] != '/') {
         return NGX_DECLINED;
@@ -234,9 +278,9 @@
     }

     r->headers_out.status = NGX_HTTP_OK;
-    r->headers_out.content_type_len = sizeof("text/html") - 1;
-    r->headers_out.content_type.len = sizeof("text/html") - 1;
-    r->headers_out.content_type.data = (u_char *) "text/html";
+    r->headers_out.content_type_len = sizeof("application/javascript") - 1;
+    r->headers_out.content_type.len = sizeof("application/javascript") - 1;
+    r->headers_out.content_type.data = (u_char *) "application/javascript";

     rc = ngx_http_send_header(r);

@@ -363,184 +407,7 @@
                       ngx_close_dir_n " \"%s\" failed", &path);
     }

-    len = sizeof(title) - 1
-          + r->uri.len
-          + sizeof(header) - 1
-          + r->uri.len
-          + 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++) {
-        len += sizeof("<a href=\"") - 1
-            + entry[i].name.len + entry[i].escape
-            + 1                                          /* 1 is for "/" */
-            + sizeof("\">") - 1
-            + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2
-            + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
-            + sizeof("</a>") - 1
-            + sizeof(" 28-Sep-1970 12:00 ") - 1
-            + 20                                         /* the file size */
-            + 2;
-    }
-
-    b = ngx_create_temp_buf(r->pool, len);
-    if (b == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    if (entries.nelts > 1) {
-        ngx_qsort(entry, (size_t) entries.nelts,
-                  sizeof(ngx_http_autoindex_entry_t),
-                  ngx_http_autoindex_cmp_entries);
-    }
-
-    b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
-    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);
-
-    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].colon) {
-            *b->last++ = '.';
-            *b->last++ = '/';
-        }
-
-        if (entry[i].escape) {
-            ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
-                           NGX_ESCAPE_HTML);
-
-            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) {
-                utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
-
-            } else {
-                utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
-            }
-
-            b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
-                                       utf_len, entry[i].name.len + 1);
-            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);
-            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;
-    }
-
-    /* TODO: free temporary pool */
-
-    b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
-
-    b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);
+    b = autoindex_generate_html(r, entries, alcf);

     if (r == r->main) {
         b->last_buf = 1;
@@ -555,63 +422,6 @@
 }


-static int ngx_libc_cdecl
-ngx_http_autoindex_cmp_entries(const void *one, const void *two)
-{
-    ngx_http_autoindex_entry_t *first = (ngx_http_autoindex_entry_t *) one;
-    ngx_http_autoindex_entry_t *second = (ngx_http_autoindex_entry_t *) two;
-
-    if (first->dir && !second->dir) {
-        /* move the directories to the start */
-        return -1;
-    }
-
-    if (!first->dir && second->dir) {
-        /* move the directories to the start */
-        return 1;
-    }
-
-    return (int) ngx_strcmp(first->name.data, second->name.data);
-}
-
-
-#if 0
-
-static ngx_buf_t *
-ngx_http_autoindex_alloc(ngx_http_autoindex_ctx_t *ctx, size_t size)
-{
-    ngx_chain_t  *cl;
-
-    if (ctx->buf) {
-
-        if ((size_t) (ctx->buf->end - ctx->buf->last) >= size) {
-            return ctx->buf;
-        }
-
-        ctx->size += ctx->buf->last - ctx->buf->pos;
-    }
-
-    ctx->buf = ngx_create_temp_buf(ctx->pool, ctx->alloc_size);
-    if (ctx->buf == NULL) {
-        return NULL;
-    }
-
-    cl = ngx_alloc_chain_link(ctx->pool);
-    if (cl == NULL) {
-        return NULL;
-    }
-
-    cl->buf = ctx->buf;
-    cl->next = NULL;
-
-    *ctx->last_out = cl;
-    ctx->last_out = &cl->next;
-
-    return ctx->buf;
-}
-
-#endif
-

 static ngx_int_t
 ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name)

相关内容