int insert_in_response(INKHttpTxn txnp, char *result_val) { INKMBuffer resp_bufp; INKMLoc resp_loc; INKMLoc field_loc; LOG_SET_FUNCTION_NAME("insert_in_response"); #ifdef DEBUG if (INKHttpTxnClientRespGet(NULL, &resp_bufp, &resp_loc) != 0) { LOG_ERROR_NEG("INKHttpTxnClientRespGet(null, buf, hdr_loc)"); } if (INKHttpTxnClientRespGet(txnp, NULL, &resp_loc) != 0) { LOG_ERROR_NEG("INKHttpTxnClientRespGet(txnp, null, hdr_loc)"); } if (INKHttpTxnClientRespGet(txnp, &resp_bufp, NULL) != 0) { LOG_ERROR_NEG("INKHttpTxnClientRespGet(txnp, buf, null)"); } #endif if (!INKHttpTxnClientRespGet(txnp, &resp_bufp, &resp_loc)) { LOG_ERROR_AND_RETURN("INKHttpTxnClientRespGet"); } /* create a new field in the response header */ if ((field_loc = INKMimeHdrFieldCreate(resp_bufp, resp_loc)) == INK_ERROR_PTR) { INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc); LOG_ERROR_AND_RETURN("INKMimeHdrFieldCreate"); } /* set its name */ if (INKMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, "CacheTester-Result", 18) == INK_ERROR) { INKHandleMLocRelease(resp_bufp, resp_loc, field_loc); INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc); LOG_ERROR_AND_RETURN("INKMimeHdrFieldNameSet"); } /* set its value */ if (INKMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, result_val, strlen(result_val)) == INK_ERROR) { INKHandleMLocRelease(resp_bufp, resp_loc, field_loc); INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc); LOG_ERROR_AND_RETURN("INKMimeHdrFieldValueIntInsert"); } /* insert it into the header */ if (INKMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc) == INK_ERROR) { INKHandleMLocRelease(resp_bufp, resp_loc, field_loc); INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc); LOG_ERROR_AND_RETURN("INKMimeHdrFieldAppend"); } if (INKHandleMLocRelease(resp_bufp, resp_loc, field_loc) == INK_ERROR) { INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc); LOG_ERROR_AND_RETURN("INKHandleMLocRelease"); } if (INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc) == INK_ERROR) { LOG_ERROR_AND_RETURN("INKHandleMLocRelease"); } return 1; }
static void handleSendResponse(INKCont pCont, INKHttpTxn pTxn) { LOG_SET_FUNCTION_NAME("handleSendResponse"); INKMBuffer respHdrBuf = NULL, newHttpHdrBuf = NULL, parseBuffer = NULL; INKMLoc respHttpHdrLoc = NULL, newHttpHdrLoc = NULL, parseHttpHdrLoc = NULL; INKHttpStatus oldHttpStatus, tmpHttpStatus; INKHttpType httpType; INKHttpParser httpRespParser = NULL; HdrInfo_T *pRespHdrInfo = NULL, *pNewRespHdrInfo = NULL; int iHttpHdrReasonLength, iOldHttpVersion, iTmpHttpVersion, iTmpHttpHdrReasonLength; const char *sHttpHdrReason = NULL, *sTmpHttpHdrReason = NULL, *pHttpParseStart = NULL, *pHttpParseEnd = NULL; char *sOldHttpReason = NULL; const char *sRespHdrStr1 = "HTTP/1.1 200 OK\r\nServer: Netscape-Enterprise/4.1\r\nDate: Tue, 31 Oct 2000 03:38:19 GMT\r\nContent-type: text/html\r\nAge: 3476\r\nContent-Length: 12440\r\nVia: HTTP/1.1 ts-sun14 (Traffic-Server/4.0.0 [cHs f ])\r\n\r\n"; const char *sRespHdrStr2 = "HTTP/1.1 404 Not Found \r\nServer: Netscape-Enterprise/4.1\r\nDate: Tue, 31 Oct 2000 03:38:19 GMT\r\nContent-type: text/html\r\nAge: 3476\r\nContent-Length: 12440\r\nVia: HTTP/1.1 ts-sun24 (Traffic-Server/4.0.0 [cHs f ])\r\n\r\n"; const char *sRespHdrStr3 = "HTTP/1.1 505 HTTP Version Not Supported \r\nServer: Netscape-Enterprise/4.1\r\nDate: Tue, 31 Oct 2000 03:38:19 GMT\r\nContent-type: text/html\r\nAge: 3476\r\nContent-Length: 12440\r\nVia: HTTP/1.1 ts-sun34 (Traffic-Server/4.0.0 [cHs f ])\r\n\r\n"; pRespHdrInfo = initHdr(); pNewRespHdrInfo = initHdr(); INKDebug(RESP, ">>> handleSendResponse <<<<\n"); /* Get Response Marshall Buffer */ if (!INKHttpTxnClientRespGet(pTxn, &respHdrBuf, &respHttpHdrLoc)) { LOG_API_ERROR_COMMENT("INKHttpTxnClientReqGet", "ERROR: Can't retrieve client req hdr"); goto done; } #ifdef DEBUG negTesting(respHdrBuf, respHttpHdrLoc); #endif /******* (1): Exercise all possible INK*GET and print the values **********/ INKDebug(RESP, "--------------------------------"); getHdrInfo(pRespHdrInfo, respHdrBuf, respHttpHdrLoc); printHttpHeader(respHdrBuf, respHttpHdrLoc, RESP, 1); /******* (2): Create a new header and check everything is copied correctly *********/ INKDebug(RESP, "--------------------------------"); if ((newHttpHdrBuf = INKMBufferCreate()) == INK_ERROR_PTR) { LOG_API_ERROR_COMMENT("INKMBufferCreate", "skipping to section(4)"); goto resp_4; } /*** INKHttpHdrCreate ***/ if ((newHttpHdrLoc = INKHttpHdrCreate(newHttpHdrBuf)) == INK_ERROR_PTR) { LOG_API_ERROR_COMMENT("INKMHTTPHdrCreate", "skipping to section(4)"); goto resp_4; } /* Make sure the newly created HTTP header has INKHttpType value of INK_HTTP_TYPE_UNKNOWN */ if ((httpType = INKHttpHdrTypeGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR_COMMENT("INKMHTTPHdrCreate", "continuing"); } else if (httpType != INK_HTTP_TYPE_UNKNOWN) { LOG_AUTO_ERROR("INKHttpHdrCreate", "Newly created hdr not of type INK_HTTP_TYPE_UNKNOWN"); } /*** INKHttpHdrCopy ***/ if (INKHttpHdrCopy(newHttpHdrBuf, newHttpHdrLoc, respHdrBuf, respHttpHdrLoc) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrCopy"); } getHdrInfo(pNewRespHdrInfo, newHttpHdrBuf, newHttpHdrLoc); printHttpHeader(newHttpHdrBuf, newHttpHdrLoc, RESP, 2); if (!identical_hdr(pRespHdrInfo, pNewRespHdrInfo)) { LOG_AUTO_ERROR("INKHttpHdrCopy", "copy of the resp header not identical to the original"); } /* Reuse: * newHttpHdrBuf, newHttHdrLoc */ /******* (3): Now excercise some INK..SETs on the new header ********/ INKDebug(RESP, "--------------------------------"); /*** INKHttpHdrTypeSet ***/ /* ERROR: * 1. Setting type other than INK_HTTP_TYPE_UNKNOWN, INK_HTTP_TYPE_REQUEST, * INK_HTTP_TYPE_RESPONSE, and, * 2. Setting the type twice. The hdr type has been already set during INKHttpHdrCopy * above, so setting it again is incorrect */ if (INKHttpHdrTypeSet(newHttpHdrBuf, newHttpHdrLoc, INK_HTTP_TYPE_RESPONSE) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrTypeSet"); } /*** INKHttpHdrReasonSet ***/ /* save the original reason */ if ((sHttpHdrReason = INKHttpHdrReasonGet(newHttpHdrBuf, newHttpHdrLoc, &iHttpHdrReasonLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrReasonGet"); } else { sOldHttpReason = INKstrndup(sHttpHdrReason, iHttpHdrReasonLength); } /* Note: * INKHttpHdrReasonGet may return a NULL reason string (for e.g. I tried www.eyesong.8m.com). * Do NOT assume that INKstrndup always returns a null terminated string. INKstrndup does * not returns a NULL terminated string for a NULL ptr as i/p parameter. It simply returns * it backs. So functions like strlen() on the return value might cause TS to crash */ if (INKHttpHdrReasonSet(newHttpHdrBuf, newHttpHdrLoc, "dummy reason", strlen("dummy reason")) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrReasonGet"); } else { if ((sTmpHttpHdrReason = INKHttpHdrReasonGet(newHttpHdrBuf, newHttpHdrLoc, &iTmpHttpHdrReasonLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrReasonGet"); } else if (sTmpHttpHdrReason && strncmp(sTmpHttpHdrReason, "dummy reason", iTmpHttpHdrReasonLength)) { LOG_AUTO_ERROR("INKHttpHdrReasonSet/Get", "GET reason different from the SET reason"); } STR_RELEASE(newHttpHdrBuf, newHttpHdrLoc, sTmpHttpHdrReason); } /*** INKHttpStatusSet ***/ /* save the original value */ if ((oldHttpStatus = INKHttpHdrStatusGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusGet"); } /* change it to some unknown value */ if (INKHttpHdrStatusSet(newHttpHdrBuf, newHttpHdrLoc, INK_HTTP_STATUS_NONE) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusSet"); } else if ((tmpHttpStatus = INKHttpHdrStatusGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusGet"); } else if (tmpHttpStatus != INK_HTTP_STATUS_NONE) { LOG_AUTO_ERROR("INKHttpHdrStatusGet/Set", "GET status different from the SET status"); } /*** INKHttpHdrVersionSet ***/ /* get the original version */ if ((iOldHttpVersion = INKHttpHdrVersionGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } /* change it to some unknown version */ if (INKHttpHdrVersionSet(newHttpHdrBuf, newHttpHdrLoc, INK_HTTP_VERSION(10, 10)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionSet"); } else if ((iTmpHttpVersion = INKHttpHdrVersionGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } else if (INK_HTTP_MAJOR(iTmpHttpVersion) != 10 && INK_HTTP_MINOR(iTmpHttpVersion) != 10) { LOG_AUTO_ERROR("INKHttpHdrVersionSet", "GET version different from SET version"); } printHttpHeader(newHttpHdrBuf, newHttpHdrLoc, RESP, 3); /* Restore the original values */ /* Here we can't use strlen(sOldHttpReason) to set the length. This would crash TS if * sOldHttpReason happens to be NULL */ if (INKHttpHdrReasonSet(newHttpHdrBuf, newHttpHdrLoc, sOldHttpReason, iHttpHdrReasonLength) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrReasonSet"); } /*INKHttpHdrReasonSet (newHttpHdrBuf, newHttpHdrLoc, sOldHttpReason, strlen(sOldHttpReason)); */ if (INKHttpHdrStatusSet(newHttpHdrBuf, newHttpHdrLoc, oldHttpStatus) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusSet"); } if (INKHttpHdrVersionSet(newHttpHdrBuf, newHttpHdrLoc, iOldHttpVersion) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusSet"); } if (!identical_hdr(pRespHdrInfo, pNewRespHdrInfo)) { LOG_AUTO_ERROR("INK..SET", "Hdr values not properly restored"); } /* (3): clean-up */ STR_RELEASE(newHttpHdrBuf, newHttpHdrLoc, sHttpHdrReason); FREE(sOldHttpReason); resp_4: /******* (4): Now excercise some SETs on the response header ********/ INKDebug(RESP, "--------------------------------"); /*** INKHttpHdrReasonSet ***/ /* save the original reason */ if ((sHttpHdrReason = INKHttpHdrReasonGet(respHdrBuf, respHttpHdrLoc, &iHttpHdrReasonLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrReasonGet"); } else { sOldHttpReason = INKstrndup(sHttpHdrReason, iHttpHdrReasonLength); } /* change the reason phrase */ if (INKHttpHdrReasonSet(respHdrBuf, respHttpHdrLoc, "dummy reason", strlen("dummy reason")) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrReasonSet"); } if ((sTmpHttpHdrReason = INKHttpHdrReasonGet(respHdrBuf, respHttpHdrLoc, &iTmpHttpHdrReasonLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrReasonGet"); } else if (sTmpHttpHdrReason && strncmp(sTmpHttpHdrReason, "dummy reason", iTmpHttpHdrReasonLength)) { LOG_AUTO_ERROR("INKHttpHdrReasonSet/Get", "GET reason string different from SET reason"); } STR_RELEASE(respHdrBuf, respHttpHdrLoc, sTmpHttpHdrReason); /*** INKHttpStatusSet ***/ /* save the original value */ if ((oldHttpStatus = INKHttpHdrStatusGet(respHdrBuf, respHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusGet"); } /* change it to some unknown value */ if (INKHttpHdrStatusSet(respHdrBuf, respHttpHdrLoc, INK_HTTP_STATUS_NONE) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusSet"); } else if (INKHttpHdrStatusGet(respHdrBuf, respHttpHdrLoc) != INK_HTTP_STATUS_NONE) { LOG_AUTO_ERROR("INKHttpHdrStatusSet/GET", "GET status value different from SET status"); } /*** INKHttpHdrTypeSet ***/ /* ERROR: * 1. Setting type other than INK_HTTP_TYPE_UNKNOWN, INK_HTTP_TYPE_REQUEST, * INK_HTTP_TYPE_RESPONSE and, * 2. Setting the type twice. The hdr type has been already set during INKHttpTxnClientRespGet * above, so setting it again should fail */ if (INKHttpHdrTypeSet(respHdrBuf, respHttpHdrLoc, INK_HTTP_TYPE_RESPONSE) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrTypeSet"); } if (INKHttpHdrTypeGet(respHdrBuf, respHttpHdrLoc) == INK_HTTP_TYPE_UNKNOWN) { LOG_AUTO_ERROR("INKHttpHdrTypeSet/Get", "respHdrBuf CAN be set to INK_HTTP_TYPE_UNKNOWN"); } /*** INKHttpHdrVersionSet ***/ /* get the original version */ if ((iOldHttpVersion = INKHttpHdrVersionGet(respHdrBuf, respHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } /* change it to some unknown version */ if (INKHttpHdrVersionSet(respHdrBuf, respHttpHdrLoc, INK_HTTP_VERSION(10, 10)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionSet"); } else if ((iTmpHttpVersion = INKHttpHdrVersionGet(respHdrBuf, respHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } else if (INK_HTTP_MAJOR(iTmpHttpVersion) != 10 && INK_HTTP_MINOR(iTmpHttpVersion) != 10) { LOG_AUTO_ERROR("INKHttpHdrVersionGet/Set", "GET HTTP version different from SET version"); } printHttpHeader(respHdrBuf, respHttpHdrLoc, RESP, 4); /* restore the original values */ /* For INKHttpHdrReasonSet, do NOT use strlen(sOldHttpReason) to set the length. * This would crash TS if sOldHttpReason happened to be NULL */ if (INKHttpHdrReasonSet(respHdrBuf, respHttpHdrLoc, sOldHttpReason, iHttpHdrReasonLength) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrReasonSet"); } /*INKHttpHdrReasonSet (respHdrBuf, respHttpHdrLoc, sOldHttpReason, strlen(sOldHttpReason)); */ if (INKHttpHdrStatusSet(respHdrBuf, respHttpHdrLoc, oldHttpStatus) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrStatusSet"); } if (INKHttpHdrVersionSet(respHdrBuf, respHttpHdrLoc, iOldHttpVersion) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionSet"); } FREE(pNewRespHdrInfo->hdrReason); getHdrInfo(pNewRespHdrInfo, respHdrBuf, respHttpHdrLoc); if (!identical_hdr(pRespHdrInfo, pNewRespHdrInfo)) { LOG_AUTO_ERROR("INK..SET", "Hdr values not properly restored"); } /* (4): clean-up */ STR_RELEASE(respHdrBuf, respHttpHdrLoc, sHttpHdrReason); FREE(sOldHttpReason); /********************************/ /** (5): INKHttpHdrParseResp **/ /********************************/ INKDebug(RESP, "--------------------------------"); /* Create a parser Buffer and header location */ if ((parseBuffer = INKMBufferCreate()) == INK_ERROR_PTR || parseBuffer == NULL) { LOG_API_ERROR_COMMENT("INKMBufferCreate", "abnormal exit"); goto done; } else if ((parseHttpHdrLoc = INKHttpHdrCreate(parseBuffer)) == INK_ERROR_PTR || parseHttpHdrLoc == NULL) { LOG_API_ERROR_COMMENT("INKHttpHdrCreate", "abnormal exit"); goto done; } pHttpParseStart = sRespHdrStr1; pHttpParseEnd = pHttpParseStart + strlen(pHttpParseStart); httpRespParser = INKHttpParserCreate(); if (INKHttpHdrParseResp(httpRespParser, parseBuffer, parseHttpHdrLoc, &pHttpParseStart, pHttpParseEnd) == INK_PARSE_ERROR) { LOG_API_ERROR("INKHttpHdrParseResp"); } printHttpHeader(parseBuffer, parseHttpHdrLoc, RESP, 5.1); if (INKHttpParserClear(httpRespParser) == INK_ERROR) { LOG_API_ERROR("INKHttpParseClear"); } INKDebug(RESP, "--------------------------------"); pHttpParseStart = sRespHdrStr2; pHttpParseEnd = pHttpParseStart + strlen(pHttpParseStart); /* httpRespParser = INKHttpParserCreate(); */ if (INKHttpHdrParseResp(httpRespParser, parseBuffer, parseHttpHdrLoc, &pHttpParseStart, pHttpParseEnd) == INK_PARSE_ERROR) { LOG_API_ERROR("INKHttpHdrParseResp"); } printHttpHeader(parseBuffer, parseHttpHdrLoc, RESP, 5.2); if (INKHttpParserClear(httpRespParser) == INK_ERROR) { LOG_API_ERROR("INKHttpParseClear"); } INKDebug(RESP, "--------------------------------"); pHttpParseStart = sRespHdrStr3; pHttpParseEnd = pHttpParseStart + strlen(pHttpParseStart); /* httpRespParser = INKHttpParserCreate(); */ if (INKHttpHdrParseResp(httpRespParser, parseBuffer, parseHttpHdrLoc, &pHttpParseStart, pHttpParseEnd) == INK_PARSE_ERROR) { LOG_API_ERROR("INKHttpHdrParseResp"); } printHttpHeader(parseBuffer, parseHttpHdrLoc, RESP, 5.3); done: /* Clean-up */ freeHdr(pRespHdrInfo); freeHdr(pNewRespHdrInfo); /* release hdrLoc */ HANDLE_RELEASE(respHdrBuf, INK_NULL_MLOC, respHttpHdrLoc); HANDLE_RELEASE(newHttpHdrBuf, INK_NULL_MLOC, newHttpHdrLoc); HANDLE_RELEASE(parseBuffer, INK_NULL_MLOC, parseHttpHdrLoc); /* destroy hdrLoc */ HDR_DESTROY(respHdrBuf, respHttpHdrLoc); HDR_DESTROY(parseBuffer, parseHttpHdrLoc); /* destroy mbuffer */ BUFFER_DESTROY(newHttpHdrBuf); BUFFER_DESTROY(parseBuffer); /* destroy the parser */ if (INKHttpParserDestroy(httpRespParser) == INK_ERROR) { LOG_API_ERROR("INKHttpParserDestroy"); } if (INKHttpTxnReenable(pTxn, INK_EVENT_HTTP_CONTINUE) == INK_ERROR) { LOG_API_ERROR("INKHttpTxnReenable"); } INKDebug(RESP, "......... exiting handleRespResponse .............\n"); } /* handleSendResponse */