⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buffio.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					dwBytesToRecv = dwMaxBufferSize - m_iNextIn;
				else
					dwBytesToRecv = dwAvailable;

				if(!AllocMem(dwBytesToRecv+1))
					myretleave(INPUT_ERROR, 103);
			}	
			else {                       // Read in only requested amount of POST
				dwBytesToRecv = min(dwAvailable,dwBytesRemainingToBeRead);
				// we don't call AllocMem() here because we allocated all we'll need at top of function.
			}

			DEBUGMSG(ZONE_REQUEST_VERBOSE,(L"HTTPD: RecvToBuf: available bytes=%d, bytes we'll recv=%d\r\n",dwAvailable,dwBytesToRecv));
		}
#if defined (DEBUG)
		else
			DEBUGMSG(ZONE_REQUEST_VERBOSE,(L"HTTPD: RecvToBuf has %d bytes of data already from SSL negotiation, using it instead of calling recv()\r\n",m_iNextIn));
#endif

		DEBUGCHK((m_iSize-m_iNextIn) >= (int)dwBytesToRecv);
		BufferConsistencyChecks();

		int iRecv = 0;
		if (fSSLSkipFirstRead) {
			// We already have data from SSL handshake that needs to be decrypted.
			// trick receive logic into thinking we read preexisting data 
			// into buffer on the loop above.  After this point, there's no difference
			// between if we got data left over from handshake or if we got it from first receive 
			// at any point during the request.
			iRecv = m_iNextIn;
			m_iNextIn = 0;
			fSSLSkipFirstRead = FALSE;
		}
		else {
			// typical case, read data.
			iRecv = recv(sock, m_pszBuf+m_iNextIn, dwBytesToRecv, 0) ;
			DEBUGMSG(ZONE_SOCKET, (L"HTTPD: recv(%x) got %d\r\n", sock, iRecv));

			if (iRecv == 0 && !fForceSSLRenegotiate) {
				DEBUGMSG(ZONE_REQUEST_VERBOSE,(L"HTTPD: RecvToBuf: iRecv==0, m_iNextIn=%d\r\n",m_iNextIn));
				myretleave((m_iNextIn ? INPUT_OK : INPUT_TIMEOUT), 0); 
			} // got EOF. If we have any data return OK, else return TIMEOUT
			else if (iRecv == SOCKET_ERROR) { 
				DEBUGMSG(ZONE_REQUEST_VERBOSE,(L"HTTPD: RecvToBuf: iRecv==SOCKET_ERROR, m_iNextIn=%d\r\n",m_iNextIn));
				myretleave(((GetLastError()==WSAECONNRESET) ? INPUT_TIMEOUT : INPUT_ERROR), 104);
			}
		}

		// The following block is executed if we want to decrypt SSL.  When reading http
		// headers on secure channel, always do SSLDecrypt because we don't know how big headers 
		// will be.  When reading in POST data, if we know we haven't recv()'d enough data yet, call
		// recv() again before starting decryption as an optimization.
		if (fForceSSLRenegotiate || (fIsSecure && (fReadHeaders || (0 >= (int)dwBytesRemainingToBeRead-iRecv)))) {
			DWORD dwBytesDecryptedInCall=0, dwExtra=0, dwIgnore=0;
			DWORD dwSSLOffsetOrg = dwSSLOffset;
			DWORD dwDecLen = dwSSLOffset+iRecv;
			BOOL fCompletedRenegotiate = FALSE;

			// Calls into SSL/HTTP layer to perform decryption.  See function definition for explanation of paramaters.
			SECURITY_STATUS scRet = pRequest->SSLDecrypt(m_pszBuf+m_iNextDecrypt,
			                                   dwDecLen,&dwBytesDecryptedInCall,&dwSSLOffset,&dwExtra,&dwIgnore,&fCompletedRenegotiate);

			if ((scRet != SEC_E_OK) &&
			    (scRet != SEC_E_INCOMPLETE_MESSAGE)) {
			    DEBUGMSG(ZONE_ERROR,(L"HTTPD: SSLDecrypt fails, scRet=0x%08x\r\n",scRet));
				myretleave(INPUT_ERROR,115);
			}

			DEBUGMSG(ZONE_SSL_VERBOSE,(L"HTTPD: dwBytesDecryptedInCall=%d,dwBytesDecrypted=%d,dwIgnore=%d,dwBytesRemainingToBeRead=%d,dwDecLen=%d,dwSSLOffset=%d,dwSSLOffsetOrg=%d\r\n",
			                                    dwBytesDecryptedInCall,dwBytesDecrypted,dwIgnore,dwBytesRemainingToBeRead,dwDecLen,dwSSLOffset,dwSSLOffsetOrg));

			dwBytesDecrypted += dwBytesDecryptedInCall;
			m_iNextDecrypt   += dwBytesDecryptedInCall;

			// iRecv is number of bytes previous receive call got, however because 
			// we may be throwing out unneeded trailer information the next place
			// we read in may be a little lower than it was before call.
			if (scRet == SEC_E_OK)
				iRecv = (int)(dwBytesDecryptedInCall-dwSSLOffsetOrg);
			else
				iRecv -= (int) dwIgnore;

			dwBytesRemainingToBeRead -= dwIgnore;

			// we renegotiate and don't have any POST data to read, or have finished with POST data
			if (fForceSSLRenegotiate && fCompletedRenegotiate)  {
				DEBUGMSG(ZONE_SSL_VERBOSE,(L"HTTPD: SSLDecrypt completed negotiate, dwBytesDecryptedInCall=%d,m_iNextIn=%d\r\n",dwBytesDecryptedInCall,m_iNextIn + dwBytesDecryptedInCall));
				if (scRet == SEC_E_OK)
					m_iNextIn += iRecv;
				myretleave(scRet == S_OK ? INPUT_OK : INPUT_ERROR,119);
			}

			// Once we get 1st part of unencrypted data we'll start scanning over the HTTP headers.
			if (fReadHeaders && dwBytesDecryptedInCall)
				fScanHeadersForCRLF = TRUE;

			if (scRet == SEC_E_OK) {
				if (!fReadHeaders) {
					if (dwBytesDecrypted >= dwLength)
						dwBytesRemainingToBeRead = 0;
					else
						dwBytesRemainingToBeRead = iRecv + dwLength - dwBytesDecrypted;
				}
			}
			else if (scRet == SEC_E_INCOMPLETE_MESSAGE && !fReadHeaders)  {
				// We don't have complete message but we know how long it's going to be.
				// This will make main loop continue.  For Headers we just call elsewhere.
				DWORD dwBytesToAlloc;

				if (! safeIntUAdd(dwExtra,iRecv,(UINT*)&dwBytesToAlloc)) {
					DEBUGMSG(ZONE_ERROR,(L"HTTPD: ERROR: Integer overflow on attempting to allocate data\r\n"));
					DEBUGCHK(0);
					myretleave(INPUT_ERROR, 103);
				}

				if (!AllocMem(dwBytesToAlloc))
					myretleave(INPUT_ERROR, 103);

				dwBytesRemainingToBeRead += dwExtra;
			}

			// we've read all the POST data off the wire, however we still
			// need more packets to come across to contain the renegotiation information.
			if ((dwBytesRemainingToBeRead == 0) && fSSLRenegotiate && !fForceSSLRenegotiate) {
				DEBUGMSG(ZONE_SSL_VERBOSE,(L"HTTPD: All POST data read but still need renegotiate for client certs, fForceSSLRenegotiate=TRUE\r\n"));
				fForceSSLRenegotiate = TRUE;
			}
		}
		else
			dwSSLOffset += iRecv;

		m_iNextIn += iRecv;
		WriteBufferToDebugOut(FALSE);

		if (dwBytesRemainingToBeRead)
			dwBytesRemainingToBeRead -= iRecv;

		BufferConsistencyChecks();
		DEBUGCHK(!fReadHeaders || (int)dwMaxBufferSize >= m_iNextIn);
	}
	DEBUGCHK(0); // no fall through
	
done:
	BufferConsistencyChecks();

	// Always make this buffer into a null terminated string
	if (m_pszBuf) {
		m_pszBuf[m_iNextIn] = 0;
	}

	WriteBufferToDebugOut(TRUE);

	DEBUGMSG(ZONE_REQUEST, (L"HTTPD: end RecvToBuf (ret=%d err=%d iGLE=%d)\r\n", ret, err, GLE(err)));
	return ret;
}


// tokenize the input stream: We always skip leading white-space
// once we're in the token, we stop on whitespace or EOL, depending
// on the fWS param
BOOL CBuffer::NextToken(PSTR* ppszTok, int* piLen, BOOL fWS, BOOL fColon)  {
	int i, j;
	// restore saved char, if any
	if(m_chSaved)  {
		DEBUGCHK(m_pszBuf[m_iNextOut]==0);
		m_pszBuf[m_iNextOut] = m_chSaved;
		m_chSaved = 0;
	}
	
	for(i=m_iNextOut; i<m_iNextIn; i++) {
		// if not whitespace break
		if(! (m_pszBuf[i]==' ' || m_pszBuf[i]=='\t') )
			break;
	}
	for(j=i; j<m_iNextIn; j++) {
		// if we get an EOL, it's always end of token
		if(m_pszBuf[j]=='\r' || m_pszBuf[j]=='\n')
			break;
		// if fWS==TRUE and we got white-space, then end of token
		if(fWS && (m_pszBuf[j]==' ' || m_pszBuf[j]=='\t'))
			break;

		// HTTP 1.1 headers may start immediatly without a space between name/value
		// (i.e. header-name:value).
		if (fColon && (j>0) && (m_pszBuf[j-1]==':'))
			break;
	}
	m_iNextOut = j;
	*piLen = (j-i);
	*ppszTok = &(m_pszBuf[i]);
	if(i==j) {
		DEBUGMSG(ZONE_TOKEN, (L"HTTPD: Got NULL token"));
		return FALSE;
	}
	else {
		// save a char so we can null-terminate the current token
		m_chSaved = m_pszBuf[m_iNextOut];
		m_pszBuf[m_iNextOut] = 0;
		DEBUGMSG(ZONE_TOKEN, (L"HTTPD: Got token (%a) Len %d\r\n", *ppszTok, (*piLen)));
		return TRUE;
	}
}

// skip rest of current line and CRLF
BOOL CBuffer::NextLine() {
	int i, j;
	
	// restore saved char, if any
	if(m_chSaved) {
		DEBUGCHK(m_pszBuf[m_iNextOut]==0);
		m_pszBuf[m_iNextOut] = m_chSaved;
		m_chSaved = 0;
	}

	for(i=m_iNextOut, j=i+1; j<m_iNextIn; i++, j++) {
		if(m_pszBuf[i]=='\r' && m_pszBuf[j]=='\n') {
			m_iNextOut = j+1;
			DEBUGMSG(ZONE_TOKEN, (L"HTTPD: NextLine: OK\r\n"));
			return TRUE;
		}
	}
	DEBUGMSG(ZONE_TOKEN, (L"HTTPD: NextLine: error\r\n"));
	return FALSE;
}	

BOOL CBuffer::AppendData(PCSTR pszData, int iLen) {
	// make sure we have enough memory
	DWORD dwBytesToAlloc;

	if (! safeIntUAdd(iLen,1,(UINT*)&dwBytesToAlloc)) {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: ERROR: Integer overflow on attempting to allocate data\r\n"));
		DEBUGCHK(0);
		return FALSE;
	}
	
	if(!AllocMem(dwBytesToAlloc))
		return FALSE;

	DEBUGCHK((m_iSize-m_iNextIn) >= iLen);
	memcpy(m_pszBuf+m_iNextIn, pszData, iLen);
	m_iNextIn += iLen;
	return TRUE;
}



BOOL CBuffer::SendBuffer(CHttpRequest *pRequest) {
	DEBUGCHK(m_iNextOut==0);
	DEBUGCHK(m_chSaved==0);

	if(!m_iNextIn) {
		DEBUGMSG(ZONE_REQUEST_VERBOSE, (L"HTTPD: SendBuffer: empty\r\n"));
		return TRUE;
	}

	BOOL fRet = pRequest->SendData(m_pszBuf,m_iNextIn);
	m_iNextIn = 0;
	return fRet;
}

#if defined (DEBUG)
void CBuffer::WriteBufferToDebugOut(BOOL fPrintAll)  {
	int i = 0;

	if (! (ZONE_REQUEST_VERBOSE & dpCurSettings.ulZoneMask))
		return;

	DEBUGMSG(1,(L"HTTPD: m_iSize = %d, m_iNextOut = %d, m_iNextIn = %d, m_iNextInFollow = %d\r\n",m_iSize,m_iNextOut,m_iNextIn,m_iNextInFollow));
	DEBUGMSG(1,(L"HTTPD: m_iNextRequestBegin = %d, m_iNextRequestSize =%d, m_iNextDecrypt=%d\r\n",m_iNextRequestBegin,m_iNextRequestSize,m_iNextDecrypt));

#if defined (DEBUG_PRINT_ALL_BYTES)

	if (fPrintAll) {
		DEBUGMSG(1,(L"--BEGIN BUFFER\r\n"));
		for (i = m_iNextOut; i < m_iNextIn; i += 8) {
			DEBUGMSG(1,(L"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n",
			            m_pszBuf[i],  m_pszBuf[i+1],m_pszBuf[i+2],m_pszBuf[i+3],
			            m_pszBuf[i+4],m_pszBuf[i+5],m_pszBuf[i+6],m_pszBuf[i+7]));
		}
		DEBUGMSG(1,(L"--END BUFFER\r\n"));
	}
#endif

}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -