⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_http_memcached_module.c

📁 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_event.h>#include <ngx_http.h>typedef struct {    ngx_http_upstream_conf_t   upstream;    ngx_int_t                  index;} ngx_http_memcached_loc_conf_t;typedef struct {    size_t                     rest;    ngx_http_request_t        *request;    ngx_str_t                  key;} ngx_http_memcached_ctx_t;static ngx_int_t ngx_http_memcached_create_request(ngx_http_request_t *r);static ngx_int_t ngx_http_memcached_reinit_request(ngx_http_request_t *r);static ngx_int_t ngx_http_memcached_process_header(ngx_http_request_t *r);static ngx_int_t ngx_http_memcached_filter_init(void *data);static ngx_int_t ngx_http_memcached_filter(void *data, ssize_t bytes);static void ngx_http_memcached_abort_request(ngx_http_request_t *r);static void ngx_http_memcached_finalize_request(ngx_http_request_t *r,    ngx_int_t rc);static void *ngx_http_memcached_create_loc_conf(ngx_conf_t *cf);static char *ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf,    void *parent, void *child);static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,    void *conf);static char *ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf,    ngx_command_t *cmd, void *conf);static char *ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf,    ngx_command_t *cmd, void *conf);static ngx_conf_bitmask_t  ngx_http_memcached_next_upstream_masks[] = {    { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },    { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },    { ngx_string("invalid_response"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },    { ngx_string("not_found"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },    { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },    { ngx_null_string, 0 }};static ngx_command_t  ngx_http_memcached_commands[] = {    { ngx_string("memcached_pass"),      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_http_memcached_pass,      NGX_HTTP_LOC_CONF_OFFSET,      0,      NULL },    { ngx_string("memcached_connect_timeout"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_conf_set_msec_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_memcached_loc_conf_t, upstream.connect_timeout),      NULL },    { ngx_string("memcached_send_timeout"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_conf_set_msec_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_memcached_loc_conf_t, upstream.send_timeout),      NULL },    { ngx_string("memcached_buffer_size"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_conf_set_size_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_memcached_loc_conf_t, upstream.buffer_size),      NULL },    { ngx_string("memcached_read_timeout"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_conf_set_msec_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout),      NULL },    { ngx_string("memcached_next_upstream"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,      ngx_conf_set_bitmask_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream),      &ngx_http_memcached_next_upstream_masks },    { ngx_string("memcached_upstream_max_fails"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_http_memcached_upstream_max_fails_unsupported,      0,      0,      NULL },    { ngx_string("memcached_upstream_fail_timeout"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,      ngx_http_memcached_upstream_fail_timeout_unsupported,      0,      0,      NULL },      ngx_null_command};static ngx_http_module_t  ngx_http_memcached_module_ctx = {    NULL,                                  /* preconfiguration */    NULL,                                  /* postconfiguration */    NULL,                                  /* create main configuration */    NULL,                                  /* init main configuration */    NULL,                                  /* create server configuration */    NULL,                                  /* merge server configuration */    ngx_http_memcached_create_loc_conf,    /* create location configration */    ngx_http_memcached_merge_loc_conf      /* merge location configration */};ngx_module_t  ngx_http_memcached_module = {    NGX_MODULE_V1,    &ngx_http_memcached_module_ctx,        /* module context */    ngx_http_memcached_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 ngx_str_t  ngx_http_memcached_key = ngx_string("memcached_key");#define NGX_HTTP_MEMCACHED_END   (sizeof(ngx_http_memcached_end) - 1)static u_char  ngx_http_memcached_end[] = CRLF "END" CRLF;static ngx_int_tngx_http_memcached_handler(ngx_http_request_t *r){    ngx_int_t                       rc;    ngx_http_upstream_t            *u;    ngx_http_memcached_ctx_t       *ctx;    ngx_http_memcached_loc_conf_t  *mlcf;    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {        return NGX_HTTP_NOT_ALLOWED;    }    rc = ngx_http_discard_body(r);    if (rc != NGX_OK && rc != NGX_AGAIN) {        return rc;    }    if (ngx_http_set_content_type(r) != NGX_OK) {        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);    u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));    if (u == NULL) {        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    u->peer.log = r->connection->log;    u->peer.log_error = NGX_ERROR_ERR;#if (NGX_THREADS)    u->peer.lock = &r->connection->lock;#endif    u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;    u->conf = &mlcf->upstream;    u->create_request = ngx_http_memcached_create_request;    u->reinit_request = ngx_http_memcached_reinit_request;    u->process_header = ngx_http_memcached_process_header;    u->abort_request = ngx_http_memcached_abort_request;    u->finalize_request = ngx_http_memcached_finalize_request;    r->upstream = u;    ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));    if (ctx == NULL) {        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    ctx->rest = NGX_HTTP_MEMCACHED_END;    ctx->request = r;    ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);    u->input_filter_init = ngx_http_memcached_filter_init;    u->input_filter = ngx_http_memcached_filter;    u->input_filter_ctx = ctx;    ngx_http_upstream_init(r);    return NGX_DONE;}static ngx_int_tngx_http_memcached_create_request(ngx_http_request_t *r){    size_t                          len;    uintptr_t                       escape;    ngx_buf_t                      *b;    ngx_chain_t                    *cl;    ngx_http_memcached_ctx_t       *ctx;    ngx_http_variable_value_t      *vv;    ngx_http_memcached_loc_conf_t  *mlcf;    mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);    vv = ngx_http_get_indexed_variable(r, mlcf->index);    if (vv == NULL || vv->not_found || vv->len == 0) {        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,                      "the \"$memcached_key\" variable is not set");        return NGX_ERROR;    }    escape = 2 * ngx_escape_uri(NULL, vv->data, vv->len, NGX_ESCAPE_MEMCACHED);    len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1;    b = ngx_create_temp_buf(r->pool, len);    if (b == NULL) {        return NGX_ERROR;    }    cl = ngx_alloc_chain_link(r->pool);    if (cl == NULL) {        return NGX_ERROR;    }    cl->buf = b;    cl->next = NULL;    r->upstream->request_bufs = cl;    *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' ';    ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module);    ctx->key.data = b->last;    if (escape == 0) {        b->last = ngx_copy(b->last, vv->data, vv->len);    } else {        b->last = (u_char *) ngx_escape_uri(b->last, vv->data, vv->len,                                            NGX_ESCAPE_MEMCACHED);    }    ctx->key.len = b->last - ctx->key.data;    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "http memcached request: \"%V\"", &ctx->key);    *b->last++ = CR; *b->last++ = LF;    return NGX_OK;}static ngx_int_tngx_http_memcached_reinit_request(ngx_http_request_t *r){    return NGX_OK;}static ngx_int_tngx_http_memcached_process_header(ngx_http_request_t *r){    u_char                    *p, *len;    ngx_str_t                  line;    ngx_http_upstream_t       *u;    ngx_http_memcached_ctx_t  *ctx;    u = r->upstream;    for (p = u->buffer.pos; p < u->buffer.last; p++) {        if (*p == LF) {            goto found;        }    }    return NGX_AGAIN;found:    *p = '\0';    line.len = p - u->buffer.pos - 1;    line.data = u->buffer.pos;    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "memcached: \"%V\"", &line);    p = u->buffer.pos;    ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module);    if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -