static ssize_t
ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file)
{
    ssize_t                  n;
    static u_char            buf[1];
    ngx_event_aio_t         *aio;
    ngx_http_request_t      *r;
    ngx_output_chain_ctx_t  *ctx;

    n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL);

    if (n == NGX_AGAIN) {
        aio = file->file->aio;
        aio->handler = ngx_http_copy_aio_sendfile_event_handler;

        r = aio->data;
        r->main->blocked++;
        r->aio = 1;

        ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
        ctx->aio = 1;
    }

    return n;
}
static ngx_int_t
ngx_squ_file_aio_read(ngx_squ_thread_t *thr, ngx_lua_file_ctx_t *ctx)
{
    ssize_t      n;
    ngx_buf_t   *b;
    ngx_file_t  *file;

    ngx_log_debug0(NGX_LOG_DEBUG_CORE, thr->log, 0, "squ file aio read");

    file = &ctx->file;
    b = ctx->in;

#if (NGX_HAVE_FILE_AIO)
    n = ngx_file_aio_read(file, b->start, ctx->size, ctx->offset, ctx->pool);
#else
    n = ngx_read_file(file, b->start, ctx->size, ctx->offset);
#endif

    if (n == NGX_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, thr->log, ngx_errno,
                      "ngx_file_aio_read() \"%V\" failed", &file->name);
        squ_pushboolean(thr->l, 0);
        squ_pushstring(thr->l, "ngx_file_aio_read() failed");
        return 2;
    }

#if (NGX_HAVE_FILE_AIO)
    if (n == NGX_AGAIN) {
        ctx->file.aio->data = ctx;
        ctx->file.aio->handler = ngx_squ_file_aio_read_handler;
        return NGX_AGAIN;
    }
#endif

    ctx->offset += n;

    squ_pushlstring(thr->l, (char *) b->start, n);

    return 1;
}
ngx_int_t 
ngx_async_file_read(ngx_file_reader_state_t* state, ngx_buf_t *buf, size_t size, off_t offset)
{
	ssize_t rc;

	ngx_log_debug2(NGX_LOG_DEBUG_HTTP, state->log, 0, "ngx_async_file_read: reading offset %O size %uz", offset, size);

	if (state->use_aio)
	{
		rc = ngx_file_aio_read(&state->file, buf->last, size, offset, state->r->pool);
		if (rc == NGX_AGAIN)
		{
			// wait for completion
			state->file.aio->data = state;
			state->file.aio->handler = ngx_async_read_completed_callback;

			state->r->main->blocked++;
			state->r->aio = 1;

			state->buf = buf;
			return rc;
		}
	}
	else
	{
		rc = ngx_read_file(&state->file, buf->last, size, offset);
	}

	if (rc < 0)
	{
		ngx_log_error(NGX_LOG_ERR, state->log, 0, "ngx_async_file_read: ngx_file_aio_read failed rc=%z", rc);
		return rc;
	}

	ngx_log_debug1(NGX_LOG_DEBUG_HTTP, state->log, 0, "ngx_async_file_read: ngx_file_aio_read returned %z", rc);
	buf->last += rc;
	
	return NGX_OK;
}
static void
ngx_async_read_completed_callback(ngx_event_t *ev)
{
	ngx_file_reader_state_t* state;
	ngx_http_request_t *r;
	ngx_connection_t *c;
	ngx_event_aio_t *aio;
	ssize_t bytes_read;
	ssize_t rc;

	aio = ev->data;
	state = aio->data;
	r = state->r;
	c = r->connection;

	r->main->blocked--;
	r->aio = 0;

	// get the number of bytes read (offset, size, buffer are ignored in this case)
	rc = ngx_file_aio_read(&state->file, NULL, 0, 0, r->pool);

	if (rc < 0)
	{
		ngx_log_error(NGX_LOG_ERR, state->log, 0,
			"ngx_async_read_completed_callback: ngx_file_aio_read failed rc=%z", rc);
		bytes_read = 0;
	}
	else
	{
		ngx_log_debug1(NGX_LOG_DEBUG_HTTP, state->log, 0, "ngx_async_read_completed_callback: ngx_file_aio_read returned %z", rc);
		state->buf->last += rc;
		bytes_read = rc;
		rc = NGX_OK;
	}

	state->read_callback(state->callback_context, rc, NULL, bytes_read);

	ngx_http_run_posted_requests(c);
}
Esempio n. 5
0
static ssize_t
ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
{
#if (NGX_HAVE_FILE_AIO)
    ssize_t                    n;
    ngx_http_core_loc_conf_t  *clcf;

    if (!ngx_file_aio) {
        goto noaio;
    }

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    if (!clcf->aio) {
        goto noaio;
    }

    n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);

    if (n != NGX_AGAIN) {
        return n;
    }

    c->file.aio->data = r;
    c->file.aio->handler = ngx_http_cache_aio_event_handler;

    r->main->blocked++;
    r->aio = 1;

    return NGX_AGAIN;

noaio:

#endif

    return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
}
Esempio n. 6
0
static ngx_int_t
ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_int_t                     rc;
    ngx_connection_t             *c;
    ngx_output_chain_ctx_t       *ctx;
    ngx_http_core_loc_conf_t     *clcf;
    ngx_http_copy_filter_conf_t  *conf;

    c = r->connection;

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http copy filter: \"%V?%V\"", &r->uri, &r->args);

    ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);

    if (ctx == NULL) {
        ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
        if (ctx == NULL) {
            return NGX_ERROR;
        }

        ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module);

        conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module);
        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

        ctx->sendfile = c->sendfile;
        ctx->need_in_memory = r->main_filter_need_in_memory
                              || r->filter_need_in_memory;
        ctx->need_in_temp = r->filter_need_temporary;

        ctx->alignment = clcf->directio_alignment;

        ctx->pool = r->pool;
        ctx->bufs = conf->bufs;
        ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module;

        ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter;
        ctx->filter_ctx = r;

#if (NGX_HAVE_FILE_AIO)
        if (ngx_file_aio && clcf->aio) {
            ctx->aio_handler = ngx_http_copy_aio_handler;
#if (NGX_HAVE_AIO_SENDFILE)
            c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE);
#endif
        }
#endif

        r->request_output = 1;
    }

#if (NGX_HAVE_FILE_AIO)
    ctx->aio = r->aio;
#endif

    for ( ;; ) {
        rc = ngx_output_chain(ctx, in);

        if (ctx->in == NULL) {
            r->buffered &= ~NGX_HTTP_COPY_BUFFERED;

        } else {
            r->buffered |= NGX_HTTP_COPY_BUFFERED;
        }

        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);

#if (NGX_HAVE_FILE_AIO && NGX_HAVE_AIO_SENDFILE)

        if (c->busy_sendfile) {
            ssize_t                n;
            off_t                  offset;
            ngx_file_t            *file;
            ngx_http_ephemeral_t  *e;

            file = c->busy_sendfile->file;
            offset = c->busy_sendfile->file_pos;

            if (file->aio) {
                c->aio_sendfile = (offset != file->aio->last_offset);
                file->aio->last_offset = offset;

                if (c->aio_sendfile == 0) {
                    ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                                  "sendfile(%V) returned busy again",
                                  &file->name);
                }
            }

            c->busy_sendfile = NULL;
            e = (ngx_http_ephemeral_t *) &r->uri_start;

            n = ngx_file_aio_read(file, &e->aio_preload, 1, offset, r->pool);

            if (n > 0) {
                in = NULL;
                continue;
            }

            rc = n;

            if (file->aio) {
                file->aio->data = r;
                file->aio->handler = ngx_http_copy_aio_sendfile_event_handler;

                r->main->blocked++;
                r->aio = 1;
            }
        }
#endif

        return rc;
    }
}
Esempio n. 7
0
static ngx_int_t
ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
{
    off_t        size;
    ssize_t      n;
    ngx_buf_t   *src, *dst;
    ngx_uint_t   sendfile;

    src = ctx->in->buf;
    dst = ctx->buf;

    size = ngx_buf_size(src);
    size = ngx_min(size, dst->end - dst->pos);

    sendfile = ctx->sendfile & !ctx->directio;

#if (NGX_SENDFILE_LIMIT)

    if (src->in_file && src->file_pos >= NGX_SENDFILE_LIMIT) {
        sendfile = 0;
    }

#endif

    if (ngx_buf_in_memory(src)) {
        ngx_memcpy(dst->pos, src->pos, (size_t) size);
        src->pos += (size_t) size;
        dst->last += (size_t) size;

        if (src->in_file) {

            if (sendfile) {
                dst->in_file = 1;
                dst->file = src->file;
                dst->file_pos = src->file_pos;
                dst->file_last = src->file_pos + size;

            } else {
                dst->in_file = 0;
            }

            src->file_pos += size;

        } else {
            dst->in_file = 0;
        }

        if (src->pos == src->last) {
            dst->flush = src->flush;
            dst->last_buf = src->last_buf;
            dst->last_in_chain = src->last_in_chain;
        }

    } else {

#if (NGX_HAVE_ALIGNED_DIRECTIO)

        if (ctx->unaligned) {
            if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
                              ngx_directio_off_n " \"%s\" failed",
                              src->file->name.data);
            }
        }

#endif

#if (NGX_HAVE_FILE_AIO)
        if (ctx->aio_handler) {
            n = ngx_file_aio_read(src->file, dst->pos, (size_t) size,
                                  src->file_pos, ctx->pool);
            if (n == NGX_AGAIN) {
                ctx->aio_handler(ctx, src->file);
                return NGX_AGAIN;
            }

        } else
#endif
#if (NGX_THREADS)
        if (src->file->thread_handler) {
            n = ngx_thread_read(&ctx->thread_task, src->file, dst->pos,
                                (size_t) size, src->file_pos, ctx->pool);
            if (n == NGX_AGAIN) {
                ctx->aio = 1;
                return NGX_AGAIN;
            }

        } else
#endif
        {
            n = ngx_read_file(src->file, dst->pos, (size_t) size,
                              src->file_pos);
        }

#if (NGX_HAVE_ALIGNED_DIRECTIO)

        if (ctx->unaligned) {
            ngx_err_t  err;

            err = ngx_errno;

            if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
                              ngx_directio_on_n " \"%s\" failed",
                              src->file->name.data);
            }

            ngx_set_errno(err);

            ctx->unaligned = 0;
        }

#endif

        if (n == NGX_ERROR) {
            return (ngx_int_t) n;
        }

        if (n != size) {
            ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
                          ngx_read_file_n " read only %z of %O from \"%s\"",
                          n, size, src->file->name.data);
            return NGX_ERROR;
        }

        dst->last += n;

        if (sendfile) {
            dst->in_file = 1;
            dst->file = src->file;
            dst->file_pos = src->file_pos;
            dst->file_last = src->file_pos + n;

        } else {
            dst->in_file = 0;
        }

        src->file_pos += n;

        if (src->file_pos == src->file_last) {
            dst->flush = src->flush;
            dst->last_buf = src->last_buf;
            dst->last_in_chain = src->last_in_chain;
        }
    }

    return NGX_OK;
}
static ngx_int_t 
ngx_http_minify_buf(ngx_buf_t *buf,ngx_http_request_t *r,
                    ngx_open_file_info_t *of)
{
    ngx_buf_t   *b = NULL, *dst = NULL, *min_dst = NULL;
    ngx_int_t    size;
    ngx_file_t  *src_file ;
    ssize_t n;

    src_file =  ngx_pcalloc(r->pool, sizeof(ngx_file_t));
    if (src_file == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    src_file->fd = of->fd;
    src_file->name = buf->file->name;
    src_file->log = r->connection->log;
    src_file->directio = of->is_directio;

    size = of->size;

    b = ngx_calloc_buf(r->pool); 
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    b->start = ngx_palloc(r->pool, size+1);
    b->pos = b->start;
    b->last = b->start;
    b->end = b->last + size ;
    b->temporary = 1;

    dst = b;

    #if (NGX_HAVE_FILE_AIO)
    
         ngx_output_chain_ctx_t       *ctx;
         ctx = ngx_http_get_module_ctx(r, ngx_http_minify_filter_module);
         if (ctx->aio_handler) {
             n = ngx_file_aio_read(src_file, dst->pos, (size_t) size, 0, 
                                   ctx->pool);

             if (n == NGX_AGAIN) {
             ctx->aio_handler(ctx, src_file);
             return NGX_AGAIN;
             }
    
         } else {
             n = ngx_read_file(src_file, dst->pos, (size_t) size, 0);
         }
    #else
    
        ngx_read_file(src_file, dst->pos, (size_t) size, 0);
    #endif

    dst->end[0] = 0;
    
    b = ngx_calloc_buf(r->pool); 
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    b->start = ngx_palloc(r->pool, size);
    b->pos = b->start;
    b->last = b->start;
    b->end = b->last + size;
    b->temporary = 1;
    
    min_dst = b;
    if (ngx_strcmp(r->headers_out.content_type.data,
                   ngx_http_minify_default_types[0].data) 
        == 0)
    {
        jsmin(dst,min_dst);

    } else if (ngx_strcmp(r->headers_out.content_type.data, 
                          ngx_http_minify_default_types[1].data) 
               == 0)
    {
        cssmin(dst,min_dst);

    } else {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    buf->start = min_dst->start;     
    buf->pos = min_dst->pos;
    buf->last = min_dst->last;
    buf->end = min_dst->end;
    buf->memory = 1;
    buf->in_file = 0;
    

    return NGX_OK;

}