📄 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 = (unsigned)~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);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -