private void validateFirstByteOfHeader(final int i, final int posIdx, final int lenIdx, final int memoIdx, final int stateIdx, Pipe<NetPayloadSchema> localInputPipe, HTTPClientConnection cc, int len) { //we may hit zero in the middle of a payload so this check //is only valid for the 0 state. if (len>0 && positionMemoData[stateIdx]==0) { //we have new data plus we know that we have no old data //because of this we know the first letter must be an H for HTTP. boolean isValid = localInputPipe.blobRing[localInputPipe.blobMask&trieReader.sourcePos]=='H'; if (!isValid) { logger.warn("invalid HTTP request from server should start with H"); if (null!=cc) { try { closeConnectionAndAbandonOldData(posIdx, lenIdx, stateIdx, cc, i); } catch (Throwable e) { //ignore this is not the source of the problem } } } } }
private long processHeaderLogic(int i, final int memoIdx, final int stateIdx, Pipe<NetPayloadSchema> localInputPipe, HTTPClientConnection cc, DataOutputBlobWriter<NetResponseSchema> writer) { long headerToken; int startingLength = TrieParserReader.savePositionMemo(trieReader, positionMemoData, memoIdx); //TODO = save position is wrong if we continue??? headerToken = TrieParserReader.parseNext(trieReader, cc.headerParser()); assert(headerToken==-1 || headerToken>=(Integer.MAX_VALUE-2)) : "bad token "+headerToken; int consumed = startingLength - trieReader.sourceLen; runningHeaderBytes[i] += consumed; if (headerToken != -1) { if (HTTPSpecification.END_OF_HEADER_ID != headerToken) { headerProcessing(i, writer, headerToken, cc); //do not change state we want to come back here. } else { endOfHeaderProcessing(i, memoIdx, stateIdx, localInputPipe, writer); } } return headerToken; }
HTTPSpecification<?,?,?,?> httpSpec) { super(graphManager, input, join(output,ackStop)); this.input = input; this.output = output.length==1 & input.length>1 ? reSizeArray(output[0],input.length) //we only have 1 output so all data must go there.
processFoundRevision(i, stateIdx, targetPipe, ccId, cc, startingLength1); assert(positionMemoData[stateIdx]==1); } else { maxIter = 0; } else { reportCorruptStream("HTTP revision", cc); closeConnectionAndAbandonOldData(posIdx, lenIdx, stateIdx, cc, i); headerToken = processHeaderLogic(i, memoIdx, stateIdx, localInputPipe, cc, writer); } while ((headerToken != -1) && positionMemoData[stateIdx]==1); if (headerToken == -1) { reportCorruptStream2(cc); foundWork += finishAndRelease(i, posIdx, lenIdx, stateIdx, localInputPipe, cc, 0); parseErrorWhileChunking(memoIdx, localInputPipe, trieReader.sourcePos); boolean foundEnd = consumeTralingHeaders(cc); if (!foundEnd) { logger.warn("unable to find end of message"); foundWork += finishAndRelease(i, posIdx, lenIdx, stateIdx, localInputPipe, cc, 0); foundWork += finishAndRelease(i, posIdx, lenIdx, stateIdx, localInputPipe, cc, 0);
closeConnectionAndAbandonOldData(posIdx, lenIdx, stateIdx, cc, i); continue; closeConnectionAndAbandonOldData(posIdx, lenIdx, stateIdx, cc, i); positionMemoData[posIdx] = pos; positionMemoData[lenIdx] = len; validateFirstByteOfHeader(i, posIdx, lenIdx, memoIdx, stateIdx, localInputPipe, cc, len); } else { positionMemoData[lenIdx] += len; targetPipe = output[i]; } else { closeConnectionAndAbandonOldData(posIdx, lenIdx, stateIdx, cc, i); continue; //was closed so we can not do anything with this connection assert(checkPipeWriteState(stateIdx, targetPipe)); foundWork = parseHTTP(foundWork, i, memoIdx, posIdx, lenIdx, stateIdx, targetPipe, ccId, localInputPipe, cc);
assert(confirmCoreHeadersSupported()); boolean verboseShowHeaders = false; if (verboseShowHeaders) { reportUnsupportedHeader(); //ignore since we did not want this
private void endOfHeaderProcessing(int i, final int memoIdx, final int stateIdx, Pipe<NetPayloadSchema> localInputPipe, DataOutputBlobWriter<NetResponseSchema> writer) { //logger.trace("end of headers"); positionMemoData[stateIdx] = endOfHeaderProcessing(i, stateIdx, writer); //logger.trace("finished reading header now going to state {}",state); if (3==positionMemoData[stateIdx]) { //release all header bytes, we will do each chunk on its own. assert(runningHeaderBytes[i]>0); Pipe.releasePendingAsReadLock(localInputPipe, runningHeaderBytes[i]); runningHeaderBytes[i] = 0; } //only case where state is not 1 so we must call save all others will call when while loops back to top. TrieParserReader.savePositionMemo(trieReader, positionMemoData, memoIdx); //logger.info("payload position {}", writer.position()); //NOTE: payload index position is always zero DataOutputBlobWriter.setIntBackData(writer, writer.position(), 0); }
while(--p >= 0) { HTTP1xResponseParserStage parser = new HTTP1xResponseParserStage(gm, request[p], response[p], ackRelease[p], ccm, HTTPSpecification.defaultSpec()); GraphManager.addNota(gm, GraphManager.DOT_RANK_NAME, "HTTPParser", parser); ccm.processNota(gm, parser); HTTP1xResponseParserStage parser = new HTTP1xResponseParserStage(gm, rawToParse, parsedResponse, ackRelease[0], ccm, HTTPSpecification.defaultSpec()); GraphManager.addNota(gm, GraphManager.DOT_RANK_NAME, "HTTPParser", parser); ccm.processNota(gm, parser);
private void processFoundRevision(int i, final int stateIdx, Pipe<NetResponseSchema> targetPipe, long ccId, HTTPClientConnection cc, int startingLength1) { clearConnectionStateData(i); //because we have started written the response we MUST do extra cleanup later. Pipe.addMsgIdx(targetPipe, NetResponseSchema.MSG_RESPONSE_101); Pipe.addLongValue(ccId, targetPipe); // NetResponseSchema.MSG_RESPONSE_101_FIELD_CONNECTIONID_1, ccId); Pipe.addIntValue(cc.sessionId, targetPipe); Pipe.addIntValue(ServerCoordinator.BEGIN_RESPONSE_MASK, targetPipe);//flags, init to zero, will set later if required positionMemoData[stateIdx]++;//state change is key DataOutputBlobWriter<NetResponseSchema> openOutputStream = Pipe.openOutputStream(targetPipe); DataOutputBlobWriter.tryClearIntBackData(openOutputStream, cc.totalSizeOfIndexes()); //NOTE: this is always first and not indexed... TrieParserReader.writeCapturedShort(trieReader, 0, openOutputStream); //status code runningHeaderBytes[i] = startingLength1 - trieReader.sourceLen; }