static void add_header(TSHttpTxn txnp, TSCont contp) { TSMBuffer req_bufp; TSMLoc req_loc; TSMLoc field_loc; TSMLoc next_field_loc; TSMLoc new_field_loc; int retval; if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) != TS_SUCCESS) { TSError("[add_header] Error while retrieving client request header\n"); goto done; } field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0); if (field_loc == TS_NULL_MLOC) { TSError("[add_header] Error while getting field"); goto error; } /* Loop on our header containing fields to add */ while (field_loc) { /* First create a new field in the client request header */ if (TSMimeHdrFieldCreate(req_bufp, req_loc, &new_field_loc) != TS_SUCCESS) { TSError("[add_header] Error while creating new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* Then copy our new field at this new location */ retval = TSMimeHdrFieldCopy(req_bufp, req_loc, new_field_loc, hdr_bufp, hdr_loc, field_loc); if (retval == TS_ERROR) { TSError("[add_header] Error while copying new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* Add this field to the Http client request header */ retval = TSMimeHdrFieldAppend(req_bufp, req_loc, new_field_loc); if (retval != TS_SUCCESS) { TSError("[add_header] Error while appending new field"); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); break; } /* We can now release this handle */ TSHandleMLocRelease(req_bufp, req_loc, new_field_loc); next_field_loc = TSMimeHdrFieldNext(hdr_bufp, hdr_loc, field_loc); TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc); field_loc = next_field_loc; } error: TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc); done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); }
static void modify_header(TSHttpTxn txnp) { TSMBuffer resp_bufp; TSMBuffer cached_bufp; TSMLoc resp_loc; TSMLoc cached_loc; TSHttpStatus resp_status; TSMLoc new_field_loc; TSMLoc cached_field_loc; time_t recvd_time; const char *chkptr; int chklength; int num_refreshes = 0; if (!init_buffer_status) return; /* caller reenables */ if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) { TSError("couldn't retrieve server response header\n"); return; /* caller reenables */ } /* TSqa06246/TSqa06144 */ resp_status = TSHttpHdrStatusGet(resp_bufp, resp_loc); if (TS_HTTP_STATUS_OK == resp_status) { TSDebug("resphdr", "Processing 200 OK"); TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */ TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc); /* copy name/values created at init * ( "x-num-served-from-cache" ) : ( "0" ) */ TSMimeHdrFieldCopy(resp_bufp, resp_loc, new_field_loc, hdr_bufp, hdr_loc, field_loc); /*********** Unclear why this is needed **************/ TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc); /* Cache-Control: Public */ TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */ TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc); TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc); TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, TS_MIME_FIELD_CACHE_CONTROL, TS_MIME_LEN_CACHE_CONTROL); TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, new_field_loc, -1, TS_HTTP_VALUE_PUBLIC, TS_HTTP_LEN_PUBLIC); /* * mimehdr2_name = TSstrdup( "x-date-200-recvd" ) : CurrentDateTime */ TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */ TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc); TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc); TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, mimehdr2_name, strlen(mimehdr2_name)); recvd_time = time(NULL); TSMimeHdrFieldValueDateInsert(resp_bufp, resp_loc, new_field_loc, recvd_time); TSHandleMLocRelease(resp_bufp, resp_loc, new_field_loc); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); } else if (TS_HTTP_STATUS_NOT_MODIFIED == resp_status) { TSDebug("resphdr", "Processing 304 Not Modified"); /* N.B.: Protect writes to data (hash on URL + mutex: (ies)) */ /* Get the cached HTTP header */ if (TSHttpTxnCachedRespGet(txnp, &cached_bufp, &cached_loc) != TS_SUCCESS) { TSError("STATUS 304, TSHttpTxnCachedRespGet():"); TSError("couldn't retrieve cached response header\n"); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); return; /* Caller reenables */ } /* Get the cached MIME field name for this HTTP header */ cached_field_loc = TSMimeHdrFieldFind(cached_bufp, cached_loc, (const char *)mimehdr1_name, strlen(mimehdr1_name)); if (TS_NULL_MLOC == cached_field_loc) { TSError("Can't find header %s in cached document", mimehdr1_name); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc); return; /* Caller reenables */ } /* Get the cached MIME value for this name in this HTTP header */ chkptr = TSMimeHdrFieldValueStringGet(cached_bufp, cached_loc, cached_field_loc, -1, &chklength); if (NULL == chkptr || !chklength) { TSError("Could not find value for cached MIME field name %s", mimehdr1_name); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc); TSHandleMLocRelease(cached_bufp, cached_loc, cached_field_loc); return; /* Caller reenables */ } TSDebug("resphdr", "Header field value is %s, with length %d", chkptr, chklength); /* Get the cached MIME value for this name in this HTTP header */ /* TSMimeHdrFieldValueUintGet(cached_bufp, cached_loc, cached_field_loc, 0, &num_refreshes); TSDebug("resphdr", "Cached header shows %d refreshes so far", num_refreshes ); num_refreshes++ ; */ /* txn origin server response for this transaction stored * in resp_bufp, resp_loc * * Create a new MIME field/value. Cached value has been incremented. * Insert new MIME field/value into the server response buffer, * allow HTTP processing to continue. This will update * (indirectly invalidates) the cached HTTP headers MIME field. * It is apparently not necessary to update all of the MIME fields * in the in-process response in order to have the cached response * become invalid. */ TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probaby should check for errrors */ /* mimehdr1_name : TSstrdup( "x-num-served-from-cache" ) ; */ TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc); TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, mimehdr1_name, strlen(mimehdr1_name)); TSMimeHdrFieldValueUintInsert(resp_bufp, resp_loc, new_field_loc, -1, num_refreshes); TSHandleMLocRelease(resp_bufp, resp_loc, new_field_loc); TSHandleMLocRelease(cached_bufp, cached_loc, cached_field_loc); TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc); TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc); } else { TSDebug("resphdr", "other response code %d", resp_status); } /* * Additional 200/304 processing can go here, if so desired. */ /* Caller reneables */ }