static ngx_int_t ngx_http_google_request_generater(ngx_http_request_t * r, ngx_http_google_ctx_t * ctx) { ngx_uint_t i; ngx_table_elt_t * tb; ngx_table_elt_t ** ptr; ngx_str_t * cookie = ngx_http_google_implode_kv(r, ctx->cookies, "; "); if (!cookie) return NGX_ERROR; if (!r->headers_in.cookies.nelts) { tb = ngx_list_push(&r->headers_in.headers); if (!tb) return NGX_ERROR; ngx_str_set(&tb->key, "Cookie"); tb->value = *cookie; tb->hash = ngx_hash_key_lc(tb->key.data, tb->key.len); } else { ptr = r->headers_in.cookies.elts; for (i = 0; i < r->headers_in.cookies.nelts; i++) { ptr[i]->value = *cookie; } } ngx_str_t * arg = ngx_http_google_implode_kv(r, ctx->args, "&"); if (!arg) return NGX_ERROR; ctx->arg = arg; if (!ctx->arg->len) { r->unparsed_uri = *ctx->uri; } else { ngx_str_t uri; uri.len = ctx->uri->len + 1 + ctx->arg->len; uri.data = ngx_pcalloc(r->pool, uri.len); if (!uri.data) return NGX_ERROR; ngx_snprintf(uri.data, uri.len, "%V?%V", ctx->uri, ctx->arg); r->unparsed_uri = uri; } return NGX_OK; }
static ngx_int_t ngx_http_google_response_header_set_cookie(ngx_http_request_t * r, ngx_http_google_ctx_t * ctx, ngx_table_elt_t * tb) { ngx_array_t * kvs = ngx_http_google_explode_kv(r, &tb->value, ";"); if (!kvs) return NGX_ERROR; ngx_uint_t i; ngx_keyval_t * kv, * hd = kvs->elts; for (i = 0; i < kvs->nelts; i++) { kv = hd + i; if (!ngx_strncasecmp(kv->key.data, ctx->conf->data, ctx->conf->len)) { if (ngx_http_google_response_header_set_cookie_conf(r, ctx, &kv->value)) { return NGX_ERROR; } } if (!ngx_strncasecmp(kv->key.data, (u_char *)"GOOGLE_ABUSE_EXEMPTION", 22)) { if (ngx_http_google_response_header_set_cookie_exempt(r, ctx, kvs)) { return NGX_ERROR; } } if (!ngx_strncasecmp(kv->key.data, (u_char *)"domain", 6)) { kv->value = *ctx->domain; } if (!ngx_strncasecmp(kv->key.data, (u_char *)"path", 4)) { ngx_str_set(&kv->value, "/"); } } // unset this key if (!kvs->nelts) { tb->hash = 0; return NGX_OK; } ngx_str_t * set_cookie = ngx_http_google_implode_kv(r, kvs, "; "); if (!set_cookie) return NGX_ERROR; // reset set cookie tb->value = *set_cookie; return NGX_OK; }
static ngx_int_t ngx_http_google_response_header_set_cookie_conf(ngx_http_request_t * r, ngx_http_google_ctx_t * ctx, ngx_str_t * v) { if (ctx->type != ngx_http_google_type_main && ctx->type != ngx_http_google_type_scholar) return NGX_OK; if (ctx->ncr) return NGX_OK; ngx_uint_t i; ngx_array_t * kvs = ngx_http_google_explode_kv(r, v, ":"); if (!kvs) return NGX_ERROR; ngx_int_t nw = 0; ngx_keyval_t * kv, * hd; hd = kvs->elts; for (i = 0; i < kvs->nelts; i++) { kv = hd + i; if (!ngx_strncasecmp(kv->key.data, (u_char *)"LD", 2)) { if (ctx->lang->len) kv->value = *ctx->lang; else { ngx_str_set(&kv->value, "zh-CN"); } } if (!ngx_strncasecmp(kv->key.data, (u_char *)"NW", 2)) nw = 1; } if (!nw) { kv = ngx_array_push(kvs); if (!kv) return NGX_ERROR; ngx_str_set(&kv->key, "NW"); ngx_str_set(&kv->value, "1"); } // sort with length ngx_sort(kvs->elts, kvs->nelts, sizeof(ngx_keyval_t), ngx_http_google_response_header_sort_cookie_conf); ngx_str_t * nv = ngx_http_google_implode_kv(r, kvs, ":"); if (!nv) return NGX_ERROR; *v = *nv; return NGX_OK; }