Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 1 | |
| 2 | #include <ngx_config.h> |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 3 | #include <ngx_string.h> |
| 4 | #include <ngx_file.h> |
| 5 | #include <ngx_hunk.h> |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 6 | #include <ngx_http.h> |
| 7 | |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 8 | ngx_http_module_t ngx_http_static_module; |
| 9 | |
| 10 | |
| 11 | #if 0 |
| 12 | /* STUB */ |
| 13 | static ngx_http_static_ctx_t module_ctx; |
| 14 | |
| 15 | void ngx_http_static_init() |
| 16 | { |
| 17 | module_ctx.out = NULL; |
| 18 | |
| 19 | ngx_http_static_module.ctx = &module_ctx; |
| 20 | } |
| 21 | /* */ |
| 22 | #endif |
| 23 | |
| 24 | |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 25 | int ngx_http_static_handler(ngx_http_request_t *r) |
| 26 | { |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 27 | int rc; |
| 28 | ngx_err_t err; |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 29 | ngx_hunk_t *h; |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 30 | ngx_http_log_ctx_t *ctx; |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 31 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 32 | #if 0 |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 33 | ngx_http_event_static_handler_loc_conf_t *cf; |
| 34 | |
| 35 | cf = (ngx_http_event_static_handler_loc_conf_t *) |
| 36 | ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module); |
| 37 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 38 | #endif |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 39 | |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 40 | ngx_http_discard_body(r); |
| 41 | ctx = r->connection->log->data; |
| 42 | ctx->action = "sending response"; |
| 43 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 44 | if (r->file.fd == NGX_INVALID_FILE) |
| 45 | r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY); |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 46 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 47 | if (r->file.fd == NGX_INVALID_FILE) { |
| 48 | err = ngx_errno; |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 49 | ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, |
| 50 | "ngx_http_static_handler: " |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 51 | ngx_open_file_n " %s failed", r->file.name.data); |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 52 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 53 | if (err == NGX_ENOENT) |
| 54 | return NGX_HTTP_NOT_FOUND; |
| 55 | #if (WIN32) |
| 56 | else if (err == ERROR_PATH_NOT_FOUND) |
| 57 | return NGX_HTTP_NOT_FOUND; |
| 58 | #endif |
| 59 | else |
| 60 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 61 | } |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 62 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 63 | if (!r->file.info_valid) { |
| 64 | if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { |
| 65 | ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, |
| 66 | "ngx_http_static_handler: " |
| 67 | ngx_stat_fd_n " %s failed", r->file.name.data); |
| 68 | |
| 69 | if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) |
| 70 | ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, |
| 71 | "ngx_http_static_handler: " |
| 72 | ngx_close_file_n " %s failed", r->file.name.data); |
| 73 | |
| 74 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 75 | } |
| 76 | |
| 77 | r->file.info_valid = 1; |
| 78 | } |
| 79 | |
| 80 | #if !(WIN32) /* it's probably Unix specific */ |
| 81 | |
| 82 | if (!ngx_is_file(r->file.info)) { |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 83 | ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, |
| 84 | "ngx_http_static_handler: " |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 85 | "%s is not regular file", r->file.name.data); |
Igor Sysoev | e0268b9 | 2002-09-11 15:18:33 +0000 | [diff] [blame] | 86 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 87 | if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) |
| 88 | ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, |
| 89 | "ngx_http_static_handler: " |
| 90 | ngx_close_file_n " %s failed", r->file.name.data); |
| 91 | |
| 92 | return NGX_HTTP_NOT_FOUND; |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 93 | } |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 94 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 95 | #endif |
| 96 | |
Igor Sysoev | a0bb31f | 2002-12-02 16:09:40 +0000 | [diff] [blame] | 97 | r->headers_out.status = NGX_HTTP_OK; |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 98 | r->headers_out.content_length = ngx_file_size(r->file.info); |
| 99 | r->headers_out.last_modified_time = ngx_file_mtime(r->file.info); |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 100 | |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 101 | ngx_test_null(r->headers_out.content_type, |
| 102 | ngx_push_table(r->headers_out.headers), |
| 103 | NGX_HTTP_INTERNAL_SERVER_ERROR); |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 104 | |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 105 | r->headers_out.content_type->key.len = 12; |
| 106 | r->headers_out.content_type->key.data = "Content-Type"; |
| 107 | |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 108 | /* STUB */ |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 109 | if (r->exten.len) { |
| 110 | if (strcasecmp(r->exten.data, "html") == 0) { |
| 111 | r->headers_out.content_type->value.len = 25; |
| 112 | r->headers_out.content_type->value.data = |
| 113 | "text/html; charset=koi8-r"; |
| 114 | } else if (strcasecmp(r->exten.data, "gif") == 0) { |
| 115 | r->headers_out.content_type->value.len = 9; |
| 116 | r->headers_out.content_type->value.data = "image/gif"; |
| 117 | } else if (strcasecmp(r->exten.data, "jpg") == 0) { |
| 118 | r->headers_out.content_type->value.len = 10; |
| 119 | r->headers_out.content_type->value.data = "image/jpeg"; |
| 120 | } |
Igor Sysoev | 682bf8e | 2002-09-16 15:01:44 +0000 | [diff] [blame] | 121 | |
| 122 | } else { |
Igor Sysoev | b086905 | 2002-12-10 18:05:12 +0000 | [diff] [blame] | 123 | r->headers_out.content_type->value.len = 25; |
| 124 | r->headers_out.content_type->value.data = "text/html; charset=koi8-r"; |
Igor Sysoev | 682bf8e | 2002-09-16 15:01:44 +0000 | [diff] [blame] | 125 | } |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 126 | /**/ |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 127 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 128 | /* we need to allocate them before header would be sent */ |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 129 | ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 130 | NGX_HTTP_INTERNAL_SERVER_ERROR); |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 131 | |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 132 | ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)), |
| 133 | NGX_HTTP_INTERNAL_SERVER_ERROR); |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 134 | |
| 135 | rc = ngx_http_send_header(r); |
| 136 | if (r->header_only) |
| 137 | return rc; |
| 138 | |
| 139 | h->type = NGX_HUNK_FILE|NGX_HUNK_LAST; |
| 140 | h->pos.file = 0; |
| 141 | h->last.file = ngx_file_size(r->file.info); |
| 142 | |
| 143 | h->file->fd = r->file.fd; |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 144 | h->file->log = r->connection->log; |
| 145 | |
| 146 | rc = ngx_http_output_filter(r, h); |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 147 | |
Igor Sysoev | a58e3ca | 2002-09-02 14:48:24 +0000 | [diff] [blame] | 148 | ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc); |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame^] | 149 | |
Igor Sysoev | 2b54238 | 2002-08-20 14:48:28 +0000 | [diff] [blame] | 150 | return rc; |
Igor Sysoev | 0c331d9 | 2002-08-15 17:20:26 +0000 | [diff] [blame] | 151 | } |