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