static ngx_int_t
ngx_http_trackuri_handler(ngx_http_request_t *r)
{
    ngx_http_trackuri_loc_conf_t  *flcf;
    flcf = ngx_http_get_module_loc_conf(r, ngx_http_trackuri_module);
    if (flcf->track_uri != 1)
        return NGX_HTTP_NOT_ALLOWED;

    if (!ngx_uri_table_add(&flcf->uri_table, &r->uri))
        return NGX_HTTP_INTERNAL_SERVER_ERROR;

    // add top-n stats to response body.
    if ((r->method & NGX_HTTP_GET) && flcf->return_uri_stats == 1) {
        ngx_str_t report;
        ngx_uri_table_report(&flcf->uri_table, &report);
        ngx_http_complex_value_t  cv;
        ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));
        cv.value.len  = report.len;
        cv.value.data = report.data;
        r->headers_out.last_modified_time = 23349600;
        return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_text_type, &cv);
    }

    return NGX_HTTP_CLOSE;
}
/* The actual handler that will process requests. */
ngx_int_t ngx_http_rrd_handler(ngx_http_request_t *r)
{
    ngx_log_t* log = r->connection->log;


    if (NGX_HTTP_GET == r->method) {
        return ngx_http_rrd_show_graph(r);
    } else if (NGX_HTTP_POST == r->method) {
        return ngx_http_rrd_update_database(r);
    } else if (NGX_HTTP_HEAD == r->method) {
        /*  HEAD is supposed to give you the headers the GET would give you.
         * So, we're providing the content-type.
         */
        r->headers_out.status = NGX_HTTP_OK;
        r->header_only = 1;
        r->headers_out.content_type.data = IMAGE_PNG.data;
        r->headers_out.content_type.len = IMAGE_PNG.len;
        return ngx_http_send_header(r);
    } else {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
                              ERR_BAD_METHOD_MSG_CSTR);
        ngx_http_complex_value_t cv = {ERR_BAD_METHOD_MSG, NULL, NULL, NULL};

        return ngx_http_send_response(r, NGX_HTTP_NOT_ALLOWED,
                                      &TEXT_PLAIN, &cv);
    }
}
static ngx_int_t output(ngx_http_request_t *r,void *conf,ngx_str_t type)
{
	ngx_image_conf_t *info = conf;
	ngx_http_complex_value_t  cv;
	ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));
	cv.value.len = info->img_size;
	cv.value.data = (u_char *)info->img_data;
	return ngx_http_send_response(r, NGX_HTTP_OK, &type, &cv);
}
/*
 *  The handler for POST requests (that update the RRD database). The
 * thing here is to remember that when this is called, the body might
 * not be available. So, you must to register an extra callback that
 * will be called when the body is available.
 */
ngx_int_t ngx_http_rrd_update_database(ngx_http_request_t *r)
{
    ngx_log_t *log = r->connection->log;
    ngx_int_t rc;

    /* One could think of using ngx_http_test_content_type (I did) but this
     * is irrelevant as ngx_http_test_content_type works on the response
     * content type, not the request. On top of that, there is really
     * no need to go through a hash-table to check ONE value. */
    if (r->headers_in.content_type == NULL
            || r->headers_in.content_type->value.data == NULL
            || r->headers_in.content_type->value.len != WWW_FORM_URLENCODED.len
            || ngx_strncasecmp(r->headers_in.content_type->value.data,
                    WWW_FORM_URLENCODED.data,
                    WWW_FORM_URLENCODED.len) != 0)
    {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
                              (char *) ERR_BAD_CONTENT_TYPE_MSG.data);
        ngx_http_complex_value_t cv = {ERR_BAD_CONTENT_TYPE_MSG, NULL, NULL, NULL};

        return ngx_http_send_response(r, NGX_HTTP_NOT_ALLOWED,
                                      &TEXT_PLAIN, &cv);
    }
    ngx_log_debug(NGX_LOG_DEBUG_HTTP, log, 0,
                          "rrd module: Content-type is OK. Proceeding.");

    ngx_log_debug(NGX_LOG_DEBUG_HTTP, log, 0,
                   "rrd module: start reading client request body");

    rc = ngx_http_read_client_request_body(r, ngx_http_rrd_body_received);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    if (rc == NGX_AGAIN) {
        /*  nginx will call the body_received when needed. Returning
         * NGX_DONE will prevent nginx from calling ngx_http_finalize_request
         * (which we will call in body_received) */
        return NGX_DONE;
    }
    if (NGX_OK == rc) {
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, log, 0,
                      "rrd module: client request body already read");
        return rc;
    }

    ngx_log_error(NGX_LOG_ALERT, log, 0,
                   "rrd module: unexpected response code from"
                   "ngx_http_read_client_request_body : %u", rc);
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
static ngx_int_t
ngx_http_empty_gif_handler(ngx_http_request_t *r)
{
    ngx_http_complex_value_t  cv;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));

    cv.value.len = sizeof(ngx_empty_gif);
    cv.value.data = ngx_empty_gif;
    r->headers_out.last_modified_time = 23349600;

    return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_gif_type, &cv);
}
static ngx_int_t
ngx_http_brainfuck_handler(ngx_http_request_t *r)
{
  /* e.g) ngx_http_send_response
   * http://antoine.bonavita.free.fr/nginx_mod_dev_en.html
   * ngx_http_script_run
   * */

  ngx_http_complex_value_t cv;

  ngx_memzero(&cv, sizeof (ngx_http_complex_value_t));

  cv.value.len = NULL;
  cv.value.data = NULL;

  return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_html_type, &cv);
}
static ngx_int_t output(ngx_http_request_t *r,void *conf,ngx_str_t type)
{
    ngx_int_t status = 0;
	ngx_image_conf_t *info = conf;
	ngx_http_complex_value_t  cv;
    ngx_pool_cleanup_t            *cln;
    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(info->img_data);
        return status;
    }
    cln->handler = gd_clean_data;
    cln->data = info->img_data;

	ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));
	cv.value.len = info->img_size;
	cv.value.data = (u_char *)info->img_data;
    status = ngx_http_send_response(r, NGX_HTTP_OK, &type, &cv);
    return status;
}
static ngx_int_t hexin_http_scribe_handler(ngx_http_request_t *r)
{
	ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "进入 hexin_http_scribe_handler 方法..");
	
	ngx_int_t rc;
	
	if(!(r->method & (NGX_HTTP_GET))) {
		 return NGX_HTTP_NOT_ALLOWED;	
	}

	rc = ngx_http_discard_request_body(r);

    	if (rc != NGX_OK) {
        	return rc;
    	}
	ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "discard body..");

    	if (ngx_http_set_content_type(r) != NGX_OK) {
        	return NGX_HTTP_INTERNAL_SERVER_ERROR;
    	}   

	hexin_http_scribe_loc_conf_t  *plcf;
	plcf = ngx_http_get_module_loc_conf(r, hexin_http_scribe_module);

	r->state = 0;	

	ngx_http_variable_value_t		*messages;
	messages = ngx_http_get_indexed_variable(r, plcf->message_index);	

	PyObject_CallMethod(hexin_http_scribe_python->pScriberClient, "slog", "(ss)", plcf->scribe_category.data, messages->data);

	ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "hexin_http_scribe_handler 结束..");

	r->headers_out.status = NGX_HTTP_OK;
	r->keepalive = 0;
	r->headers_out.charset = UTF_8;

	return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_gif_type, &hexin_http_scribe_python->success_response);
}