/************************************************ * Description: * Find a entry for the given rowId and Key * Converted * input * pFile -- File Handler * rowId -- row id * key -- value * curIdxRidListHdrPtr - point to the header * output * lbid -- File block id * sbid -- Sub Block id * entry -- Entry id * * * return value * true --found * false--not found ************************************************/ const int IndexList::findFirstBlk(FILE* pFile, const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr, uint64_t& lbid) { int rc; CommBlock cb; int count; cb.file.oid = m_oid; cb.file.pFile = pFile; m_pFile = pFile; rc = getHdrInfo(curIdxRidListHdrPtr); if (key!= m_curIdxRidListHdr.key) { return ERR_IDX_LIST_INVALID_KEY;; } int type = m_curIdxRidListHdr.nextIdxRidListPtr.type; switch (type) { case LIST_NOT_USED_TYPE://Header is not full, no sub-block linked lbid = INVALID_LBID; return NO_ERROR; //not found case LIST_RID_TYPE:// There is a row id here, Check! lbid = INVALID_LBID; return NO_ERROR; //not found case LIST_SUBBLOCK_TYPE://Not found in header //get the lbid sbid and entry out from the header last entry rc = getSubBlk(m_lbid, m_sbid, m_entry ); m_curType = type; if (m_lbid != m_hdrLbid) rc =readCurBlk(); rc = getNextInfoFromBlk(m_lastIdxRidListPtr); count = m_lastIdxRidListPtr.count; //current count type = m_lastIdxRidListPtr.type; //block type if (type==LIST_BLOCK_TYPE) lbid = ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->fbo; else lbid = INVALID_LBID; return NO_ERROR; break; default: //printf ("FIND FIRST BLOCK got no where, error out !! \n"); break; }; //end switch lbid =INVALID_LBID; return NO_ERROR; } //end function
/************************************************ * Description: * Find a entry for the given rowId and Key * Converted * input * pFile -- File Handler * rowId -- row id * key -- value * curIdxRidListHdrPtr - point to the header * output * lbid -- File block id * sbid -- Sub Block id * entry -- Entry id * * * return value * true --found * false--not found ************************************************/ bool IndexList::findRowId(FILE* pFile, const RID& rowId, const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr, uint64_t& lbid, int& sbid, int& entry) { bool found = false; int rc; m_pFile = pFile; rc = getHdrInfo(curIdxRidListHdrPtr); if (key!= m_curIdxRidListHdr.key) { return false; } found = findRowId(rowId, key, lbid, sbid, entry); return found; }
/************************************************ * Description: * Converted * Find an entry for the given rowId and Key * Then Delete it from the list * Move the rest of the row id up in the same * sub block an decrement the count in that subblock * decrement the header size * input * pFile -- File Handler * rowId -- row id * key -- value * curIdxRidListHdrPtr - point to the header * * return value * Success -- 0 * Fail -- ERR_IDX_LIST_INVALID_DELETE ************************************************/ const int IndexList::deleteIndexList( FILE* pFile, const RID& rowId, const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr, uint64_t& lbid, int&sbid, int& entry) { int rc =ERR_IDX_LIST_INVALID_DELETE; bool found = false; m_pFile = pFile; getHdrInfo(curIdxRidListHdrPtr); if (key!= m_curIdxRidListHdr.key) { return ERR_IDX_LIST_INVALID_KEY; } uint64_t dlbid =-1LL; int dsbid = -1; int dentry = -1; rc = deleteIndexList(rowId,key,dlbid,dsbid,dentry); if (rc!=NO_ERROR) { lbid=-1LL; sbid =-1; entry=-1; found = false; return rc; } else { lbid = dlbid; sbid = dsbid; entry = dentry; } return rc; }
const int IndexList::getRIDArrayFromListHdrNarray(FILE* pFile, uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr, RID* ridArray, int& size, bool flag) { int rc=NO_ERROR; IdxRidNextListPtr *nextIdxListPtr; int pos =0, totalbytes=0; IdxRidListPtr *lastIdxRidListPtr; IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY*10]; int type=0, count=0; m_pFile = pFile; CommBlock cb; cb.file.oid = m_oid; cb.file.pFile = m_pFile; if (flag) { rc = getHdrInfo(curIdxRidListHdrPtr); if (m_curIdxRidListHdr.idxRidListSize.size==0) {size =0; return NO_ERROR;} if (key!= m_curIdxRidListHdr.key) { return ERR_IDX_LIST_WRONG_KEY; } // cout << "IndexList::getRIDArrayFromListHdr->KEY ------>" << key << endl; //Check the first row location, 3rd enty if (m_curIdxRidListHdr.firstIdxRidListEntry.type==(int)LIST_RID_TYPE) { ridArray[size]= (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid; //cout<<" IndexList::getRIDArrayFromListHdr->header Lbid->" << m_hdrLbid <<" count->" << arrayCount <<endl; size++; //cout << "RID = " << (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid << endl; }; //Check Header last entry's type int type = m_curIdxRidListHdr.nextIdxRidListPtr.type; switch (type) { case LIST_RID_TYPE:// There is a row id here, Check! ridArray[size]=(RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp; //cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl; size++; //cout << "RID = " << (RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp << endl; return NO_ERROR; case LIST_SUBBLOCK_TYPE://Not found in header, so go to the sub-block //get thelbid sbid and entry out from the header last entry m_lbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo; m_sbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid; m_entry=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry; m_curType = type; //Read the pointer entry at LIST_SUB_LLP_POS location memset(rowIdArray,0,BYTE_PER_BLOCK); pos = LIST_SUB_LLP_POS; totalbytes = SUBBLOCK_TOTAL_BYTES; if (m_lbid!=m_hdrLbid) { rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, m_sbid, 0, totalbytes, rowIdArray); m_curBlock.lbid = m_lbid; m_curBlock.state = BLK_READ; m_curBlock.dirty = true; } else getSubBlockEntry(m_hdrBlock.data, m_sbid, 0, totalbytes, rowIdArray ); lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos]; type = lastIdxRidListPtr->type; count = lastIdxRidListPtr->count; //cout << "count->" << count << endl; //type should be LIST_BLOCK_TYPE from now on for (int i=0; i<count; i++) { ridArray[size]= (RID)(rowIdArray[i].rid); //cout << "RID =" << (RID)(rowIdArray[i].rid) << endl; //cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl; size++; } //cout << " Lbid->" << m_lbid ; //cout << " count->" << count << endl; m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo; m_curType = type; }//end of switch }//end if flag if (m_curType ==LIST_BLOCK_TYPE) { pos = LIST_BLOCK_LLP_POS; totalbytes = BYTE_PER_BLOCK; rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, 0 , 0, totalbytes, rowIdArray); m_curBlock.lbid = m_lbid; m_curBlock.state = BLK_READ; m_curBlock.dirty = true; nextIdxListPtr = (IdxRidNextListPtr *)&rowIdArray[pos]; type = nextIdxListPtr->type; count = nextIdxListPtr->count; for (int i=0; i<count; i++) { ridArray[size]=(RID)(rowIdArray[i].rid) ; size++; } IdxRidListArrayPtr idxRidListArrayPtr; int curLevel = 0, curCount=0; memset(&idxRidListArrayPtr, 0, sizeof(idxRidListArrayPtr)); getSubBlockEntry(m_curBlock.data, 0, BEGIN_LIST_BLK_LLP_POS, LIST_BLK_LLP_ENTRY_WIDTH, &idxRidListArrayPtr); curLevel = idxRidListArrayPtr.nextIdxListPtr.curLevel; curCount = idxRidListArrayPtr.nextIdxListPtr.count; for (int i=0; i<TOTAL_NUM_ARRAY_PTR; i++) { m_lbid = idxRidListArrayPtr.childIdxRidListPtr[i].childLbid; int type = idxRidListArrayPtr.childIdxRidListPtr[i].type; if ((m_lbid != (uint64_t)INVALID_LBID) &&(type == LIST_BLOCK_TYPE)) { m_curType=LIST_BLOCK_TYPE; getRIDArrayFromListHdrNarray(pFile,key,curIdxRidListHdrPtr, ridArray, size, false); } } }//end if block return rc; }//end getRIDArrayFromListHdrNarray
/************************************************ * Description: * Converted * Find all of the row Id or toke from list * input * pFile -- File Handler * curIdxRidListHdrPtr - point to the header * * return value * Success -- 0 * Fail -- ERR_IDX_LIST_INVALID_DELETE ************************************************/ const int IndexList::getRIDArrayFromListHdr(FILE* pFile, uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr, RID* ridArray, int& size) { int rc=NO_ERROR; int arrayCount = 0; IdxRidNextListPtr *nextIdxListPtr = NULL; m_pFile = pFile; CommBlock cb; cb.file.oid = m_oid; cb.file.pFile = m_pFile; rc = getHdrInfo(curIdxRidListHdrPtr); if (m_curIdxRidListHdr.idxRidListSize.size==0) {size =0; return NO_ERROR;} if (key!= m_curIdxRidListHdr.key) { return ERR_IDX_LIST_WRONG_KEY; } // cout << "IndexList::getRIDArrayFromListHdr->KEY ------>" << key << endl; //Check the first row location, 3rd enty if (m_curIdxRidListHdr.firstIdxRidListEntry.type==(int)LIST_RID_TYPE) { ridArray[arrayCount]= (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid; //cout<<" IndexList::getRIDArrayFromListHdr->header Lbid->" << m_hdrLbid <<" count->" << arrayCount <<endl; arrayCount++; //cout << "RID = " << (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid << endl; }; //Check Header last entry's type int type = m_curIdxRidListHdr.nextIdxRidListPtr.type; switch (type) { case LIST_RID_TYPE:// There is a row id here, Check! ridArray[arrayCount]=(RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp; //cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl; arrayCount++; //cout << "RID = " << (RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp << endl; size = arrayCount; return NO_ERROR; case LIST_SUBBLOCK_TYPE://Not found in header, so go to the sub-block //get thelbid sbid and entry out from the header last entry m_lbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo; m_sbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid; m_entry=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry; m_curType = type; //Read the pointer entry at LIST_SUB_LLP_POS location IdxRidListPtr *lastIdxRidListPtr; IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY]; memset(rowIdArray,0,BYTE_PER_BLOCK); int pos =0, totalbytes=0; pos = LIST_SUB_LLP_POS; totalbytes = SUBBLOCK_TOTAL_BYTES; if (m_lbid!=m_hdrLbid) { rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, m_sbid, 0, totalbytes, rowIdArray); m_curBlock.lbid = m_lbid; m_curBlock.state = BLK_READ; m_curBlock.dirty = true; } else getSubBlockEntry(m_hdrBlock.data, m_sbid, 0, totalbytes, rowIdArray ); int type, count; lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos]; type = lastIdxRidListPtr->type; count = lastIdxRidListPtr->count; //cout << "count->" << count << endl; //type should be LIST_BLOCK_TYPE from now on for (int i=0; i<count; i++) { ridArray[arrayCount]= (RID)(rowIdArray[i].rid); //cout << "RID =" << (RID)(rowIdArray[i].rid) << endl; //cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl; arrayCount++; } //cout << " Lbid->" << m_lbid ; //cout << " count->" << count << endl; m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo; while (type ==LIST_BLOCK_TYPE) { //cout << " Lbid->" << m_lbid ; pos = LIST_BLOCK_LLP_POS; totalbytes = BYTE_PER_BLOCK; rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, 0 , 0, totalbytes, rowIdArray); m_curBlock.lbid = m_lbid; m_curBlock.state = BLK_READ; m_curBlock.dirty = true; if (!m_useNarray) { lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos]; type = lastIdxRidListPtr->type; count = lastIdxRidListPtr->count; } else { nextIdxListPtr = (IdxRidNextListPtr *)&rowIdArray[pos]; type = nextIdxListPtr->type; count = nextIdxListPtr->count; } //cout << " count->" << count << endl; for (int i=0; i<count; i++) { ridArray[arrayCount]=(RID)(rowIdArray[i].rid) ; //cout << "RID =" << (RID)(rowIdArray[i].rid) << endl; //cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl; arrayCount++; } if (type ==LIST_BLOCK_TYPE) { if (m_useNarray) m_lbid = nextIdxListPtr->nextLbid; else m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo; } }//end while };//end of switch size = arrayCount; return rc; }//end getRIDArrayFromListHdr
static void handleReadRequest(INKCont pCont, INKHttpTxn pTxn) { LOG_SET_FUNCTION_NAME("handleReadRequest"); INKMBuffer reqHdrBuf = NULL, newHttpHdrBuf = NULL; INKMLoc reqHdrLoc = NULL, newHttpHdrLoc = NULL; INKHttpType httpType; int iOldHttpVersion, iHttpMethodLength, iHttpVersion; const char *sHttpMethod = NULL; char *outputString = NULL, *sOldHttpMethod = NULL; HdrInfo_T *pReqHdrInfo = NULL, *pNewReqHdrInfo = NULL; #if 0 const char *constant_request_header_str = "GET http://www.joes-hardware.com/ HTTP/1.0\r\nDate: Wed, 05 Jul 2000 22:12:26 GMT\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.51 [en] (X11; U; IRIX 6.2 IP22)\r\nHost: www.joes-hardware.com\r\nCache-Control: no-cache\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\nAccept-Charset: iso-8859-1,*,utf-8\r\nAccept-Encoding: gzip\r\nAccept-Language: en\r\nX-Number-Header: 12345\r\nX-Silly-Header: frobnichek grobbledegook\r\nAccept-Charset: windows-1250, koi8-r\r\nX-Silly-Header: wawaaa\r\n\r\n"; #endif pReqHdrInfo = initHdr(); pNewReqHdrInfo = initHdr(); INKDebug(REQ, "\n>>>>>> handleReadRequest <<<<<<<\n"); /* Get Request Marshall Buffer */ if (!INKHttpTxnClientReqGet(pTxn, &reqHdrBuf, &reqHdrLoc)) { LOG_API_ERROR_COMMENT("INKHttpTxnClientReqGet", "ERROR: Can't retrieve client req hdr"); goto done; } /******* (1): Get every specifics from the HTTP header *********/ INKDebug(REQ, "--------------------------------"); getHdrInfo(pReqHdrInfo, reqHdrBuf, reqHdrLoc); printHttpHeader(reqHdrBuf, reqHdrLoc, REQ, 1); #ifdef DEBUG negTesting(reqHdrBuf, reqHdrLoc); #endif /*********** (2): Create/Copy/Destroy **********/ /* For every request, create, copy and destroy a new HTTP header and * print the details */ INKDebug(REQ, "--------------------------------"); if ((newHttpHdrBuf = INKMBufferCreate()) == INK_ERROR_PTR) { LOG_API_ERROR_COMMENT("INKMBufferCreate", "skipping to section 3"); goto section_3; /* Skip to section (3) down the line directly; I hate GOTOs */ } /*** INKHttpHdrCreate ***/ if ((newHttpHdrLoc = INKHttpHdrCreate(newHttpHdrBuf)) == INK_ERROR_PTR) { LOG_API_ERROR_COMMENT("INKHttpHdrCreate", "skipping to section 3"); goto section_3; /* Skip to section (3) down the line directly; I hate GOTOs */ } /* 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("INKHttpHdrTypeGet", "but still continuing..."); } else if (httpType != INK_HTTP_TYPE_UNKNOWN) { LOG_AUTO_ERROR("INKHttpHdrCreate", "Newly created hdr not of type INK_HTTP_TYPE_UNKNOWN"); } /* set the HTTP header type: a new buffer has a type INK_HTTP_TYPE_UNKNOWN by default */ if (INKHttpHdrTypeSet(newHttpHdrBuf, newHttpHdrLoc, INK_HTTP_TYPE_REQUEST) == INK_ERROR) { LOG_API_ERROR_COMMENT("INKHttpHdrTypeSet", "unable to set it to INK_HTTP_TYPE_REQUEST"); } else if ((httpType = INKHttpHdrTypeGet(newHttpHdrBuf, newHttpHdrLoc)) == INK_ERROR) { LOG_API_ERROR_COMMENT("INKHttpHdrTypeGet", "still continuing"); } else if (httpType != INK_HTTP_TYPE_REQUEST) { LOG_AUTO_ERROR("INKHttpHdrTypeSet", "Type not set to INK_HTTP_TYPE_REQUEST"); } /*** INKHttpHdrCopy ***/ if (INKHttpHdrCopy(newHttpHdrBuf, newHttpHdrLoc, reqHdrBuf, reqHdrLoc) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrCopy"); } getHdrInfo(pNewReqHdrInfo, newHttpHdrBuf, newHttpHdrLoc); if (!identical_hdr(pNewReqHdrInfo, pReqHdrInfo)) { LOG_AUTO_ERROR("INKHttpHdrCopy", "New req buffer not identical to the original"); } printHttpHeader(newHttpHdrBuf, newHttpHdrLoc, REQ, 2); FREE(pNewReqHdrInfo->httpMethod); FREE(pNewReqHdrInfo->hostName); section_3: /********* (3): Excercise all the INK__Set on ReqBuf *********/ INKDebug(REQ, "--------------------------------"); /*** INKHttpHdrMethodSet ***/ /* save the original method */ if ((sHttpMethod = INKHttpHdrMethodGet(reqHdrBuf, reqHdrLoc, &iHttpMethodLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrMethodGet"); } else { sOldHttpMethod = INKstrndup(sHttpMethod, iHttpMethodLength); } /* change it to some unknown method */ if (INKHttpHdrMethodSet(reqHdrBuf, reqHdrLoc, "FOOBAR", strlen("FOOBAR")) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrMethodSet"); } else { if ((sHttpMethod = INKHttpHdrMethodGet(reqHdrBuf, reqHdrLoc, &iHttpMethodLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrMethodGet"); } else if (strncmp(sHttpMethod, "FOOBAR", iHttpMethodLength)) { LOG_AUTO_ERROR("INKHttpHdrMethodSet/Get", "GET method different from SET method"); } } outputString = INKstrndup(sHttpMethod, iHttpMethodLength); INKDebug(REQ, "(3): new HTTP Header Method = %s", outputString); FREE(outputString); STR_RELEASE(reqHdrBuf, reqHdrLoc, sHttpMethod); printHttpHeader(reqHdrBuf, reqHdrLoc, REQ, 3); /* set it back to the original method */ /*INKHttpHdrMethodSet (reqHdrBuf, reqHdrLoc, sOldHttpMethod, iHttpMethodLength); */ if (INKHttpHdrMethodSet(reqHdrBuf, reqHdrLoc, sOldHttpMethod, strlen(sOldHttpMethod)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrMethodSet"); } else if ((sHttpMethod = INKHttpHdrMethodGet(reqHdrBuf, reqHdrLoc, &iHttpMethodLength)) == INK_ERROR_PTR) { LOG_API_ERROR("INKHttpHdrMethodGet"); } else if (strncmp(sHttpMethod, sOldHttpMethod, iHttpMethodLength)) { LOG_AUTO_ERROR("INKHttpHdrMethodSet/Get", "GET method different from SET method"); } outputString = INKstrndup(sHttpMethod, iHttpMethodLength); INKDebug(REQ, "(3): original HTTP Header Method = %s", outputString); FREE(outputString); STR_RELEASE(reqHdrBuf, reqHdrLoc, sHttpMethod); /*** INKHttpHdrVersionSet ***/ /* get the original version */ if ((iOldHttpVersion = INKHttpHdrVersionGet(reqHdrBuf, reqHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } /* change it to some unknown version */ if (INKHttpHdrVersionSet(reqHdrBuf, reqHdrLoc, INK_HTTP_VERSION(10, 10)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionSet"); } else if ((iHttpVersion = INKHttpHdrVersionGet(reqHdrBuf, reqHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } else if ((INK_HTTP_MAJOR(iHttpVersion) != 10) || (INK_HTTP_MINOR(iHttpVersion) != 10)) { LOG_AUTO_ERROR("INKHttpHdrVersionSet/Get", "SET HTTP version different from GET version"); } INKDebug(REQ, "(3): new HTTP version; Major = %d Minor = %d", INK_HTTP_MAJOR(iHttpVersion), INK_HTTP_MINOR(iHttpVersion)); /* change it back to the original version */ if (INKHttpHdrVersionSet(reqHdrBuf, reqHdrLoc, iOldHttpVersion) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionSet"); } else if ((iHttpVersion = INKHttpHdrVersionGet(reqHdrBuf, reqHdrLoc)) == INK_ERROR) { LOG_API_ERROR("INKHttpHdrVersionGet"); } else if (iHttpVersion != iOldHttpVersion) { LOG_AUTO_ERROR("INKHttpHdrVersionSet/Get", "SET HTTP version different from GET version"); } getHdrInfo(pNewReqHdrInfo, reqHdrBuf, reqHdrLoc); if (!identical_hdr(pNewReqHdrInfo, pReqHdrInfo)) { LOG_AUTO_ERROR("INK..Set", "ReqBuf: Values not restored properly"); } /* (3): clean-up */ FREE(sOldHttpMethod); done: /*************** Clean-up ***********************/ /* FREE(pReqHdrInfo->httpMethod); FREE(pReqHdrInfo->hostName); FREE(pNewReqHdrInfo->httpMethod); FREE(pNewReqHdrInfo->hostName); FREE(pReqHdrInfo); FREE(pNewReqHdrInfo); */ freeHdr(pReqHdrInfo); freeHdr(pNewReqHdrInfo); /* release hdrLoc */ HANDLE_RELEASE(reqHdrBuf, INK_NULL_MLOC, reqHdrLoc); HANDLE_RELEASE(newHttpHdrBuf, INK_NULL_MLOC, newHttpHdrLoc); /* destroy hdr */ HDR_DESTROY(newHttpHdrBuf, newHttpHdrLoc); /* destroy mbuffer */ BUFFER_DESTROY(newHttpHdrBuf); if (INKHttpTxnReenable(pTxn, INK_EVENT_HTTP_CONTINUE) == INK_ERROR) { LOG_API_ERROR("INKHttpTxnReenable"); } INKDebug(REQ, "..... exiting handleReadRequest ......\n"); } /* handleReadReadRequest */
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 */