send file from tmp directory
Anatoli Marinov
toli at webforge.bg
Wed Jan 18 16:27:42 UTC 2012
Hello Colleagues,
I am working on a patch for upstream and proxy_cache that should serve
files not only from cache dir but also from tmp dir.
At the moment I can send only first 114,327 bytes from file in tmp dir.
Its size is more than 1 MB.
The code is:
check the file is in tmp dir
if it is call :
ngx_int_t
ngx_http_tmp_send(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
ngx_http_cache_t *c;
ngx_http_tmp_cache_node_t *n;
c = r->cache;
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
if (b->file == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
n = r->tmp_cache_file.tmp_cache_node;
b->file_pos = c->body_start;
b->file_last = n->tmp_file_size;
b->in_file = 1;
b->last_buf = 0;
b->last_in_chain = 1;
b->file->fd = r->tmp_cache_file.file.fd;
b->file->log = r->connection->log;
out.buf = b;
out.next = NULL;
if(n->downloaded == 1) {
b->last_buf = 1;
ngx_http_output_filter(r, &out);
ngx_http_finalize_request(r, NGX_OK);
return NGX_OK;
}
return ngx_http_output_filter(r, &out);
}
Also I have a new request write handler :
static void ngx_http_upstream_tmp_send_handler(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_chain_t out;
ngx_http_cache_t *c;
ngx_http_tmp_cache_node_t *n;
c = r->cache;
n = r->tmp_cache_file.tmp_cache_node;
if(n->tmp_file_size == r->out->buf->file_pos) {
return;
}
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
if (b->file == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
b->file_pos = r->out->buf->file_pos;
b->file_last = n->tmp_file_size;
b->in_file = 1;
b->last_buf = 0;
b->last_in_chain = 1;
b->file->fd = c->file.fd;
b->file->name = c->file.name;
b->file->log = r->connection->log;
out.buf = b;
out.next = NULL;
if(n->downloaded == 1) {
b->last_buf = 1;
ngx_http_output_filter(r, &out);
ngx_http_finalize_request(r, NGX_OK);
return;
}
ngx_http_output_filter(r, &out);
}
I know the code is not optimal but its a try.
So what I have.
After ngx_http_tmp_send is called b->file_pos and b->file_last have
right size. b->file_last is bigger than 1MB. The file is actually 1MB.
It is in tmp dir I can see it.
To the http client are sent ~114KB data and request write handler is
called.
In ngx_http_upstream_tmp_send_handler I checked r->out->buf->file_pos
and it is moved with ~114KB but I did not find any way to send the rest
of the data.
Where could be my mistake?
More information about the nginx-devel
mailing list