Exemple #1
0
void
ngx_http_file_cache_create_key(ngx_http_request_t *r)
{
    size_t             len;
    ngx_str_t         *key;
    ngx_uint_t         i;
    ngx_md5_t          md5;
    ngx_http_cache_t  *c;

    c = r->cache;

    len = 0;

    ngx_crc32_init(c->crc32);
    ngx_md5_init(&md5);

    key = c->keys.elts;
    for (i = 0; i < c->keys.nelts; i++) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "http cache key: \"%V\"", &key[i]);

        len += key[i].len;

        ngx_crc32_update(&c->crc32, key[i].data, key[i].len);
        ngx_md5_update(&md5, key[i].data, key[i].len);
    }

    c->header_start = sizeof(ngx_http_file_cache_header_t)
                      + sizeof(ngx_http_file_cache_key) + len + 1;

    ngx_crc32_final(c->crc32);
    ngx_md5_final(c->key, &md5);
}
void
ngx_http_file_cache_create_key(ngx_http_request_t *r)
{
    size_t             len;
    ngx_str_t         *key;
    ngx_uint_t         i;
    ngx_md5_t          md5;
    ngx_http_cache_t  *c;

    c = r->cache;

    len = 0;

    ngx_crc32_init(c->crc32);	//Here,we do the crc get a key!
    ngx_md5_init(&md5);			//Here,we get the md5

    key = c->keys.elts;			//Means how much elements we used to caculate the key!
    for (i = 0; i < c->keys.nelts; i++) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http cache key: \"%V\"", &key[i]);

        len += key[i].len;

        ngx_crc32_update(&c->crc32, key[i].data, key[i].len);	//do the crc32
        ngx_md5_update(&md5, key[i].data, key[i].len);			//do the md5
    }

    c->header_start = sizeof(ngx_http_file_cache_header_t) + sizeof(ngx_http_file_cache_key) + len + 1;

    ngx_crc32_final(c->crc32);
    ngx_md5_final(c->key, &md5);
}
static int
ngx_http_lua_ngx_md5(lua_State *L)
{
    u_char                  *src;
    size_t                   slen;

    ngx_md5_t                md5;
    u_char                   md5_buf[MD5_DIGEST_LENGTH];
    u_char                   hex_buf[2 * sizeof(md5_buf)];

    if (lua_gettop(L) != 1) {
        return luaL_error(L, "expecting one argument");
    }

    if (strcmp(luaL_typename(L, 1), (char *) "nil") == 0) {
        src     = (u_char *) "";
        slen    = 0;

    } else {
        src = (u_char *) luaL_checklstring(L, 1, &slen);
    }

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, src, slen);
    ngx_md5_final(md5_buf, &md5);

    ngx_hex_dump(hex_buf, md5_buf, sizeof(md5_buf));

    lua_pushlstring(L, (char *) hex_buf, sizeof(hex_buf));

    return 1;
}
static int
ngx_http_lua_ngx_md5_bin(lua_State *L)
{
    u_char                  *src;
    size_t                   slen;

    ngx_md5_t                md5;
    u_char                   md5_buf[MD5_DIGEST_LENGTH];

    if (lua_gettop(L) != 1) {
        return luaL_error(L, "expecting one argument");
    }

    if (lua_isnil(L, 1)) {
        src     = (u_char *) "";
        slen    = 0;

    } else {
        src = (u_char *) luaL_checklstring(L, 1, &slen);
    }

    dd("slen: %d", (int) slen);

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, src, slen);
    ngx_md5_final(md5_buf, &md5);

    lua_pushlstring(L, (char *) md5_buf, sizeof(md5_buf));

    return 1;
}
ngx_int_t ngx_http_sticky_misc_hmac_md5(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *key, ngx_str_t *digest)
{
	u_char hash[MD5_DIGEST_LENGTH];
	u_char k[MD5_CBLOCK];
	ngx_md5_t md5;
	u_int i;

	digest->data = ngx_pcalloc(pool, MD5_DIGEST_LENGTH * 2);
	if (digest->data == NULL) {
		return NGX_ERROR;
	}
	digest->len = MD5_DIGEST_LENGTH * 2;

	ngx_memzero(k, sizeof(k));

	if (key->len > MD5_CBLOCK) {
		ngx_md5_init(&md5);
		ngx_md5_update(&md5, key->data, key->len);
		ngx_md5_final(k, &md5);
	} else {
		ngx_memcpy(k, key->data, key->len);
	}

	/* XOR ipad */
	for (i=0; i < MD5_CBLOCK; i++) {
		k[i] ^= 0x36;
	}

	ngx_md5_init(&md5);
	ngx_md5_update(&md5, k, MD5_CBLOCK);
	ngx_md5_update(&md5, in, len);
	ngx_md5_final(hash, &md5);

	/* Convert k to opad -- 0x6A = 0x36 ^ 0x5C */
	for (i=0; i < MD5_CBLOCK; i++) {
		k[i] ^= 0x6a;
	}

	ngx_md5_init(&md5);
	ngx_md5_update(&md5, k, MD5_CBLOCK);
	ngx_md5_update(&md5, hash, MD5_DIGEST_LENGTH);
	ngx_md5_final(hash, &md5);

	ngx_hex_dump(digest->data, hash, MD5_DIGEST_LENGTH);

	return NGX_OK;
}
void
ngx_http_lua_ffi_md5_bin(const u_char *src, size_t len, u_char *dst)
{
    ngx_md5_t     md5;

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, src, len);
    ngx_md5_final(dst, &md5);
}
static u_char*
ngx_http_upstream_consistent_md5_hash(u_char *result, const u_char *key, size_t key_length) {
    ngx_md5_t md5;

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, key, key_length);
    ngx_md5_final(result, &md5);

    return result;
}
static ngx_int_t
ngx_http_md5_hash_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
                           uintptr_t data)
{
    ngx_http_hash_ctx_t *ctx = (ngx_http_hash_ctx_t *)data;

    ngx_uint_t i;

    ngx_str_t  val;
    ngx_md5_t  md5;
    u_char     hash[16], *p;

    if (ngx_http_complex_value(r, &ctx->value, &val) != NGX_OK) {
        return NGX_ERROR;
    }

    v->len = sizeof("7002945D4B8D9E472866092689DB3EAD") - 1;

    if (v->len <= ctx->start) {
        return NGX_ERROR;
    }

    if (v->len < ctx->end) {
        return NGX_ERROR;
    }

    v->data = ngx_palloc(r->pool, v->len);
    if (v->data == NULL) {
        v->not_found = 1;
        return NGX_OK;
    }

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, val.data, val.len);
    ngx_md5_final((u_char*)hash, &md5);

    p = v->data;

    for (i = 0; i < 16; i++) {
        p = ngx_sprintf(p, "%02XD", hash[i]);
    }

    v->valid = 1;
    v->not_found = 0;
    v->no_cacheable = 0;

    if (ctx->end) {
        v->data += ctx->start;
        v->len = ctx->end;
    }


    return NGX_OK;
}
void
ngx_http_lua_ffi_md5(const u_char *src, size_t len, u_char *dst)
{
    ngx_md5_t           md5;
    u_char              md5_buf[MD5_DIGEST_LENGTH];

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, src, len);
    ngx_md5_final(md5_buf, &md5);

    ngx_hex_dump(dst, md5_buf, sizeof(md5_buf));
}
u_char *
ngx_http_lua_digest_hex(u_char *dest, const u_char *buf, int buf_len)
{
    ngx_md5_t                     md5;
    u_char                        md5_buf[MD5_DIGEST_LENGTH];

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, buf, buf_len);
    ngx_md5_final(md5_buf, &md5);

    return ngx_hex_dump(dest, md5_buf, sizeof(md5_buf));
}
/* The md5 hash vaule has better random value with the input string than crc32.
 * And the virtual node can be dispersed uniformly in the ring.
 * */
static int32_t 
ngx_http_upstream_consistent_hash_node_point(u_char *str, size_t len)
{
    u_char     md5_buf[16];
    ngx_md5_t  md5;

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, str, len);
    ngx_md5_final(md5_buf, &md5);

    return ngx_crc32_long(md5_buf, 16);
}
Exemple #12
0
static ngx_int_t
ngx_http_session_gen_sid(ngx_http_request_t *r, ngx_str_t *sid)
{
    ngx_md5_t                        md5_state;
    u_char                           md5_digest[16];
    u_char                           hex_output[16 * 2 + 1], source[512];
    ngx_uint_t                       di, source_len = 0, port_time_len;
    struct sockaddr_in               *peer_addr;
    socklen_t                        peer_len = NGX_SOCKADDRLEN;
    u_char                           sa[NGX_SOCKADDRLEN];
    ngx_int_t                        ret = 0;
    ngx_time_t                       *time;

    memset(source, 0, 512);

    memcpy(source, r->connection->addr_text.data, r->connection->addr_text.len);
    source_len += r->connection->addr_text.len;
    
    ret = getpeername(r->connection->fd, (struct sockaddr *)&sa, &peer_len);
    if (ret < 0) {
        return NGX_ERROR;
    }

    time = ngx_timeofday();
    if (!time) {
        return NGX_ERROR;
    }

    peer_addr = (struct sockaddr_in *)sa;
    port_time_len = sprintf((char *)source + source_len, ":%d %d.%d", 
            peer_addr->sin_port, (int)ngx_time(), (int)time->msec);

    if (port_time_len <= 0) {
        return NGX_ERROR;
    }

    source_len += port_time_len;

    ngx_md5_init(&md5_state);
    ngx_md5_update(&md5_state, (void *)source, source_len);
    ngx_md5_final(md5_digest, &md5_state);

    for (di = 0; di < 16; di++) {
        sprintf((char *)hex_output + di * 2, "%02x", md5_digest[di]);
    }

    memcpy(sid->data, hex_output, NGX_HTTP_SESSION_DEFAULT_SID_LEN);
    sid->data[NGX_HTTP_SESSION_DEFAULT_SID_LEN] = 0;
    sid->len = NGX_HTTP_SESSION_DEFAULT_SID_LEN;

    return NGX_OK;
}
static ngx_int_t
ngx_http_secure_cookie_set_md5_variable(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    u_char                           md5_buf[16];
    ngx_str_t                        res, val;
    ngx_md5_t                        md5;
    ngx_http_secure_cookie_conf_t   *sclcf;

    sclcf = ngx_http_get_module_loc_conf(r, ngx_http_secure_cookie_module);
    if (sclcf == NULL) {
        goto not_found;
    }

    if (ngx_http_complex_value(r, sclcf->md5, &val) != NGX_OK) {
        goto not_found;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "secure cookie set md5 base string: \"%V\"", &val);

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, val.data, val.len);
    ngx_md5_final(md5_buf, &md5);

    res.len = 24;
    res.data = ngx_pcalloc(r->pool, res.len);
    if (res.data == NULL) {
        goto not_found;
    }

    val.len = 16;
    val.data = md5_buf;
    ngx_encode_base64(&res, &val);

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "secure cookie set md5 base64: \"%V\"", &res);

    v->len = res.len;
    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->data = res.data;

    return NGX_OK;

not_found:

    v->not_found = 1;

    return NGX_OK;
}
static ngx_uint_t
ngx_http_auth_mysql_check_md5(ngx_http_request_t *r, ngx_str_t sent_password, ngx_str_t actual_password) {
	u_char md5_str[2*MD5_DIGEST_LENGTH + 1];
	u_char md5_digest[MD5_DIGEST_LENGTH];	
	ngx_md5_t md5;
	
	ngx_md5_init(&md5);
	ngx_md5_update(&md5, sent_password.data, sent_password.len);
	ngx_md5_final(md5_digest, &md5);
	ngx_hex_dump(md5_str, md5_digest, MD5_DIGEST_LENGTH);
	md5_str[2*MD5_DIGEST_LENGTH] = '\0';
	return (ngx_strcmp(actual_password.data, md5_str) == 0)? NGX_OK : NGX_DECLINED;
}
static void
ngx_rtmp_notify_set_name(u_char *dst, size_t dst_len, u_char *src,
    size_t src_len)
{
    u_char     result[16], *p;
    ngx_md5_t  md5;

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, src, src_len);
    ngx_md5_final(result, &md5);

    p = ngx_hex_dump(dst, result, ngx_min((dst_len - 1) / 2, 16));
    *p = '\0';
}
static ngx_int_t
ngx_http_requestid_set_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
{
    ngx_md5_t                    md5;
    ngx_http_requestid_conf_t    *conf;
    u_char                       *end;
    u_char                       val[NGX_INT64_LEN * 3 + 3];
    u_char                       hashb[MD5_BHASH_LEN];
    ngx_uint_t                   i, k;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_requestid_module);

    if (conf->enable == 0) {
    	v->not_found = 1;
    	return NGX_OK;
    }

    end = ngx_sprintf(val, "%i,%ui,%i",
                      ngx_pid, r->connection->number, ngx_random());
    *end = 0;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "requestid: data for hash=%s", val);

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, val, end-val);
    ngx_md5_final(hashb, &md5);

    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->len = MD5_HASH_LEN;
    v->data = ngx_pnalloc(r->pool, MD5_HASH_LEN);

    if (v->data == NULL) {
        return NGX_ERROR;
    }

    for (i = TIMESTAMP_LENGTH & ~1, k = 0; i < MD5_HASH_LEN; i += 2, ++k) {
        v->data[i]   = hex[hashb[k] >> 4];
        v->data[i+1] = hex[hashb[k] & 0xf];
    }

    ngx_snprintf(v->data, TIMESTAMP_LENGTH, "%ui%03d",
                 r->start_sec, r->start_msec);

    return NGX_OK;
}
static void
ngx_http_parallel_calculate_key(
	u_char* key,
	ngx_http_request_t *r)
{
	ngx_md5_t md5;

	ngx_md5_init(&md5);
	if (r->headers_in.host != NULL)
	{
		ngx_md5_update(&md5, r->headers_in.host->value.data, r->headers_in.host->value.len);
	}
	ngx_md5_update(&md5, r->uri.data, r->uri.len);
	ngx_md5_final(key, &md5);
}
void
calc_req_digest( ngx_http_request_t* r, radius_str_t* secret, u_char* digest ) {

    ngx_md5_t md5; 
    ngx_md5_init( &md5 ); 
    ngx_md5_update( &md5, secret->s, secret->len ); 
    ngx_md5_update( &md5, r->headers_in.user.data, r->headers_in.user.len ); 
    ngx_md5_update( &md5, r->headers_in.passwd.data, r->headers_in.passwd.len ); 

    u_char d[ 16 ];
    ngx_md5_final( d, &md5 ); 

    ngx_hex_dump( digest, d, sizeof( d ) );

}
static int ngx_http_static_etags_md5(unsigned int size, char *file, char *md5sum, ngx_log_t *log) {
   FILE             *fp = NULL;
   char             data[4096];
   int              ret;
   int              j;
   int              chunk_size = 4096;
   int              chunks = 0;
   int              left_over = 0;
   unsigned int     fileLen;
   ngx_md5_t        md5;
   unsigned char    digest[16];
   u_char           hex[] = "0123456789abcdef";


   ngx_md5_init(&md5);

   fp = fopen((char *) file, "rb");
   if (fp == NULL)
     return (int ) 1;
   fseek(fp, 0, SEEK_END);
   fileLen = ftell(fp);
   fseek(fp, 0, SEEK_SET);
  
   ngx_md5_init(&md5);
   chunks = fileLen / chunk_size;
   left_over = fileLen % chunk_size;
   for (j = 0; j < chunks; j++) {
     ret = fread(&data, chunk_size, 1 ,fp);
     ngx_md5_update(&md5, data, chunk_size);
   }

   if(left_over) {
     ret = fread(&data, left_over, 1 ,fp);
     ngx_md5_update(&md5, data, left_over);
   }

   fclose(fp);
   ngx_md5_final(digest, &md5);

   ngx_memzero(md5sum, 33);
   md5sum[32] = '\0';
   for ( j = 0 ; j < 16; j++ ) {
     md5sum[2*j] = hex[digest[j] >> 4];
     md5sum[2*j+1] = hex[digest[j] & 0xf];
   }

   return (int ) 0;
}
ngx_int_t ngx_http_sticky_misc_md5(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *digest)
{
	ngx_md5_t md5;
	u_char hash[MD5_DIGEST_LENGTH];

	digest->data = ngx_pcalloc(pool, MD5_DIGEST_LENGTH * 2);
	if (digest->data == NULL) {
		return NGX_ERROR;
	}

	digest->len = MD5_DIGEST_LENGTH * 2;
	ngx_md5_init(&md5);
	ngx_md5_update(&md5, in, len);
	ngx_md5_final(hash, &md5);

	ngx_hex_dump(digest->data, hash, MD5_DIGEST_LENGTH);
	return NGX_OK;
}
static ngx_int_t
ngx_http_vod_dash_webm_handle_init_segment(
	ngx_http_vod_submodule_context_t* submodule_context,
	ngx_str_t* response,
	ngx_str_t* content_type)
{
	vod_status_t rc;
	ngx_md5_t md5;
	ngx_str_t* uri;
	uint64_t track_uid;
	u_char uri_key[16];

	// calculate a uid for track based on the request uri
	uri = &submodule_context->r->uri;
	ngx_md5_init(&md5);
	ngx_md5_update(&md5, uri->data, uri->len);
	ngx_md5_final(uri_key, &md5);
	ngx_memcpy(&track_uid, uri_key, sizeof(track_uid));

	rc = mkv_build_init_segment(
		&submodule_context->request_context,
		submodule_context->media_set.sequences[0].filtered_clips[0].first_track,
		track_uid,
		response);
	if (rc != VOD_OK)
	{
		ngx_log_debug1(NGX_LOG_DEBUG_HTTP, submodule_context->request_context.log, 0,
			"ngx_http_vod_dash_webm_handle_init_segment: mkv_build_init_segment failed %i", rc);
		return ngx_http_vod_status_to_ngx_error(rc);
	}

	if (submodule_context->media_set.track_count[MEDIA_TYPE_VIDEO] != 0)
	{
		content_type->data = webm_video_content_type;
		content_type->len = sizeof(webm_video_content_type) - 1;
	}
	else
	{
		content_type->data = webm_audio_content_type;
		content_type->len = sizeof(webm_audio_content_type) - 1;
	}

	return NGX_OK;
}
Exemple #22
0
static void sample_md5()
{
	char key[] = "test_string";
	ngx_md5_t md5;
	u_char digest[16];
	int i;

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, key, ngx_strlen(key));
    ngx_md5_final(digest, &md5);

	puts("sample_md5 --------");
	printf("string = [%s]\n", key);
	for (i = 0; i < sizeof(digest); i++) {
		printf("%02x", digest[i]);
	}
	printf("\n");

	return;
}
static ngx_int_t
ngx_http_upstream_session_sticky_set_sid(ngx_conf_t *cf,
    ngx_http_ss_server_t *s)
{
    u_char     buf[16];
    ngx_md5_t  md5;

    s->sid.len = 32;
    s->sid.data = ngx_pnalloc(cf->pool, 32);
    if (s->sid.data == NULL) {
        return NGX_ERROR;
    }

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, s->name->data, s->name->len);
    ngx_md5_final(buf, &md5);

    ngx_hex_dump(s->sid.data, buf, 16);

    return NGX_OK;
}
Exemple #24
0
static JSBool
method_md5(JSContext *cx, JSObject *self, uintN argc, jsval *argv, jsval *rval)
{
	JSString                      *jsstr;
	ngx_md5_t                      md5;
	u_char                        *str, hash[16], hex[32];
	size_t                         len;
	
	TRACE();
	
	if (argc != 1)
	{
		JS_ReportError(cx, "Nginx.md5 takes 1 argument");
		return JS_FALSE;
	}
	
	jsstr = JS_ValueToString(cx, argv[0]);
	if (jsstr == NULL)
	{
		return JS_FALSE;
	}
	
	str = (u_char *) JS_GetStringBytes(jsstr);
	if (str == NULL)
	{
		return JS_FALSE;
	}
	
	len = ngx_strlen(str);
	
	ngx_md5_init(&md5);
	ngx_md5_update(&md5, str, len);
	ngx_md5_final(hash, &md5);
	
	ngx_hex_dump(hex, hash, 16);
	
	DATA_LEN_to_JS_STRING_to_JSVAL(cx, hex, 32, *rval);
	
	return JS_TRUE;
}
Exemple #25
0
int main (int argc, char *argv[])
{
    ngx_int_t i;
    ngx_md5_t md5;
    u_char *p, md5_buf[16], md5_dump_buf[32];
    ngx_str_t s = ngx_string("bokko");

    printf("%s:", s.data);

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, s.data, s.len);
    ngx_md5_final(md5_buf, &md5);

    p = md5_dump_buf;
    p = ngx_hex_dump(p, md5_buf, 16);
    for (i=0;i<32;i++) {
        printf("%c", md5_dump_buf[i]);
    }
    printf("\n");


    return 0;
}
static ngx_int_t
ngx_http_cp_gen_cookie_data(ngx_http_request_t *r, 
        ngx_str_t *cookie, ngx_str_t *neteye_cookie,
        ngx_uint_t magic)
{
    ngx_md5_t                        md5_ctx;
    u_char                           md5_digest[16];
    u_char                          *hex_output, *source;
    ngx_uint_t                       di;

    source = ngx_pcalloc(r->pool, cookie->len + sizeof(magic));
    if (!source) {
        return NGX_ERROR;
    }

    hex_output = ngx_pcalloc(r->pool, NGX_HTTP_CP_MD5_LEN + 1);
    if (!hex_output) {
        return NGX_ERROR;
    }
    
    memcpy(source, cookie->data, cookie->len);
    memcpy(source + cookie->len, &magic, sizeof(magic));

    ngx_md5_init(&md5_ctx);
    ngx_md5_update(&md5_ctx, (void *)source, strlen((char *)source));
    ngx_md5_final(md5_digest, &md5_ctx);

    for (di = 0; di < 16; di++) {
        sprintf((char *)hex_output + di * 2, "%02x", md5_digest[di]);
    }

    neteye_cookie->data = hex_output;
    neteye_cookie->len = NGX_HTTP_CP_MD5_LEN;

    return NGX_OK;
}
static ngx_int_t
ngx_secure_token_cht_get_var(
	ngx_http_request_t *r,
	ngx_http_variable_value_t *v,
	uintptr_t data)
{
	ngx_secure_token_cht_token_t* token = (void*)data;
	ngx_str_t expires_str;
	ngx_str_t md5hash_str;
	ngx_str_t token_str;
	ngx_str_t acl;
	ngx_md5_t md5;
	u_char end_time_buf[NGX_INT32_LEN];
	u_char md5hash_buf[MD5_DIGEST_LENGTH];
	u_char token_buf[ngx_base64_encoded_length(MD5_DIGEST_LENGTH)];
	time_t end_time;
	size_t result_size;
	u_char* p;
	ngx_int_t rc;

	// get the acl
	rc = ngx_http_secure_token_get_acl(r, token->acl, &acl);
	if (rc != NGX_OK)
	{
		return rc;
	}

	// get the end time
	end_time = token->end.val;
	if (token->end.type == NGX_HTTP_SECURE_TOKEN_TIME_RELATIVE)
	{
		end_time += ngx_time();
	}
	expires_str.data = end_time_buf;
	expires_str.len = ngx_sprintf(end_time_buf, "%uD", (uint32_t)end_time) - end_time_buf;
	
	// calculate the signature
	ngx_md5_init(&md5);
	ngx_md5_update(&md5, acl.data, acl.len);
	ngx_md5_update(&md5, token->key.data, token->key.len);
	ngx_md5_update(&md5, expires_str.data, expires_str.len);
	ngx_md5_final(md5hash_buf, &md5);

	md5hash_str.data = md5hash_buf;
	md5hash_str.len = sizeof(md5hash_buf);

	token_str.data = token_buf;
	ngx_encode_base64url(&token_str, &md5hash_str);

	// get the result size
	result_size = sizeof(TOKEN_PART1) + token_str.len + sizeof(TOKEN_PART2) + expires_str.len;

	// allocate the result
	p = ngx_pnalloc(r->pool, result_size);
	if (p == NULL)
	{
		return NGX_ERROR;
	}

	v->data = p;

	// build the result
	p = ngx_copy(p, TOKEN_PART1, sizeof(TOKEN_PART1) - 1);
	p = ngx_copy(p, token_str.data, token_str.len);
	p = ngx_copy(p, TOKEN_PART2, sizeof(TOKEN_PART2) - 1);
	p = ngx_copy(p, expires_str.data, expires_str.len);
	*p = '\0';

	v->len = p - v->data;
	v->valid = 1;
	v->no_cacheable = 0;
	v->not_found = 0;

	return NGX_OK;
}
static ngx_int_t ngx_http_upstream_init_q_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
{
    unsigned char                         hash_data[HASH_DATA_LENGTH] = {};
    ngx_http_upstream_q_chash_ring        *q_chash_ring;
    ngx_http_upstream_q_chash_srv_conf_t  *uchscf;
    ngx_http_upstream_rr_peers_t          *peers;
    ngx_uint_t                            vnode_num, i, j, k, fill_next;
    ngx_int_t                             si;
    uint32_t                              point;

    uchscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_q_chash_module);
    if (uchscf == NULL) {
        return NGX_ERROR;
    }

    q_chash_ring = ngx_pcalloc(cf->pool, sizeof(*q_chash_ring));
    if(q_chash_ring == NULL)
        return NGX_ERROR;

    if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
        return NGX_ERROR;
    }

    us->peer.init = ngx_http_upstream_init_q_chash_peer;

    uchscf->q_chash_ring = q_chash_ring;

    peers = us->peer.data;

    for(i = 0; i < peers->number; i++) {
        if(!peers->peer[i].down)
            q_chash_ring->nr_valid_peers ++;
    }

    // old_cycle's log_level is NGX_LOG_NOTICE
    //ngx_log_debug(NGX_LOG_DEBUG_HTTP, cf->log, 0, "upstream %V nr_valid_peers %ui", peers->name, q_chash_ring->nr_valid_peers);

    // no need to hash
    if(q_chash_ring->nr_valid_peers <= 1) {
        return NGX_OK;
    }

    // create vnodes, peer_index field, sort
    q_chash_ring->vnodes = ngx_palloc(cf->pool, sizeof(q_chash_vnode_t) * peers->total_weight * NR_VNODE);
    if(q_chash_ring->vnodes == NULL) {
        return NGX_ERROR;
    }

    for(i = 0; i < peers->number; i++) {
        if(peers->peer[i].down) {
            continue;
        }
        vnode_num = peers->peer[i].weight * NR_VNODE;
        for(j = 0; j < vnode_num / 4; j++) {
            ngx_snprintf(hash_data, HASH_DATA_LENGTH, "%V-%ui%Z", &peers->peer[i].name, j);
            u_char md5[16];
            ngx_md5_t ctx;
            ngx_md5_init(&ctx);
            ngx_md5_update(&ctx, hash_data, ngx_strlen(hash_data));
            ngx_md5_final(md5, &ctx);
            for(k = 0; k < 4; k++) {
                point = *(uint32_t *)&md5[k * 4];
                q_chash_ring->vnodes[q_chash_ring->nr_vnodes].peer_index = i;
                q_chash_ring->vnodes[q_chash_ring->nr_vnodes].point = point;
                q_chash_ring->nr_vnodes ++;
            }
        }
    }

    // old_cycle's log_level is NGX_LOG_NOTICE
    //ngx_log_debug(NGX_LOG_DEBUG_HTTP, cf->log, 0, "upstream %V nr_vnodes %ui", peers->name, q_chash_ring->nr_vnodes);

    ngx_qsort(q_chash_ring->vnodes, q_chash_ring->nr_vnodes, sizeof(q_chash_vnode_t), (const void *)compare_vnodes_point);

    // fill vnode's next field
    for(i = 1; ; i ++) {
        if(q_chash_ring->vnodes[0].peer_index == q_chash_ring->vnodes[i].peer_index)
            continue;
        q_chash_ring->vnodes[0].next = i;
        break;
    }

    fill_next = 0;

    for(si = q_chash_ring->nr_vnodes - 1; si >= 0; si--) {
        if(q_chash_ring->vnodes[si].peer_index == q_chash_ring->vnodes[fill_next].peer_index) {
            q_chash_ring->vnodes[si].next = q_chash_ring->vnodes[fill_next].next;
        }
        else {
            q_chash_ring->vnodes[si].next = fill_next;
            fill_next = si;
        }
    }

    // old_cycle's log_level is NGX_LOG_NOTICE
    /*
    for(i = 0; i < q_chash_ring->nr_vnodes; i++) {
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, cf->log, 0, "%ui, next %ui peer_index %ui point %uD", i, q_chash_ring->vnodes[i].next, q_chash_ring->vnodes[i].peer_index, q_chash_ring->vnodes[i].point);
    }
    */

    // calculate peer ratio for debug ~
    ngx_uint_t *statistic_array = ngx_pcalloc(cf->pool, sizeof(uint32_t) * peers->number);
    if(statistic_array == NULL)
        return NGX_OK;
    uint32_t before_point = 0;
    for(i = 1; i < q_chash_ring->nr_vnodes; i++) {
        statistic_array[q_chash_ring->vnodes[i].peer_index] += q_chash_ring->vnodes[i].point - before_point;
        before_point = q_chash_ring->vnodes[i].point;
    }
    statistic_array[q_chash_ring->vnodes[0].peer_index] += 0xFFFFFFFF - before_point;
    for(i = 0; i < peers->number; i++) {
        if(peers->peer[i].down)
            continue;
        ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, "upstream %V %V weight %ui actually ratio %.2f%%", peers->name, &peers->peer[i].name, peers->peer[i].weight, 100 * (double)statistic_array[i] / 0xFFFFFFFF);
    }
    ngx_pfree(cf->pool, statistic_array);

    return NGX_OK;
}
static ngx_int_t
ngx_http_wd_handler(ngx_http_request_t *r)
{
    ngx_http_wd_loc_conf_t              *wdlcf;
    ngx_str_t                           file_path;
    u_char                              *p, *n;
    u_char                              *hash_value;
    u_char                              buf[1024] = {};
    u_char                              md5_digest[16];
    ngx_md5_t                           md5;
    int                                 fd, uri_len;
    ngx_uint_t                          key;
    ssize_t                             rlen;
    ngx_http_wd_ctx_t                  *ctx;
    
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "web defacement handler begin");
    
    wdlcf = ngx_http_get_module_loc_conf(r, ngx_http_web_defacement_module);
    
    if (!wdlcf->enabled || wdlcf->file_name_hash.buckets == NULL) {
        return NGX_DECLINED;
    }

#if (NGX_HTTP_NETEYE_SECURITY)
    ctx = ngx_http_ns_get_module_ctx(r, ngx_http_web_defacement_module);
    if (ctx == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
#else
    ctx = ngx_http_get_module_ctx(r, ngx_http_web_defacement_module);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "web defacement module: r=%p, ctx=%p, uri=%p",
                   r, ctx, &r->uri);

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

        ngx_http_set_ctx(r, ctx, ngx_http_web_defacement_module);
    }
#endif

    uri_len = r->uri.len;
    // Get dir
    if (r->uri.data[r->uri.len - 1] == '/') {
        uri_len += wdlcf->index_file.len;
    }
    n = ngx_pnalloc(r->pool, wdlcf->orig_path.len + uri_len + 1);
    if (n == NULL) {
        return NGX_ERROR;
    }

    p = ngx_cpymem(n, wdlcf->orig_path.data, wdlcf->orig_path.len);
    if (r->uri.data[r->uri.len - 1] == '/' && wdlcf->index_file.len > 0) {
        p = ngx_cpymem(p, r->uri.data, r->uri.len);
        ngx_cpystrn(p, wdlcf->index_file.data, wdlcf->index_file.len + 1);
    } else {
        ngx_cpystrn(p, r->uri.data, r->uri.len + 1);
    }

    file_path.len = wdlcf->orig_path.len + uri_len;
    file_path.data = n;

    key = ngx_hash_key_lc(file_path.data, file_path.len);
    hash_value = ngx_hash_find(&wdlcf->file_name_hash, key, 
            file_path.data, file_path.len);
    if (hash_value == NULL) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                "In hash, can't find file %V, pass", &file_path);
        return NGX_DECLINED;
    } else {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "Find file %s", (char *)file_path.data);
    }

    fd = open((const char *)file_path.data, O_RDONLY);
    if (fd < 0) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "Can't open file: %V", &file_path);
do_action:
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "The uri is defaced, set variables");
        ctx->defaced = 1;
        ctx->file.data = r->uri.data;
        ctx->file.len = r->uri.len;

        if (wdlcf->log_enabled) {
            ngx_http_wd_write_attack_log(r);
        }

        return NGX_DECLINED;
    }

    ngx_md5_init(&md5);

    while (1) {
        rlen = read(fd, buf, sizeof(buf));
        if (rlen < 0) {
            close(fd);
            goto do_action;
        }

        if (rlen == 0) {
            break;
        }

        ngx_md5_update(&md5, (void *)buf, rlen);
    }

    close(fd);
    ngx_md5_final(md5_digest, &md5);

    if (memcmp(hash_value, md5_digest, sizeof(md5_digest)) != 0) {
        goto do_action;
    }

    return NGX_DECLINED;
}
static ngx_int_t ngx_http_dynamic_etags_body_filter(ngx_http_request_t *r, ngx_chain_t *in) {
    ngx_chain_t *chain_link;
    ngx_http_dynamic_etags_module_ctx_t       *ctx;

    ngx_int_t  rc;
    ngx_md5_t md5;
    unsigned char digest[16];
    ngx_uint_t i;

    ctx = ngx_http_get_module_ctx(r, ngx_http_dynamic_etags_module);
    if (ctx == NULL) {
        return ngx_http_next_body_filter(r, in);
    }
	
    ngx_http_dynamic_etags_loc_conf_t *loc_conf;
    loc_conf = ngx_http_get_module_loc_conf(r, ngx_http_dynamic_etags_module);
    if (1 == loc_conf->enable) {
        ngx_md5_init(&md5);
        for (chain_link = in; chain_link; chain_link = chain_link->next) {
            ngx_md5_update(&md5, chain_link->buf->pos,
                chain_link->buf->last - chain_link->buf->pos);
        }
        ngx_md5_final(digest, &md5);

        unsigned char* etag = ngx_pcalloc(r->pool, 34);
        etag[0] = etag[33] = '"';
        for ( i = 0 ; i < 16; i++ ) {
            etag[2*i+1] = hex[digest[i] >> 4];
            etag[2*i+2] = hex[digest[i] & 0xf];
        }

        if(!r->headers_out.etag) {
            r->headers_out.etag = ngx_list_push(&r->headers_out.headers);
        }

        r->headers_out.etag->hash = 1;
        r->headers_out.etag->key.len = sizeof("ETag") - 1;
        r->headers_out.etag->key.data = (u_char *) "ETag";
        r->headers_out.etag->value.len = 34;
        r->headers_out.etag->value.data = etag;

        /* look for If-None-Match in request headers */
        ngx_uint_t      found=0;
        ngx_list_part_t *part = NULL;
        ngx_table_elt_t *header = NULL;
        ngx_table_elt_t if_none_match;
        part = &r->headers_in.headers.part;
        header = part->elts;
        for ( i = 0 ; ; i++ ) {
            if ( i >= part->nelts) {
                if ( part->next == NULL ) {
                        break;
                }

                part = part->next;
                header = part->elts;
                i = 0;
            }

            if ( ngx_strcmp(header[i].key.data, "If-None-Match") == 0 ) {
                if_none_match = header[i];
                found = 1;
                break;
            }
        }

        if ( found ) {
            if ( ngx_strncmp(r->headers_out.etag->value.data, if_none_match.value.data, r->headers_out.etag->value.len) == 0 ) {

                r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
                r->headers_out.status_line.len = 0;
                r->headers_out.content_type.len = 0;
                ngx_http_clear_content_length(r);
                ngx_http_clear_accept_ranges(r);
            }
        }
    }