static RequestInfo * create_request_info(TSHttpTxn txn) { RequestInfo *req_info; char *url; int url_len; TSMBuffer buf; TSMLoc loc; req_info = (RequestInfo *)TSmalloc(sizeof(RequestInfo)); url = TSHttpTxnEffectiveUrlStringGet(txn, &url_len); req_info->effective_url = TSstrndup(url, url_len); TSfree(url); TSHttpTxnClientReqGet(txn, &buf, &loc); req_info->buf = TSMBufferCreate(); TSHttpHdrClone(req_info->buf, buf, loc, &(req_info->http_hdr_loc)); TSHandleMLocRelease(buf, TS_NULL_MLOC, loc); req_info->client_addr = TSmalloc(sizeof(struct sockaddr)); memmove((void *)req_info->client_addr, (void *)TSHttpTxnClientAddrGet(txn), sizeof(struct sockaddr)); return req_info; }
static int ts_lua_http_redirect_url_set(lua_State *L) { const char *url; const char *redirect_url; size_t url_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); url = luaL_checklstring(L, 1, &url_len); redirect_url = TSstrndup(url, url_len); TSHttpTxnRedirectUrlSet(http_ctx->txnp, redirect_url, url_len); return 0; }
static char * get_effective_host(TSHttpTxn txn) { char *effective_url, *tmp; const char *host; int len; TSMBuffer buf; TSMLoc url_loc; effective_url = TSHttpTxnEffectiveUrlStringGet(txn, &len); buf = TSMBufferCreate(); TSUrlCreate(buf, &url_loc); tmp = effective_url; TSUrlParse(buf, url_loc, (const char **) (&tmp), (const char *) (effective_url + len)); TSfree(effective_url); host = TSUrlHostGet(buf, url_loc, &len); tmp = TSstrndup(host, len); TSHandleMLocRelease(buf, TS_NULL_MLOC, url_loc); TSMBufferDestroy(buf); return tmp; }
static RequestInfo * create_request_info(TSHttpTxn txn) { RequestInfo *req_info; char *url; int url_len; TSMBuffer buf; TSMLoc loc; const struct sockaddr *sa; req_info = (RequestInfo *)TSmalloc(sizeof(RequestInfo)); memset(req_info, 0, sizeof(RequestInfo)); url = TSHttpTxnEffectiveUrlStringGet(txn, &url_len); req_info->effective_url = TSstrndup(url, url_len); TSfree(url); TSHttpTxnClientReqGet(txn, &buf, &loc); req_info->buf = TSMBufferCreate(); TSHttpHdrClone(req_info->buf, buf, loc, &(req_info->http_hdr_loc)); TSHandleMLocRelease(buf, TS_NULL_MLOC, loc); sa = TSHttpTxnClientAddrGet(txn); switch (sa->sa_family) { case AF_INET: memcpy(&req_info->client_addr.sin, sa, sizeof(struct sockaddr_in)); break; case AF_INET6: memcpy(&req_info->client_addr.sin6, sa, sizeof(struct sockaddr_in6)); break; default: break; } return req_info; }
static CachedHeaderInfo * get_cached_header_info(TSHttpTxn txn) { CachedHeaderInfo *chi; TSMBuffer cr_buf; TSMLoc cr_hdr_loc, cr_date_loc, cr_cache_control_loc, cr_cache_control_dup_loc; int cr_cache_control_count, val_len, i; char *value, *ptr; chi = (CachedHeaderInfo *)TSmalloc(sizeof(CachedHeaderInfo)); memset(chi, 0, sizeof(CachedHeaderInfo)); if (TSHttpTxnCachedRespGet(txn, &cr_buf, &cr_hdr_loc) == TS_SUCCESS) { cr_date_loc = TSMimeHdrFieldFind(cr_buf, cr_hdr_loc, TS_MIME_FIELD_DATE, TS_MIME_LEN_DATE); if (cr_date_loc != TS_NULL_MLOC) { TSDebug(PLUGIN_NAME, "Found a date"); chi->date = TSMimeHdrFieldValueDateGet(cr_buf, cr_hdr_loc, cr_date_loc); TSHandleMLocRelease(cr_buf, cr_hdr_loc, cr_date_loc); } cr_cache_control_loc = TSMimeHdrFieldFind(cr_buf, cr_hdr_loc, TS_MIME_FIELD_CACHE_CONTROL, TS_MIME_LEN_CACHE_CONTROL); while (cr_cache_control_loc != TS_NULL_MLOC) { TSDebug(PLUGIN_NAME, "Found cache-control"); cr_cache_control_count = TSMimeHdrFieldValuesCount(cr_buf, cr_hdr_loc, cr_cache_control_loc); for (i = 0; i < cr_cache_control_count; i++) { value = (char *)TSMimeHdrFieldValueStringGet(cr_buf, cr_hdr_loc, cr_cache_control_loc, i, &val_len); ptr = value; if (strncmp(value, TS_HTTP_VALUE_MAX_AGE, TS_HTTP_LEN_MAX_AGE) == 0) { TSDebug(PLUGIN_NAME, "Found max-age"); ptr += TS_HTTP_LEN_MAX_AGE; if (*ptr == '=') { ptr++; chi->max_age = atol(ptr); } else { ptr = TSstrndup(value, TS_HTTP_LEN_MAX_AGE + 2); TSDebug(PLUGIN_NAME, "This is what I found: %s", ptr); TSfree(ptr); } } else if (strncmp(value, HTTP_VALUE_STALE_WHILE_REVALIDATE, strlen(HTTP_VALUE_STALE_WHILE_REVALIDATE)) == 0) { TSDebug(PLUGIN_NAME, "Found stale-while-revalidate"); ptr += strlen(HTTP_VALUE_STALE_WHILE_REVALIDATE); if (*ptr == '=') { ptr++; chi->stale_while_revalidate = atol(ptr); } } else if (strncmp(value, HTTP_VALUE_STALE_IF_ERROR, strlen(HTTP_VALUE_STALE_IF_ERROR)) == 0) { TSDebug(PLUGIN_NAME, "Found stale-on-error"); ptr += strlen(HTTP_VALUE_STALE_IF_ERROR); if (*ptr == '=') { ptr++; chi->stale_on_error = atol(ptr); } } else { TSDebug(PLUGIN_NAME, "Unknown field value"); } } cr_cache_control_dup_loc = TSMimeHdrFieldNextDup(cr_buf, cr_hdr_loc, cr_cache_control_loc); TSHandleMLocRelease(cr_buf, cr_hdr_loc, cr_cache_control_loc); cr_cache_control_loc = cr_cache_control_dup_loc; } TSHandleMLocRelease(cr_buf, TS_NULL_MLOC, cr_hdr_loc); } return chi; }
TSRemapStatus TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo* rri) { int i, len; time_t t, e; MD5_CTX ctx; struct sockaddr_in *in; const char *qh, *ph, *ip; unsigned char md[MD5_DIGEST_LENGTH]; secure_link_info *sli = (secure_link_info *)ih; char *token = NULL, *expire = NULL, *path = NULL; char *s, *ptr, *saveptr = NULL, *val, hash[32] = ""; in = (struct sockaddr_in *)TSHttpTxnClientAddrGet(rh); ip = inet_ntoa(in->sin_addr); s = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &len); TSDebug(PLUGIN_NAME, "request [%.*s] from [%s]", len, s, ip); TSfree(s); qh = TSUrlHttpQueryGet(rri->requestBufp, rri->requestUrl, &len); if(qh && len > 0) { s = (char *)TSstrndup(qh, len); if((ptr = strtok_r(s, "&", &saveptr)) != NULL) { do { if((val = strchr(ptr, '=')) != NULL) { *val++ = '\0'; if(strcmp(ptr, "st") == 0) { token = TSstrdup(val); } else if(strcmp(ptr, "ex") == 0) { expire = TSstrdup(val); } } else { TSError("Invalid parameter [%s]", ptr); break; } } while((ptr = strtok_r(NULL, "&", &saveptr)) != NULL); } else { TSError("strtok didn't find a & in the query string"); /* this is just example, so set fake params to prevent plugin crash */ token = TSstrdup("d41d8cd98f00b204e9800998ecf8427e"); expire = TSstrdup("00000000"); } TSfree(s); } else { TSError("TSUrlHttpQueryGet returns empty value"); } ph = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &len); if(ph && len > 0) { s = TSstrndup(ph, len); if((ptr = strrchr(s, '/')) != NULL) { *++ptr = '\0'; } path = TSstrdup(s); TSfree(s); } else { TSError("TSUrlPathGet returns empty value"); /* this is just example, so set fake params to prevent plugin crash */ path = TSstrdup("example/"); } MD5_Init(&ctx); MD5_Update(&ctx, sli->secret, strlen(sli->secret)); MD5_Update(&ctx, ip, strlen(ip)); if (path) MD5_Update(&ctx, path, strlen(path)); if (expire) MD5_Update(&ctx, expire, strlen(expire)); MD5_Final(md, &ctx); for(i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(&hash[i * 2], "%02x", md[i]); } time(&t); e = strtol(expire, NULL, 16); i = TSREMAP_DID_REMAP; if(e < t || strcmp(hash, token) != 0) { if(e < t) { TSDebug(PLUGIN_NAME, "link expired: [%lu] vs [%lu]", t, e); } else { TSDebug(PLUGIN_NAME, "tokens mismatch: [%s] vs [%s]", hash, token); } if(sli->strict) { TSDebug(PLUGIN_NAME, "request is DENY"); TSHttpTxnSetHttpRetStatus(rh, TS_HTTP_STATUS_FORBIDDEN); i = TSREMAP_NO_REMAP; } else { TSDebug(PLUGIN_NAME, "request is PASS"); } } if(i == TSREMAP_DID_REMAP) { if(TSUrlHttpQuerySet(rri->requestBufp, rri->requestUrl, "", -1) == TS_SUCCESS) { s = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &len); TSDebug(PLUGIN_NAME, "new request string is [%.*s]", len, s); TSfree(s); } else { i = TSREMAP_NO_REMAP; } } TSfree(expire); TSfree(token); TSfree(path); return i; }