comparison src/http/modules/ngx_http_autoindex_module.c @ 5945:99751fe3bc3b

Autoindex: implemented XML output format.
author Valentin Bartenev <vbart@nginx.com>
date Fri, 12 Dec 2014 20:25:42 +0300
parents 33c08d7e2915
children 044cb349fd3c
comparison
equal deleted inserted replaced
5944:33c08d7e2915 5945:99751fe3bc3b
46 46
47 47
48 #define NGX_HTTP_AUTOINDEX_HTML 0 48 #define NGX_HTTP_AUTOINDEX_HTML 0
49 #define NGX_HTTP_AUTOINDEX_JSON 1 49 #define NGX_HTTP_AUTOINDEX_JSON 1
50 #define NGX_HTTP_AUTOINDEX_JSONP 2 50 #define NGX_HTTP_AUTOINDEX_JSONP 2
51 #define NGX_HTTP_AUTOINDEX_XML 3
51 52
52 #define NGX_HTTP_AUTOINDEX_PREALLOCATE 50 53 #define NGX_HTTP_AUTOINDEX_PREALLOCATE 50
53 54
54 #define NGX_HTTP_AUTOINDEX_NAME_LEN 50 55 #define NGX_HTTP_AUTOINDEX_NAME_LEN 50
55 56
58 ngx_array_t *entries); 59 ngx_array_t *entries);
59 static ngx_buf_t *ngx_http_autoindex_json(ngx_http_request_t *r, 60 static ngx_buf_t *ngx_http_autoindex_json(ngx_http_request_t *r,
60 ngx_array_t *entries, ngx_str_t *callback); 61 ngx_array_t *entries, ngx_str_t *callback);
61 static ngx_int_t ngx_http_autoindex_jsonp_callback(ngx_http_request_t *r, 62 static ngx_int_t ngx_http_autoindex_jsonp_callback(ngx_http_request_t *r,
62 ngx_str_t *callback); 63 ngx_str_t *callback);
64 static ngx_buf_t *ngx_http_autoindex_xml(ngx_http_request_t *r,
65 ngx_array_t *entries);
63 66
64 static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one, 67 static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
65 const void *two); 68 const void *two);
66 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r, 69 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
67 ngx_dir_t *dir, ngx_str_t *name); 70 ngx_dir_t *dir, ngx_str_t *name);
74 77
75 static ngx_conf_enum_t ngx_http_autoindex_format[] = { 78 static ngx_conf_enum_t ngx_http_autoindex_format[] = {
76 { ngx_string("html"), NGX_HTTP_AUTOINDEX_HTML }, 79 { ngx_string("html"), NGX_HTTP_AUTOINDEX_HTML },
77 { ngx_string("json"), NGX_HTTP_AUTOINDEX_JSON }, 80 { ngx_string("json"), NGX_HTTP_AUTOINDEX_JSON },
78 { ngx_string("jsonp"), NGX_HTTP_AUTOINDEX_JSONP }, 81 { ngx_string("jsonp"), NGX_HTTP_AUTOINDEX_JSONP },
82 { ngx_string("xml"), NGX_HTTP_AUTOINDEX_XML },
79 { ngx_null_string, 0 } 83 { ngx_null_string, 0 }
80 }; 84 };
81 85
82 86
83 static ngx_command_t ngx_http_autoindex_commands[] = { 87 static ngx_command_t ngx_http_autoindex_commands[] = {
257 261
258 case NGX_HTTP_AUTOINDEX_JSONP: 262 case NGX_HTTP_AUTOINDEX_JSONP:
259 ngx_str_set(&r->headers_out.content_type, "application/javascript"); 263 ngx_str_set(&r->headers_out.content_type, "application/javascript");
260 break; 264 break;
261 265
266 case NGX_HTTP_AUTOINDEX_XML:
267 ngx_str_set(&r->headers_out.content_type, "text/xml");
268 ngx_str_set(&r->headers_out.charset, "utf-8");
269 break;
270
262 default: /* NGX_HTTP_AUTOINDEX_HTML */ 271 default: /* NGX_HTTP_AUTOINDEX_HTML */
263 ngx_str_set(&r->headers_out.content_type, "text/html"); 272 ngx_str_set(&r->headers_out.content_type, "text/html");
264 break; 273 break;
265 } 274 }
266 275
384 b = ngx_http_autoindex_json(r, &entries, NULL); 393 b = ngx_http_autoindex_json(r, &entries, NULL);
385 break; 394 break;
386 395
387 case NGX_HTTP_AUTOINDEX_JSONP: 396 case NGX_HTTP_AUTOINDEX_JSONP:
388 b = ngx_http_autoindex_json(r, &entries, &callback); 397 b = ngx_http_autoindex_json(r, &entries, &callback);
398 break;
399
400 case NGX_HTTP_AUTOINDEX_XML:
401 b = ngx_http_autoindex_xml(r, &entries);
389 break; 402 break;
390 403
391 default: /* NGX_HTTP_AUTOINDEX_HTML */ 404 default: /* NGX_HTTP_AUTOINDEX_HTML */
392 b = ngx_http_autoindex_html(r, &entries); 405 b = ngx_http_autoindex_html(r, &entries);
393 break; 406 break;
819 832
820 return NGX_OK; 833 return NGX_OK;
821 } 834 }
822 835
823 836
837 static ngx_buf_t *
838 ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries)
839 {
840 size_t len;
841 ngx_tm_t tm;
842 ngx_buf_t *b;
843 ngx_str_t type;
844 ngx_uint_t i;
845 ngx_http_autoindex_entry_t *entry;
846
847 static u_char head[] = "<?xml version=\"1.0\"?>" CRLF "<list>" CRLF;
848 static u_char tail[] = "</list>" CRLF;
849
850 len = sizeof(head) - 1 + sizeof(tail) - 1;
851
852 entry = entries->elts;
853
854 for (i = 0; i < entries->nelts; i++) {
855 entry[i].escape = ngx_escape_html(NULL, entry[i].name.data,
856 entry[i].name.len);
857
858 len += sizeof("<directory></directory>" CRLF) - 1
859 + entry[i].name.len + entry[i].escape
860 + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1;
861
862 if (entry[i].file) {
863 len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN;
864 }
865 }
866
867 b = ngx_create_temp_buf(r->pool, len);
868 if (b == NULL) {
869 return NULL;
870 }
871
872 b->last = ngx_cpymem(b->last, head, sizeof(head) - 1);
873
874 for (i = 0; i < entries->nelts; i++) {
875 *b->last++ = '<';
876
877 if (entry[i].dir) {
878 ngx_str_set(&type, "directory");
879
880 } else if (entry[i].file) {
881 ngx_str_set(&type, "file");
882
883 } else {
884 ngx_str_set(&type, "other");
885 }
886
887 b->last = ngx_cpymem(b->last, type.data, type.len);
888
889 b->last = ngx_cpymem(b->last, " mtime=\"", sizeof(" mtime=\"") - 1);
890
891 ngx_gmtime(entry[i].mtime, &tm);
892
893 b->last = ngx_sprintf(b->last, "%4d-%02d-%02dT%02d:%02d:%02dZ",
894 tm.ngx_tm_year, tm.ngx_tm_mon,
895 tm.ngx_tm_mday, tm.ngx_tm_hour,
896 tm.ngx_tm_min, tm.ngx_tm_sec);
897
898 if (entry[i].file) {
899 b->last = ngx_cpymem(b->last, "\" size=\"",
900 sizeof("\" size=\"") - 1);
901 b->last = ngx_sprintf(b->last, "%O", entry[i].size);
902 }
903
904 *b->last++ = '"'; *b->last++ = '>';
905
906 if (entry[i].escape) {
907 b->last = (u_char *) ngx_escape_html(b->last, entry[i].name.data,
908 entry[i].name.len);
909 } else {
910 b->last = ngx_cpymem(b->last, entry[i].name.data,
911 entry[i].name.len);
912 }
913
914 *b->last++ = '<'; *b->last++ = '/';
915
916 b->last = ngx_cpymem(b->last, type.data, type.len);
917
918 *b->last++ = '>';
919
920 *b->last++ = CR; *b->last++ = LF;
921 }
922
923 b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);
924
925 return b;
926 }
927
928
824 static int ngx_libc_cdecl 929 static int ngx_libc_cdecl
825 ngx_http_autoindex_cmp_entries(const void *one, const void *two) 930 ngx_http_autoindex_cmp_entries(const void *one, const void *two)
826 { 931 {
827 ngx_http_autoindex_entry_t *first = (ngx_http_autoindex_entry_t *) one; 932 ngx_http_autoindex_entry_t *first = (ngx_http_autoindex_entry_t *) one;
828 ngx_http_autoindex_entry_t *second = (ngx_http_autoindex_entry_t *) two; 933 ngx_http_autoindex_entry_t *second = (ngx_http_autoindex_entry_t *) two;