📄 sbinethttpstream.cpp
字号:
return rc; } VXIinetResult SBinetHttpStream::getChunkSize(VXIulong& chunk_size) { // Read next chunk size. char *chunk_size_str; if (getValue(chunk_size_str, 0) < 0) { Error(245, L"%s%s", L"URL", _url->getAbsolute()); return VXIinet_RESULT_FETCH_ERROR; } VXIinetResult rc = VXIinet_RESULT_SUCCESS; bool parseError = false; char *endParse; chunk_size = (VXIulong) strtol(chunk_size_str, &endParse, 16); // If we did not parse a single character, this is an error. if (endParse == chunk_size_str) { parseError = true; } else if (*endParse) { // We did not stop parsing at the end of the string. If the only // remaining characters are whitespace, this is not an error. while (*endParse && ap_isspace(*endParse)); // This is not really an eror as there might be a chunk extension that we // currently ignore. // //if (*endParse) parseError = true; } if (parseError) { // Either an empty string to parse or stopped at non hexadecimal // character. Error(246, L"%s%s%s%S", L"URL", _url->getAbsolute(), L"ChunkSize", chunk_size_str); rc = VXIinet_RESULT_FETCH_ERROR; } delete [] chunk_size_str; return rc; } static SWIstream::Result inetToStream(VXIinetResult rc) { switch (rc) { case VXIinet_RESULT_SUCCESS: return SWIstream::SUCCESS; case VXIinet_RESULT_FETCH_TIMEOUT: return SWIstream::TIMED_OUT; default: return SWIstream::READ_ERROR; } } int SBinetHttpStream::readChunked(VXIbyte *buffer, VXIulong buflen) { // Note. This is not fully compliant as it does not parse chunk extension. // The trailer is parsed but no action is taken. VXIinetResult rc = VXIinet_RESULT_SUCCESS; if (_leftToRead == ~0) return 0; int totalRead = 0; for (;;) { if (_leftToRead == 0) { if ((rc = waitStreamReady()) != VXIinet_RESULT_SUCCESS) return ::inetToStream(rc); if ((rc = getChunkSize(_leftToRead)) != VXIinet_RESULT_SUCCESS) return SWIstream::READ_ERROR; if (_leftToRead == 0) { parseHeaders(NULL); _leftToRead = ~0; break; } } if (buflen == 0) break; VXIulong toRead = (buflen > _leftToRead ? _leftToRead : buflen); VXIulong nbRead = 0; while (toRead > 0) { if ((rc = waitStreamReady()) != VXIinet_RESULT_SUCCESS) return ::inetToStream(rc); int count = _channel->readData(_inputStream, &buffer[nbRead], toRead); // Read error. if (count == 0) count = SWIstream::WOULD_BLOCK; if (count < 0) return count; nbRead += count; toRead -= count; } _leftToRead -= nbRead; totalRead += nbRead; buffer += nbRead; buflen -= nbRead; } return totalRead; } int SBinetHttpStream::readNormal(VXIbyte *buffer, VXIulong buflen) { int totalRead = 0; if (_leftToRead == 0) return totalRead; VXIulong toRead = (buflen > _leftToRead) ? _leftToRead : buflen; VXIulong nbRead = 0; while (toRead > 0) { // Check if fetch timeout has expired VXIinetResult rc = waitStreamReady(); if (rc != VXIinet_RESULT_SUCCESS) return inetToStream(rc); int count = _channel->readData(_inputStream, &buffer[nbRead], toRead); // This is not an error if we get END OF FILE. if (count == SWIstream::END_OF_FILE) { _closeConnection = TRUE; _leftToRead = 0; break; } // Read error. if (count == 0) count = SWIstream::WOULD_BLOCK; if (count < 0) return count; nbRead += count; toRead -= count; } totalRead += nbRead; _leftToRead -= nbRead; return totalRead; } VXIinetResult SBinetHttpStream::Read(VXIbyte *buffer, VXIulong buflen, VXIulong *nread) { VXIinetResult rc = VXIinet_RESULT_SUCCESS; int nbRead; if (_chunked) nbRead = readChunked(buffer, buflen); else nbRead = readNormal(buffer, buflen); if (nbRead >= 0) { if (nread != NULL) *nread = nbRead; if (((unsigned int) nbRead) < buflen || (!_chunked && _leftToRead == 0)) rc = VXIinet_RESULT_END_OF_STREAM; } else { _closeConnection = TRUE; switch (nbRead) { case SWIstream::END_OF_FILE: rc = VXIinet_RESULT_END_OF_STREAM; break; case SWIstream::WOULD_BLOCK: rc = VXIinet_RESULT_WOULD_BLOCK; break; case SWIstream::TIMED_OUT: rc = VXIinet_RESULT_FETCH_TIMEOUT; break; default: rc = VXIinet_RESULT_IO_ERROR; } } return rc; } VXIinetResult SBinetHttpStream::MapError(int ht_error, const VXIchar **errorDesc) { VXIinetResult rc; switch(ht_error) { case SBinetHttpUtils::HTTP_NO_ACCESS: /* Unauthorized */ *errorDesc = L"Unauthorized"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_FORBIDDEN: /* Access forbidden */ *errorDesc = L"Access forbidden"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_NOT_ACCEPTABLE:/* Not Acceptable */ *errorDesc = L"Not Acceptable"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_NO_PROXY_ACCESS: /* Proxy Authentication Failed */ *errorDesc = L"Proxy Authentication Failed"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_CONFLICT: /* Conflict */ *errorDesc = L"Conflict"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_LENGTH_REQUIRED: /* Length required */ *errorDesc = L"Length required"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_PRECONDITION_FAILED: /* Precondition failed */ *errorDesc = L"Precondition failed"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_TOO_BIG: /* Request entity too large */ *errorDesc = L"Request entity too large"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_URI_TOO_BIG: /* Request-URI too long */ *errorDesc = L"Request-URI too long"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_UNSUPPORTED: /* Unsupported */ *errorDesc = L"Unsupported"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_BAD_RANGE: /* Request Range not satisfiable */ *errorDesc = L"Request Range not satisfiable"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_EXPECTATION_FAILED: /* Expectation Failed */ *errorDesc = L"Expectation Failed"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_REAUTH: /* Reauthentication required */ *errorDesc = L"Reauthentication required"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_PROXY_REAUTH: /* Proxy Reauthentication required */ *errorDesc = L"Proxy Reauthentication required"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_SERVER_ERROR: /* Internal server error */ *errorDesc = L"Internal server error"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_NOT_IMPLEMENTED: /* Not implemented (server error) */ *errorDesc = L"Not implemented (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_BAD_GATEWAY: /* Bad gateway (server error) */ *errorDesc = L"Bad gateway (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_RETRY: /* Service not available (server error) */ *errorDesc = L"Service not available (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_GATEWAY_TIMEOUT: /* Gateway timeout (server error) */ *errorDesc = L"Gateway timeout (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_BAD_VERSION: /* Bad protocol version (server error) */ *errorDesc = L"Bad protocol version (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_NO_PARTIAL_UPDATE: /* Partial update not implemented (server error) */ *errorDesc = L"Partial update not implemented (server error)"; rc = VXIinet_RESULT_FETCH_ERROR; break; case SBinetHttpUtils::HTTP_INTERNAL: /* Weird -- should never happen. */ *errorDesc = L"Internal error"; rc = VXIinet_RESULT_NON_FATAL_ERROR; break; case SBinetHttpUtils::HTTP_WOULD_BLOCK: /* If we are in a select */ *errorDesc = L"Would block; not an error"; rc = VXIinet_RESULT_WOULD_BLOCK; break; case SBinetHttpUtils::HTTP_INTERRUPTED: /* Note the negative value! */ *errorDesc = L"Interrupted; not an error"; rc = VXIinet_RESULT_SUCCESS; break; case SBinetHttpUtils::HTTP_PAUSE: /* If we want to pause a stream */ *errorDesc = L"Stream paused; not an error"; rc = VXIinet_RESULT_SUCCESS; break; case SBinetHttpUtils::HTTP_RECOVER_PIPE: /* Recover pipe line */ *errorDesc = L"Recover pipe line; not an error"; rc = VXIinet_RESULT_SUCCESS; break; case SBinetHttpUtils::HTTP_TIMEOUT: /* Connection timeout */ *errorDesc = L"Connection timeout"; rc = VXIinet_RESULT_FETCH_TIMEOUT; break; case SBinetHttpUtils::HTTP_NOT_FOUND: /* Not found */ *errorDesc = L"Not found"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_METHOD_NOT_ALLOWED: /* Method not allowed */ *errorDesc = L"Method not allowed"; rc = VXIinet_RESULT_NON_FATAL_ERROR; break; case SBinetHttpUtils::HTTP_NO_HOST: /* Can't locate host */ *errorDesc = L"Can't locate host"; rc = VXIinet_RESULT_NOT_FOUND; break; /* These should not be errors */ case SBinetHttpUtils::HTTP_MULTIPLE_CHOICES: *errorDesc = L"Multiple choices"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_PERM_REDIRECT: *errorDesc = L"Permanent redirection"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_SEE_OTHER: *errorDesc = L"See other"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_USE_PROXY: *errorDesc = L"Use Proxy"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_PROXY_REDIRECT: *errorDesc = L"Proxy Redirect"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_TEMP_REDIRECT: *errorDesc = L"Temporary Redirect"; rc = VXIinet_RESULT_NOT_FOUND; break; case SBinetHttpUtils::HTTP_FOUND: *errorDesc = L"Found"; rc = VXIinet_RESULT_NON_FATAL_ERROR; break; default: { switch (ht_error / 100) { case 1: // informational, shouldn't fail due to this! *errorDesc = L"Unknown informational status"; break; case 2: // successful, shouldn't fail due to this! *errorDesc = L"Unknown success status"; break; case 3: // redirection *errorDesc = L"Unknown redirection error"; break; case 4: // client error *errorDesc = L"Unknown client error"; break; case 5: // server error *errorDesc = L"Unknown server error"; break; default: *errorDesc = L"Unknown HTTP status code"; } rc = VXIinet_RESULT_NON_FATAL_ERROR; } } return rc; } VXIinetResult SBinetHttpStream::Write(const VXIbyte* pBuffer, VXIulong nBuflen, VXIulong* pnWritten) { return VXIinet_RESULT_UNSUPPORTED; } VXIinetResult SBinetHttpStream::waitStreamReady() { int delay = getDelay(); if (delay == 0) return VXIinet_RESULT_FETCH_TIMEOUT; switch (_inputStream->waitReady(delay)) { case SWIstream::SUCCESS: return VXIinet_RESULT_SUCCESS; //no break: intentional case SWIstream::TIMED_OUT: return VXIinet_RESULT_FETCH_TIMEOUT; //no break: intentional default: Error(240, NULL); return VXIinet_RESULT_FETCH_ERROR; } } void SBinetHttpStream::writeDebugTimeStamp() { char timeStamp[64]; _channel->writeDebugString(CRLF "@ "); SBinetUtils::getTimeStampMsecStr(timeStamp); char buffer[1024]; #ifdef WIN32 _snprintf(buffer, 1024, "%s, URL = %s, conn = %s", timeStamp, _url->getNAbsolute(), _connection->getId()); #else snprintf(buffer, 1024, "%s, URL = %s, conn = %s", timeStamp, _url->getNAbsolute(), _connection->getId()); #endif _channel->writeDebugString(buffer); _channel->writeDebugString(CRLF); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -