Looking for developer to fix a NginX test case module

Maxim Dounin mdounin at mdounin.ru
Fri Jul 26 13:31:36 UTC 2013


Hello!

On Fri, Jul 26, 2013 at 12:05:11AM -0600, Julien Zefi wrote:

> Hi,
> 
> As i am not able to fix a problem for a NginX module that i am writing, and
> after iterate a couple of times in the mailing list, i am still not able to
> solve the problem. So i would like to offer 100 USD for who is able to help
> me to fix the problem in my test case module.
> 
> As a reference please check the following thread:
> 
> http://mailman.nginx.org/pipermail/nginx-devel/2013-July/003923.html
> 
> If you think you can fix it, please reply me back in private so we can
> discuss how to proceed,

Below is working example of what you've tried to do.  It still 
lacks various things like request body handling which should be 
here in real module, but it's expected to work.

Notable problems in your code:

1) You tried to set low-level event handlers.  That's not what 
you are supposed to do.

2) On the other hand, after handling a requests's write event you 
are responsible to call ngx_handle_write_event().

3) The r->count++ operation was done too many times, it's just wrong.

4) For some unknown reason r->header_only was set.  It's just wrong.

5) Return code from ngx_http_send_header() wasn't handled.

6) Code returned from the ngx_http_test_handler() was NGX_OK 
instead of NGX_DONE which is expected to be used if want to 
continue processing.

7) ... (there were many others, but I'm to lazy to remember all of 
them)

Overral, I would recommend you to read and understand at least 
several standard modules _before_ you'll start further coding.


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>


typedef struct {
    ngx_buf_t  *buf;
} ngx_http_test_ctx_t;


static void ngx_http_test_stream_handler(ngx_http_request_t *r);
static char *ngx_http_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);


static u_char message[] =
    "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF"
    "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF"
    "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF"
    "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF"
    "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFF"
    "\r\n";


static ngx_command_t  ngx_http_test_case_commands[] = {
    { ngx_string("test_module"),
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
      ngx_http_test,
      0,
      0,
      NULL },

    ngx_null_command
};


static ngx_http_module_t  ngx_http_test_case_ctx = {
    NULL,                          /* preconfiguration */
    NULL,                          /* postconfiguration */

    NULL,                          /* create main configuration */
    NULL,                          /* init main configuration */

    NULL,                          /* create server configuration */
    NULL,                          /* merge server configuration */

    NULL,                          /* create location configuration */
    NULL                           /* merge location configuration */
};


ngx_module_t ngx_http_test_module = {
    NGX_MODULE_V1,
    &ngx_http_test_case_ctx,       /* module context */
    ngx_http_test_case_commands,   /* module directives */
    NGX_HTTP_MODULE,               /* module type */
    NULL,                          /* init master */
    NULL,                          /* init module */
    NULL,                          /* init process */
    NULL,                          /* init thread */
    NULL,                          /* exit thread */
    NULL,                          /* exit process */
    NULL,                          /* exit master */
    NGX_MODULE_V1_PADDING
};


static void
ngx_http_test_stream_handler(ngx_http_request_t *r)
{
    ngx_int_t             rc;
    ngx_buf_t            *b;
    ngx_chain_t          *out, cl;
    ngx_http_test_ctx_t  *ctx;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "test stream handler");

    ctx = ngx_http_get_module_ctx(r, ngx_http_test_module);

    if (ctx == NULL) {
        /*
         * create new context and a buffer we will use to send
         * our data
         */

        ctx = ngx_palloc(r->pool, sizeof(ngx_http_test_ctx_t));
        if (ctx == NULL) {
            ngx_http_finalize_request(r, NGX_ERROR);
            return;
        }

        ctx->buf = ngx_create_temp_buf(r->pool, sizeof(message));

        ngx_http_set_ctx(r, ctx, ngx_http_test_module);
    }

    out = NULL;
    b = ctx->buf;

    if (ngx_buf_size(b) == 0) {
        /* new buffer or everything send, start over */

        b->pos = b->start;
        b->last = ngx_cpymem(b->pos, message, sizeof(message) - 1);
        b->flush = 1;

        cl.buf = b;
        cl.next = NULL;

        out = &cl;
    }

    rc = ngx_http_output_filter(r, out);

    if (rc == NGX_ERROR) {
        ngx_http_finalize_request(r, rc);
        return;
    }

    if (ngx_buf_size(b) == 0) {
        ngx_add_timer(r->connection->write, 1);
    }

    if (ngx_handle_write_event(r->connection->write, 0) != NGX_OK) {
        ngx_http_finalize_request(r, NGX_ERROR);
        return;
    }
}


static ngx_int_t
ngx_http_test_handler(ngx_http_request_t *r)
{
    ngx_int_t  rc;

    /* set response headers */

    r->headers_out.content_type.len = sizeof("video/mp2t") - 1;
    r->headers_out.content_type.data = (u_char *) "video/mp2t";
    r->headers_out.status = NGX_HTTP_OK;

    r->write_event_handler = ngx_http_test_stream_handler;

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    r->main->count++;
    ngx_http_test_stream_handler(r);

    return NGX_DONE;
}


static char *
ngx_http_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_loc_conf_t  *clcf;

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_test_handler;

    return NGX_CONF_OK;
}


-- 
Maxim Dounin
http://nginx.org/en/donation.html



More information about the nginx-devel mailing list