mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
nginx-0.0.1-2003-04-11-20:01:14 import
This commit is contained in:
parent
cde2478a85
commit
fd67586ef6
140
src/core/ngx_file.c
Normal file
140
src/core/ngx_file.c
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_hunk.h>
|
||||
#include <ngx_array.h>
|
||||
#include <ngx_file.h>
|
||||
#include <ngx_files.h>
|
||||
|
||||
|
||||
int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
|
||||
ngx_pool_t *pool, int num, int step, int persistent)
|
||||
{
|
||||
int i;
|
||||
ngx_err_t err;
|
||||
|
||||
file->name.len = path->name.len + 1 + path->len + 10;
|
||||
|
||||
ngx_test_null(file->name.data, ngx_palloc(pool, file->name.len + 1),
|
||||
NGX_ERROR);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < file->name.len; i++) {
|
||||
file->name.data[i] = 'X';
|
||||
}
|
||||
#endif
|
||||
|
||||
ngx_memcpy(file->name.data, path->name.data, path->name.len);
|
||||
|
||||
for ( ;; ) {
|
||||
snprintf(file->name.data + path->name.len + 1 + path->len, 11,
|
||||
"%010d", num);
|
||||
|
||||
ngx_create_hashed_filename(file, path);
|
||||
|
||||
#if 0
|
||||
#if (WIN32)
|
||||
file->fd = CreateFile(file->name.data,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
CREATE_NEW,
|
||||
persistent ? 0:
|
||||
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL);
|
||||
#else
|
||||
file->fd = open(file->name.data, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
file->fd = ngx_open_tempfile(file->name.data, persistent);
|
||||
|
||||
if (file->fd != NGX_INVALID_FILE) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
err = ngx_errno;
|
||||
|
||||
if (err == NGX_EEXIST) {
|
||||
num *= step;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (err != NGX_ENOENT
|
||||
#if (WIN32_NEED_TEST)
|
||||
&& err != NGX_ENOTDIR
|
||||
#endif
|
||||
) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, err,
|
||||
ngx_open_tempfile_n " \"%s\" failed",
|
||||
file->name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_create_path(file, path) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path)
|
||||
{
|
||||
int i, name, pos, level;
|
||||
|
||||
name = file->name.len;
|
||||
pos = path->name.len + 1;
|
||||
|
||||
file->name.data[path->name.len + path->len] = '/';
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
level = path->level[i];
|
||||
|
||||
if (level == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_log_debug(file->log, "temp: %s" _ file->name.data);
|
||||
|
||||
name -= level;
|
||||
file->name.data[pos - 1] = '/';
|
||||
ngx_memcpy(&file->name.data[pos], &file->name.data[name], level);
|
||||
pos += level + 1;
|
||||
}
|
||||
|
||||
ngx_log_debug(file->log, "temp: %s" _ file->name.data);
|
||||
}
|
||||
|
||||
|
||||
int ngx_create_path(ngx_file_t *file, ngx_path_t *path)
|
||||
{
|
||||
int i, pos;
|
||||
ngx_err_t err;
|
||||
|
||||
pos = path->name.len;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (path->level[i] == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos += path->level[i] + 1;
|
||||
|
||||
file->name.data[pos] = '\0';
|
||||
|
||||
ngx_log_debug(file->log, "temp: %s" _ file->name.data);
|
||||
|
||||
if (ngx_mkdir(file->name.data) == NGX_FILE_ERROR) {
|
||||
err = ngx_errno;
|
||||
if (err != NGX_EEXIST) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, err,
|
||||
ngx_mkdir_n " \"%s\" failed", file->name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
file->name.data[pos] = '/';
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <ngx_file.h>
|
||||
#include <ngx_log.h>
|
||||
#include <ngx_alloc.h>
|
||||
#include <ngx_string.h>
|
||||
|
||||
typedef struct ngx_file_s ngx_file_t;
|
||||
@ -21,4 +22,18 @@ struct ngx_file_s {
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
int len;
|
||||
int level[3];
|
||||
} ngx_path_t;
|
||||
|
||||
|
||||
int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
|
||||
ngx_pool_t *pool, int num, int step, int persistent);
|
||||
void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path);
|
||||
int ngx_create_path(ngx_file_t *file, ngx_path_t *path);
|
||||
|
||||
|
||||
|
||||
#endif /* _NGX_FILE_H_INCLUDED_ */
|
||||
|
@ -34,20 +34,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct ngx_hunk_s ngx_hunk_t;
|
||||
struct ngx_hunk_s {
|
||||
#if 0
|
||||
union {
|
||||
char *mem; /* start of current data */
|
||||
off_t file;
|
||||
} pos;
|
||||
union {
|
||||
char *mem; /* end of current data */
|
||||
off_t file;
|
||||
} last;
|
||||
#endif
|
||||
|
||||
char *pos;
|
||||
char *last;
|
||||
off_t file_pos;
|
||||
@ -60,10 +48,10 @@ struct ngx_hunk_s {
|
||||
char *post_end; /* end of post-allocated hunk */
|
||||
int tag;
|
||||
ngx_file_t *file;
|
||||
ngx_hunk_t *shadow;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct ngx_chain_s ngx_chain_t;
|
||||
struct ngx_chain_s {
|
||||
ngx_hunk_t *hunk;
|
||||
|
@ -58,8 +58,9 @@ ngx_module_t ngx_http_index_module = {
|
||||
Try to open first index file before the test of the directory existence
|
||||
because the valid requests should be many more then invalid ones.
|
||||
If open() failed then stat() should be more quickly because some data
|
||||
is already cached in the kernel. Besides Win32 has ERROR_PATH_NOT_FOUND
|
||||
and Unix has ENOTDIR error (although it less helpfull).
|
||||
is already cached in the kernel.
|
||||
Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) and
|
||||
Unix has ENOTDIR error (although it less helpfull).
|
||||
*/
|
||||
|
||||
int ngx_http_index_handler(ngx_http_request_t *r)
|
||||
@ -110,11 +111,7 @@ int ngx_http_index_handler(ngx_http_request_t *r)
|
||||
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
|
||||
"DEBUG: " ngx_open_file_n " %s failed", name);
|
||||
|
||||
#if (WIN32)
|
||||
if (err == ERROR_PATH_NOT_FOUND) {
|
||||
#else
|
||||
if (err == NGX_ENOTDIR) {
|
||||
#endif
|
||||
r->path_not_found = 1;
|
||||
|
||||
} else if (err == NGX_EACCES) {
|
||||
|
@ -40,14 +40,15 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
||||
"ngx_http_static_handler: "
|
||||
ngx_open_file_n " %s failed", r->file.name.data);
|
||||
|
||||
if (err == NGX_ENOENT)
|
||||
if (err == NGX_ENOENT) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
#if (WIN32)
|
||||
else if (err == ERROR_PATH_NOT_FOUND)
|
||||
|
||||
} else if (err == NGX_ENOTDIR) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
#endif
|
||||
else
|
||||
|
||||
} else {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!r->file.info_valid) {
|
||||
|
@ -31,6 +31,9 @@ static int ngx_http_proxy_process_upstream_headers(ngx_http_proxy_ctx_t *p);
|
||||
static int ngx_http_proxy_process_upstream_header_line(ngx_http_proxy_ctx_t *p);
|
||||
|
||||
|
||||
static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev);
|
||||
|
||||
|
||||
static int ngx_http_proxy_read_response_body(ngx_event_t *ev);
|
||||
static int ngx_http_proxy_write_to_client(ngx_event_t *ev);
|
||||
|
||||
@ -39,6 +42,7 @@ static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx);
|
||||
static int ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int error);
|
||||
static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len);
|
||||
|
||||
static int ngx_http_proxy_init(ngx_pool_t *pool);
|
||||
static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool);
|
||||
|
||||
static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@ -82,7 +86,7 @@ ngx_module_t ngx_http_proxy_module = {
|
||||
&ngx_http_proxy_module_ctx, /* module context */
|
||||
ngx_http_proxy_commands, /* module directives */
|
||||
NGX_HTTP_MODULE_TYPE, /* module type */
|
||||
NULL /* init module */
|
||||
ngx_http_proxy_init /* init module */
|
||||
};
|
||||
|
||||
|
||||
@ -179,7 +183,7 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
/* TODO: duplicate the hunks and chain if there is backend farm */
|
||||
p->out = chain;
|
||||
p->request_hunks = chain;
|
||||
|
||||
p->last_error = NGX_HTTP_BAD_GATEWAY;
|
||||
ngx_http_proxy_process_upstream(p, NULL);
|
||||
@ -679,12 +683,12 @@ static int ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
|
||||
ngx_chain_t *chain;
|
||||
ngx_event_t *wev;
|
||||
|
||||
chain = ngx_write_chain(p->connection, p->out, 0);
|
||||
chain = ngx_write_chain(p->connection, p->request_hunks, 0);
|
||||
if (chain == (ngx_chain_t *) -1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p->out = chain;
|
||||
p->request_hunks = chain;
|
||||
|
||||
wev = p->connection->write;
|
||||
|
||||
@ -1026,12 +1030,11 @@ static int ngx_http_proxy_process_upstream_header_line(ngx_http_proxy_ctx_t *p)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
{
|
||||
int rc, n, size;
|
||||
ngx_hunk_t *h;
|
||||
ngx_chain_t *chain, ce;
|
||||
ngx_chain_t *chain, chain_entry, *ce, *te;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_proxy_ctx_t *p;
|
||||
@ -1041,9 +1044,9 @@ static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
p = (ngx_http_proxy_ctx_t *)
|
||||
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
|
||||
|
||||
ce.next = NULL;
|
||||
chain_entry.next = NULL;
|
||||
|
||||
do {
|
||||
for ( ;; ) {
|
||||
|
||||
#if (USE_KQUEUE)
|
||||
|
||||
@ -1051,7 +1054,7 @@ static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
break;
|
||||
}
|
||||
|
||||
#elif (HAVE_KQUEUE)
|
||||
#elif (HAVE_KQUEUE0)
|
||||
|
||||
if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT
|
||||
&& ev->eof && ev->available == 0)
|
||||
@ -1063,6 +1066,7 @@ static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
|
||||
if (p->free_hunks) {
|
||||
chain = p->free_hunks;
|
||||
p->free_hunks = NULL;
|
||||
|
||||
} else if (p->allocated < p->lcf->max_block_size) {
|
||||
ngx_test_null(h,
|
||||
@ -1070,12 +1074,13 @@ static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
NGX_ERROR);
|
||||
|
||||
p->allocated += p->block_size;
|
||||
ce.hunk = h;
|
||||
chain = &ce;
|
||||
chain_entry.hunk = h;
|
||||
chain = &chain_entry;
|
||||
|
||||
} else {
|
||||
if (p->temp_fd == NGX_INVALID_FILE) {
|
||||
rc = ngx_create_temp_file(p->temp_file, r->cachable);
|
||||
if (p->temp_file->fd == NGX_INVALID_FILE) {
|
||||
rc = ngx_create_temp_file(p->temp_file, p->lcf->temp_path,
|
||||
r->pool, 0, 2, r->cachable);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
@ -1089,70 +1094,169 @@ static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
|
||||
}
|
||||
|
||||
n = ngx_write_chain_to_file(p->temp_file, p->in_hunks,
|
||||
p->temp_offset);
|
||||
p->temp_offset, r->pool);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
|
||||
NGX_ERROR);
|
||||
for (ce = p->in_hunks; ce; ce = ce->next) {
|
||||
ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
|
||||
NGX_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_FILE
|
||||
|NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_RECYCLED;
|
||||
h->type = NGX_HUNK_FILE
|
||||
|NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED;
|
||||
|
||||
h->file_pos = p->temp_offset;
|
||||
p->temp_offset += n;
|
||||
h->file_last = p->temp_offset;
|
||||
ce->hunk->shadow = h;
|
||||
h->shadow = ce->hunk;
|
||||
|
||||
h->file->fd = p->temp_file.fd;
|
||||
h->file->log = p->log;
|
||||
h->file_pos = p->temp_offset;
|
||||
p->temp_offset += ce->hunk->last - ce->hunk->pos;
|
||||
h->file_last = p->temp_offset;
|
||||
|
||||
h->pos = p->in_hunks->hunk->pos;
|
||||
h->last = p->in_hunks->hunk->last;
|
||||
h->start = p->in_hunks->hunk->start;
|
||||
h->end = p->in_hunks->hunk->end;
|
||||
h->pre_start = p->in_hunks->hunk->pre_start;
|
||||
h->post_end = p->in_hunks->hunk->post_end;
|
||||
h->file->fd = p->temp_file->fd;
|
||||
h->file->log = p->log;
|
||||
|
||||
ngx_add_hunk_to_chain(p->last_out_hunk, h, r->pool, NGX_ERROR);
|
||||
h->pos = ce->hunk->pos;
|
||||
h->last = ce->hunk->last;
|
||||
h->start = ce->hunk->start;
|
||||
h->end = ce->hunk->end;
|
||||
h->pre_start = ce->hunk->pre_start;
|
||||
h->post_end = ce->hunk->post_end;
|
||||
|
||||
ce.hunk = p->in_hunks->next;
|
||||
p->in_hunks = p->in_hunks->next;
|
||||
chain = &ce;
|
||||
ngx_test_null(te, ngx_create_chain_entry(r->pool), NGX_ERROR);
|
||||
te->hunk = h;
|
||||
te->next = NULL;
|
||||
|
||||
if (p->last_out_hunk) {
|
||||
p->last_out_hunk->next = te;
|
||||
p->last_out_hunk = te;
|
||||
|
||||
} else {
|
||||
p->last_out_hunk = te;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
n = ngx_recv_chain(c, chain);
|
||||
|
||||
h->last += n;
|
||||
left = hunk->end - hunk->last;
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} while (n > 0 && left == 0);
|
||||
if (n == NGX_AGAIN) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (ce = chain; ce && n > 0; ce = ce->next) {
|
||||
ngx_test_null(te, ngx_create_chain_entry(r->pool), NGX_ERROR);
|
||||
te->hunk = ce->hunk;
|
||||
te->next = NULL;
|
||||
|
||||
if (p->last_in_hunk) {
|
||||
p->last_in_hunk->next = te;
|
||||
p->last_in_hunk = te;
|
||||
|
||||
} else {
|
||||
p->last_in_hunk = te;
|
||||
}
|
||||
|
||||
size = ce->hunk->end - ce->hunk->last;
|
||||
|
||||
if (n >= size) {
|
||||
n -= size;
|
||||
ce->hunk->last = ce->hunk->end;
|
||||
if (ce->hunk->shadow) {
|
||||
ce->hunk->shadow->type &= ~(NGX_HUNK_TEMP
|
||||
|NGX_HUNK_IN_MEMORY
|
||||
|NGX_HUNK_RECYCLED);
|
||||
ce->hunk->shadow->shadow = NULL;
|
||||
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ce->hunk->last += n;
|
||||
if (ce->hunk->shadow) {
|
||||
ce->hunk->shadow->type &= ~(NGX_HUNK_TEMP
|
||||
|NGX_HUNK_IN_MEMORY
|
||||
|NGX_HUNK_RECYCLED);
|
||||
ce->hunk->shadow->shadow = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ce) {
|
||||
ce->next = p->free_hunks;
|
||||
p->free_hunks = ce;
|
||||
break;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->out_hunks && p->request->connection->write->ready) {
|
||||
ngx_http_proxy_write_upstream_body(p->request->connection->write);
|
||||
return
|
||||
ngx_http_proxy_write_upstream_body(p->request->connection->write);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev)
|
||||
{
|
||||
while (out) {
|
||||
output_filter(r, hunk);
|
||||
if (again)
|
||||
return
|
||||
int rc;
|
||||
ngx_hunk_t *h, *sh;
|
||||
ngx_chain_t *ce;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_proxy_ctx_t *p;
|
||||
|
||||
if (hunk done)
|
||||
remove from out
|
||||
if (hunk is memory)
|
||||
add it to free
|
||||
c = (ngx_connection_t *) wev->data;
|
||||
r = (ngx_http_request_t *) c->data;
|
||||
p = (ngx_http_proxy_ctx_t *)
|
||||
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
|
||||
|
||||
while (p->out_hunks) {
|
||||
h = p->out_hunks->hunk;
|
||||
rc = ngx_http_output_filter(r, h);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN || h->pos < h->last) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
p->out_hunks = p->out_hunks->next;
|
||||
|
||||
/* if the complete hunk has a shadow hunk
|
||||
then add a shadow hunk to p->free_hunks chain */
|
||||
|
||||
sh = h->shadow;
|
||||
|
||||
if (sh) {
|
||||
sh->pos = sh->last = sh->start;
|
||||
ngx_test_null(ce, ngx_create_chain_entry(r->pool), NGX_ERROR);
|
||||
ce->hunk = sh;
|
||||
ce->next = p->free_hunks;
|
||||
p->free_hunks = ce;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1482,9 +1586,36 @@ static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx)
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_proxy_init(ngx_pool_t *pool)
|
||||
{
|
||||
int i;
|
||||
ngx_file_t file;
|
||||
ngx_path_t path;
|
||||
|
||||
file.log = pool->log;
|
||||
|
||||
path.name.data = "temp";
|
||||
path.name.len = 4;
|
||||
path.level[0] = 1;
|
||||
path.level[1] = 2;
|
||||
path.level[2] = 3;
|
||||
path.len = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (path.level[i] == 0) {
|
||||
break;
|
||||
}
|
||||
path.len += path.level[i] + 1;
|
||||
}
|
||||
|
||||
return ngx_create_temp_file(&file, &path, pool, 123456789, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool)
|
||||
{
|
||||
ngx_http_proxy_loc_conf_t *conf;
|
||||
int i;
|
||||
ngx_http_proxy_loc_conf_t *conf;
|
||||
|
||||
ngx_test_null(conf,
|
||||
ngx_pcalloc(pool, sizeof(ngx_http_proxy_loc_conf_t)),
|
||||
@ -1498,6 +1629,22 @@ static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool)
|
||||
conf->header_size = 1024;
|
||||
conf->block_size = 4096;
|
||||
conf->max_block_size = 32768;
|
||||
|
||||
ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL);
|
||||
|
||||
conf->temp_path->name.data = "temp";
|
||||
conf->temp_path->name.len = 4;
|
||||
conf->temp_path->level[0] = 1;
|
||||
conf->temp_path->level[1] = 2;
|
||||
conf->temp_path->level[2] = 3;
|
||||
conf->temp_path->len = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (conf->temp_path->level[i] == 0) {
|
||||
break;
|
||||
}
|
||||
conf->temp_path->len += conf->temp_path->level[i] + 1;
|
||||
}
|
||||
/**/
|
||||
|
||||
return conf;
|
||||
|
@ -71,6 +71,9 @@ typedef struct {
|
||||
int block_size;
|
||||
int max_block_size;
|
||||
|
||||
ngx_path_t *temp_path;
|
||||
int temp_file_warn;
|
||||
|
||||
int retry_500_error;
|
||||
|
||||
} ngx_http_proxy_loc_conf_t;
|
||||
@ -91,7 +94,26 @@ typedef struct {
|
||||
typedef struct ngx_http_proxy_ctx_s ngx_http_proxy_ctx_t;
|
||||
|
||||
struct ngx_http_proxy_ctx_s {
|
||||
ngx_chain_t *out;
|
||||
ngx_chain_t *in_hunks;
|
||||
ngx_chain_t *last_in_hunk;
|
||||
|
||||
ngx_chain_t *out_hunks;
|
||||
ngx_chain_t *last_out_hunk;
|
||||
|
||||
ngx_chain_t *free_hunks;
|
||||
|
||||
ngx_chain_t *request_hunks;
|
||||
|
||||
ngx_connection_t *connection;
|
||||
ngx_http_request_t *request;
|
||||
ngx_http_proxy_headers_in_t headers_in;
|
||||
|
||||
|
||||
int block_size;
|
||||
int allocated;
|
||||
|
||||
ngx_file_t *temp_file;
|
||||
off_t temp_offset;
|
||||
|
||||
int last_hunk;
|
||||
ngx_array_t hunks;
|
||||
@ -99,10 +121,6 @@ struct ngx_http_proxy_ctx_s {
|
||||
|
||||
int hunk_n;
|
||||
|
||||
ngx_connection_t *connection;
|
||||
ngx_http_request_t *request;
|
||||
ngx_http_proxy_headers_in_t headers_in;
|
||||
|
||||
ngx_http_proxy_upstream_url_t *upstream_url;
|
||||
ngx_http_proxy_upstreams_t *upstreams;
|
||||
int cur_upstream;
|
||||
|
@ -148,6 +148,7 @@ struct ngx_http_request_s {
|
||||
int path_err;
|
||||
|
||||
unsigned proxy:1;
|
||||
unsigned cachable:1;
|
||||
unsigned pipeline:1;
|
||||
unsigned keepalive:1;
|
||||
unsigned lingering_close:1;
|
||||
|
@ -370,12 +370,12 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
|
||||
err = ngx_errno;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
||||
"ngx_http_core_translate_handler: "
|
||||
ngx_file_type_n " %s failed", r->file.name.data);
|
||||
ngx_file_type_n " \"%s\" failed", r->file.name.data);
|
||||
|
||||
if (err == NGX_ENOENT) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
|
||||
} else if (err == ERROR_PATH_NOT_FOUND) {
|
||||
} else if (err == NGX_ENOTDIR) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
|
||||
} else if (err == NGX_EACCES) {
|
||||
@ -396,17 +396,14 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
|
||||
err = ngx_errno;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
|
||||
"ngx_http_core_handler: "
|
||||
ngx_open_file_n " %s failed", r->file.name.data);
|
||||
ngx_open_file_n " \"%s\" failed", r->file.name.data);
|
||||
|
||||
if (err == NGX_ENOENT) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
#if (WIN32)
|
||||
} else if (err == ERROR_PATH_NOT_FOUND) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
#else
|
||||
|
||||
} else if (err == NGX_ENOTDIR) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
#endif
|
||||
|
||||
} else if (err == NGX_EACCES) {
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
|
||||
@ -419,12 +416,13 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
|
||||
if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||
"ngx_http_core_handler: "
|
||||
ngx_stat_fd_n " %s failed", r->file.name.data);
|
||||
ngx_stat_fd_n " \"%s\" failed", r->file.name.data);
|
||||
|
||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||
"ngx_http_core_handler: "
|
||||
ngx_close_file_n " %s failed", r->file.name.data);
|
||||
ngx_close_file_n " \"%s\" failed",
|
||||
r->file.name.data);
|
||||
}
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
@ -441,7 +439,7 @@ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
|
||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||
"ngx_http_core_handler: "
|
||||
ngx_close_file_n " %s failed", r->file.name.data);
|
||||
ngx_close_file_n " \"%s\" failed", r->file.name.data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -487,12 +485,12 @@ static int ngx_http_core_index_handler(ngx_http_request_t *r)
|
||||
|
||||
if (rc == NGX_HTTP_NOT_FOUND) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
|
||||
"%s is not found", r->path.data);
|
||||
"\"%s\" is not found", r->path.data);
|
||||
}
|
||||
|
||||
if (rc == NGX_HTTP_FORBIDDEN) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
|
||||
"%s is forbidden", r->path.data);
|
||||
"\"%s\" is forbidden", r->path.data);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -501,7 +499,7 @@ static int ngx_http_core_index_handler(ngx_http_request_t *r)
|
||||
|
||||
r->path.data[r->path.len] = '\0';
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"directory index of %s is forbidden", r->path.data);
|
||||
"directory index of \"%s\" is forbidden", r->path.data);
|
||||
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
@ -550,7 +548,7 @@ int ngx_http_close_request(ngx_http_request_t *r, int error)
|
||||
if (r->file.fd != NGX_INVALID_FILE) {
|
||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
ngx_close_file_n " failed");
|
||||
ngx_close_file_n " \"%s\" failed", r->file.name.data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ typedef int ngx_err_t;
|
||||
#define NGX_ENOENT ENOENT
|
||||
#define NGX_EINTR EINTR
|
||||
#define NGX_EACCES EACCES
|
||||
#define NGX_EEXIST EEXIST
|
||||
#define NGX_ENOTDIR ENOTDIR
|
||||
#define NGX_EAGAIN EWOULDBLOCK
|
||||
#define NGX_EINPROGRESS EINPROGRESS
|
||||
|
@ -1,7 +1,11 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_hunk.h>
|
||||
#include <ngx_array.h>
|
||||
#include <ngx_file.h>
|
||||
#include <ngx_files.h>
|
||||
|
||||
|
||||
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
{
|
||||
@ -12,7 +16,7 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
n = pread(file->fd, buf, size, offset);
|
||||
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "pread() failed");
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pread() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -29,12 +33,12 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
n = pwrite(file->fd, buf, size, offset);
|
||||
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "pwrite() failed");
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (n != size) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, 0,
|
||||
if ((size_t) n != size) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
||||
"pwrite() has written only %d of %d", n, size);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -45,6 +49,59 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
}
|
||||
|
||||
|
||||
ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
|
||||
off_t offset, ngx_pool_t *pool)
|
||||
{
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
struct iovec *iov;
|
||||
ngx_err_t err;
|
||||
ngx_array_t io;
|
||||
|
||||
/* use pwrite() if there's the only hunk in a chain */
|
||||
|
||||
if (ce->next == NULL) {
|
||||
return ngx_write_file(file, ce->hunk->pos,
|
||||
ce->hunk->last - ce->hunk->pos, offset);
|
||||
}
|
||||
|
||||
ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR);
|
||||
size = 0;
|
||||
|
||||
while (ce) {
|
||||
ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
|
||||
iov->iov_base = ce->hunk->pos;
|
||||
iov->iov_len = ce->hunk->last - ce->hunk->pos;
|
||||
size += ce->hunk->last - ce->hunk->pos;
|
||||
ce = ce->next;
|
||||
}
|
||||
|
||||
if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
n = writev(file->fd, (struct iovec *) io.elts, io.nelts);
|
||||
|
||||
ngx_destroy_array(&io);
|
||||
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if ((size_t) n != size) {
|
||||
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
||||
"writev() has written only %d of %d", n, size);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
file->offset += n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <ngx_config.h>
|
||||
|
||||
#include <ngx_types.h>
|
||||
#include <ngx_alloc.h>
|
||||
#include <ngx_hunk.h>
|
||||
#include <ngx_file.h>
|
||||
|
||||
|
||||
@ -19,11 +21,24 @@
|
||||
#define ngx_close_file close
|
||||
#define ngx_close_file_n "close()"
|
||||
|
||||
#define ngx_open_tempfile(name, persistent) \
|
||||
open(name, O_CREAT|O_EXCL|O_WRONLY, 0600)
|
||||
#define ngx_open_tempfile_n "open()"
|
||||
|
||||
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset);
|
||||
#define ngx_read_file_n "read()"
|
||||
|
||||
#define NGX_FILE_RDONLY O_RDONLY
|
||||
|
||||
ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset);
|
||||
|
||||
ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
|
||||
off_t offset, ngx_pool_t *pool);
|
||||
|
||||
|
||||
#define ngx_mkdir(name) mkdir(name, 0700)
|
||||
#define ngx_mkdir_n "mkdir()"
|
||||
|
||||
|
||||
#define ngx_file_type(file, sb) stat(file, sb)
|
||||
#define ngx_file_type_n "stat()"
|
||||
|
@ -140,7 +140,7 @@ ngx_chain_t *ngx_freebsd_write_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
|
||||
c->sent += sent;
|
||||
|
||||
for (ce = in; ce; ce = ce->next) {
|
||||
for (ce = in; ce && sent > 0; ce = ce->next) {
|
||||
|
||||
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
size = ce->hunk->last - ce->hunk->pos;
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *ce)
|
||||
{
|
||||
int n;
|
||||
struct iovec *iov;
|
||||
ngx_err_t err;
|
||||
ngx_array_t io;
|
||||
ssize_t n;
|
||||
struct iovec *iov;
|
||||
ngx_err_t err;
|
||||
ngx_array_t io;
|
||||
|
||||
ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
|
||||
|
||||
|
@ -12,6 +12,8 @@ typedef DWORD ngx_err_t;
|
||||
|
||||
#define NGX_ENOENT ERROR_FILE_NOT_FOUND
|
||||
#define NGX_EACCES ERROR_ACCESS_DENIED
|
||||
#define NGX_EEXIST ERROR_FILE_EXISTS
|
||||
#define NGX_ENOTDIR ERROR_PATH_NOT_FOUND
|
||||
#define NGX_EAGAIN WSAEWOULDBLOCK
|
||||
#define NGX_EINPROGRESS WSAEINPROGRESS
|
||||
#define NGX_EADDRINUSE WSAEADDRINUSE
|
||||
|
@ -26,6 +26,17 @@
|
||||
NULL, OPEN_EXISTING, 0, NULL)
|
||||
*/
|
||||
|
||||
#define ngx_open_tempfile(name, persistent) \
|
||||
CreateFile(name, \
|
||||
GENERIC_READ|GENERIC_WRITE, \
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \
|
||||
NULL, \
|
||||
CREATE_NEW, \
|
||||
persistent ? 0: \
|
||||
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, \
|
||||
NULL);
|
||||
|
||||
|
||||
#define ngx_open_file_n "CreateFile()"
|
||||
|
||||
#define NGX_FILE_RDONLY GENERIC_READ
|
||||
@ -33,6 +44,9 @@
|
||||
#define ngx_close_file CloseHandle
|
||||
#define ngx_close_file_n "CloseHandle()"
|
||||
|
||||
#define ngx_mkdir(name) CreateDirectory(name, NULL)
|
||||
#define ngx_mkdir_n "CreateDirectory()"
|
||||
|
||||
int ngx_file_type(char *filename, ngx_file_info_t *fi);
|
||||
#define ngx_file_type_n "GetFileAttributes"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user