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

📄 sbinethttpstream.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 		       VXIMap                   *streamInfo) {   VXIinetResult rc;    // Make a copy in case of redirect.   SBinetString initialUrl = _url->getAbsolute();    const int maxRedirect = 5;   int nbRedirect = 0;   time_t requestTime = (time_t) -1;    for (;;)   {     // Set up request     rc = VXIinet_RESULT_NON_FATAL_ERROR;     _HttpStatus = HTTP_UNDEFINED;     requestTime = time(NULL);     _chunked = false;     _leftToRead = ~0;     _closeConnection = !SBinetChannel::getUsePersistentConnections();     _connectionAborted = FALSE;      if (_method == GET_METHOD)       rc = doGet(flags, properties, streamInfo);     else if (_method == POST_METHOD)       rc = doPost(flags, properties, streamInfo);      if (rc != VXIinet_RESULT_SUCCESS)     {       _closeConnection = TRUE;       break;     }     else if ((rc = getHeaderInfo(streamInfo)) != VXIinet_RESULT_SUCCESS)     {       if (_connectionAborted)       {         _closeConnection = TRUE;         Close();          // Clear the streamInfo map so that previous fetch attributes do not         // remain in the map.         if (streamInfo != NULL)           clearMap(streamInfo);          continue;       }       else       {         _closeConnection = TRUE;         break;       }     }      // Avoid race condition on 100-Continue time-out.  If we got a CONTINUE     // from previous call to getHeaderInfo, we need to get it again.     if (_HttpStatus == SBinetHttpUtils::HTTP_CONTINUE &&         (rc = getHeaderInfo(streamInfo)) != VXIinet_RESULT_SUCCESS)     {       _closeConnection = TRUE;       break;     }      if (_HttpStatus >= 300 && _HttpStatus <= 399 &&         handleRedirect(streamInfo))     {       // perform a reset on the stream.       Close();       if (++nbRedirect > maxRedirect)       {         Error(229, L"%s%s", L"URL", initialUrl.c_str());         return VXIinet_RESULT_FETCH_ERROR;       }       // Clear the streamInfo map to avoid previous fetch attribute to remain       // in the map.       if (streamInfo != NULL)         clearMap(streamInfo);     }     else       break;   }    if (streamInfo != NULL && _HttpStatus >= 100 && _HttpStatus <= 999)   {     VXIMapSetProperty(streamInfo, INET_INFO_HTTP_STATUS,                       (VXIValue*) VXIIntegerCreate(_HttpStatus));   }    switch (_HttpStatus)   {    case SBinetHttpUtils::HTTP_OK:      if (streamInfo != NULL)      {        processHeaderInfo(streamInfo);        setValidatorInfo(streamInfo, requestTime);      }      rc = VXIinet_RESULT_SUCCESS;      break;    case SBinetHttpUtils::HTTP_NOT_MODIFIED:      if (streamInfo != NULL) setValidatorInfo(streamInfo, requestTime);      Close();      rc = VXIinet_RESULT_NOT_MODIFIED;      break;    default:      Close();       // Map the HTTP error code      if (_HttpStatus != HTTP_UNDEFINED)      {        const VXIchar *errorDesc;        rc = MapError(_HttpStatus, &errorDesc);        Error(219, L"%s%s%s%s%s%d%s%s", L"URL", initialUrl.c_str(),              L"Method", (_method == GET_METHOD) ? L"GET" : L"POST",              L"HTTPStatus", _HttpStatus, L"HTTPStatusDescription", errorDesc);      }      else      {        Error(217, L"%s%s", L"URL", initialUrl.c_str());        rc = VXIinet_RESULT_NON_FATAL_ERROR;      }      break;   }    return rc; }   VXIinetResult SBinetHttpStream::Close() {   if (_connection != NULL)   {     if (_closeConnection)       delete _connection;     else     {       // First make sure there is nothing left in the body.       VXIinetResult rc = skipBody();       if (rc == VXIinet_RESULT_SUCCESS)         _channel->putHttpConnection(_connection);       else         delete _connection;     }      _connection = NULL;     _inputStream = NULL;     _outputStream = NULL;   }    return(VXIinet_RESULT_SUCCESS); }   VXIinetResult SBinetHttpStream::skipBody() {   // These HTTP status code do not allow for a body.   if (_HttpStatus == SBinetHttpUtils::HTTP_NOT_MODIFIED ||       _HttpStatus == SBinetHttpUtils::HTTP_NO_DATA  ||       (_HttpStatus >= 100 && _HttpStatus <= 199))     return VXIinet_RESULT_SUCCESS;    VXIinetResult rc;   VXIbyte buffer[1024];    while ((rc = Read(buffer, sizeof(buffer), NULL)) == VXIinet_RESULT_SUCCESS);   if (rc == VXIinet_RESULT_END_OF_STREAM)     rc = VXIinet_RESULT_SUCCESS;    return rc; }  SBinetHttpStream::EncodingType SBinetHttpStream::getEncodingType(const VXIMap *properties) {   SBinetHttpStream::EncodingType encodingType = TYPE_URL_ENCODED;    // Get the submit MIME type from the properties, if defined   const VXIchar *strType =     SBinetUtils::getString(properties, INET_SUBMIT_MIME_TYPE);    if (strType && *strType)   {     // If DEFAULT ever changes, this code will need to be updated     if (::wcscmp(strType, INET_SUBMIT_MIME_TYPE_DEFAULT) == 0)       encodingType = TYPE_URL_ENCODED;     else if (::wcscmp(strType, L"multipart/form-data") == 0)       encodingType = TYPE_MULTIPART;     else       Error(304, L"%s%s%s%s%s%s", L"URL", _url->getAbsolute(),             L"EncodingType", strType,             L"DefaultType", INET_SUBMIT_MIME_TYPE_DEFAULT);   }    return encodingType; }  VXIinetResult SBinetHttpStream::getStatus() {   _HttpStatus = HTTP_UNDEFINED;    VXIinetResult rc = waitStreamReady();   if (rc != VXIinet_RESULT_SUCCESS)     return rc;    writeDebugTimeStamp();    // The HTTP status line should have the following syntax:   // HTTP/x.x yyy msg CRLF   //   // This is buggy if we ever see an HTTP/1.xx in the future   SWIdataOutputStream line;   const char *c_line = NULL;    SWIstream::Result src = _channel->readLine(_inputStream, &line);   if (src >= 0)   {     if (ap_checkmask(c_line = line.getString(), "HTTP/#.# ###*"))     {       _HttpStatus = atoi(&c_line[9]);       int version = (c_line[5] - '0') * 10 + (c_line[7] - '0');       if (version < 11) _closeConnection = TRUE;     }     else     {       Error(249, L"%s%s", L"URL", _url->getAbsolute());     }   }   // A return value of END_OF_FILE means the connection was gracefully closed.   // A return value of CONNECTION_ABORTED means the connection was aborted   // because of a time out or some other problem.   else if ((src == SWIstream::CONNECTION_ABORTED) || (src == SWIstream::END_OF_FILE))   {     // Return immediately and do not check the _HttpStatus since     // we don't want to print errors for nothing.     _connectionAborted = true;     return VXIinet_RESULT_NON_FATAL_ERROR;   }   else   {     Error(249, L"%s%s", L"URL", _url->getAbsolute());   }    if (_HttpStatus < 100 || _HttpStatus > 999)   {     if (_HttpStatus != HTTP_UNDEFINED)     {       Error(219, L"%s%s%s%s%s%d",             L"URL", _url->getAbsolute(),             L"Method", _method == GET_METHOD ? L"GET" : L"POST",             L"HTTPStatus", _HttpStatus);     }     else     {       Error(221, L"%s%s", L"URL", _url->getAbsolute());     }     rc = VXIinet_RESULT_NON_FATAL_ERROR;   }    return rc; }  enum HandlerValueType {   HANDLER_INT = 0x01,   HANDLER_DATE = 0x02,   HANDLER_STRING = 0x04,   HANDLER_CONTENT = 0x08,   HANDLER_LIST = 0x10 };   // Currently doing a linear search because of case-insenstivity of // comparisons.  If the number of entries in this array increases, we should // consider using a hash implementation instead. SBinetHttpStream::HeaderInfo SBinetHttpStream::headerInfoMap[] = {   { "Age", NULL, HANDLER_INT, NULL },   { "Cache-Control", NULL, HANDLER_STRING | HANDLER_LIST, NULL },   { "Content-Length", INET_INFO_SIZE_BYTES, HANDLER_INT, contentLengthHandler },   { "Content-Type", INET_INFO_MIME_TYPE, HANDLER_STRING, NULL },   { "Connection", NULL, HANDLER_STRING, connectionHandler },   { "Date", NULL, HANDLER_DATE, NULL },   { "ETag", NULL, HANDLER_STRING, NULL },   { "Expires", NULL, HANDLER_DATE, NULL },   { "Last-Modified", NULL, HANDLER_DATE, NULL },   { "Location", NULL, HANDLER_STRING, NULL },   { "Pragma", NULL, HANDLER_STRING, NULL },   { "Set-Cookie", NULL, HANDLER_STRING, setCookieHandler },   { "Set-Cookie2", NULL, HANDLER_STRING, setCookie2Handler },   { "Transfer-Encoding", NULL, HANDLER_STRING, transferEncodingHandler},   { NULL, NULL, 0, NULL } };  void SBinetHttpStream::setCookieHandler(HeaderInfo *headerInfo,                                         const char *value,                                         SBinetHttpStream *httpStream,                                         VXIMap *streamInfo) {   if (!httpStream->_channel->cookiesEnabled())     return;    const char *p = value;    while (p != NULL && *p)   {     SBinetCookie *cookie = SBinetCookie::parse(httpStream->_url, p, httpStream);     if (cookie != NULL)     {       httpStream->_channel->updateCookie(cookie);     }   }   httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                    L"SBinetHttpStream::setCookieHandler",                    L"Set-Cookie: %S", value); }  void SBinetHttpStream::setCookie2Handler(HeaderInfo *headerInfo,                                          const char *value,                                          SBinetHttpStream *httpStream,                                          VXIMap *streamInfo) {   if (!httpStream->_channel->cookiesEnabled())     return;    httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                    L"SBinetHttpStream::setCookie2Handler",                    L"Not Supported: \"Set-Cookie2: %S\"", value); }  void SBinetHttpStream::contentLengthHandler(HeaderInfo *headerInfo,                                             const char *value,                                             SBinetHttpStream *httpStream,                                             VXIMap *streamInfo) {   // Ignore content-length is stream is chunked.   if (!httpStream->_chunked)   {     httpStream->_leftToRead = atoi(value);   } }  void SBinetHttpStream::connectionHandler(HeaderInfo *headerInfo,                                          const char *value,                                          SBinetHttpStream *httpStream,                                          VXIMap *streamInfo) {   SBinetNString attrib;    for (;;)   {     if ((value = SBinetHttpUtils::getValue(value, attrib)) == NULL)     {       httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                        L"SBinetHttpStream::connectionHandler",                        L"Could not get attribute.");       break;     }      if ((value = SBinetHttpUtils::expectChar(value, ",")) == NULL)     {       httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                        L"SBinetHttpStream::connectionHandler",                        L"Expecting ','.");       break;     }      if (::strcasecmp(attrib.c_str(), "close") == 0)     {       httpStream->_closeConnection = TRUE;     }      // Skip comma, or if at end of string, stop parsing.     if (*value)       value++;     else       break;   } }  void SBinetHttpStream::transferEncodingHandler(HeaderInfo *headerInfo,                                                const char *value,                                                SBinetHttpStream *httpStream,                                                VXIMap *streamInfo) {   SBinetNString encoding;    for (;;)   {     if ((value = SBinetHttpUtils::getValue(value, encoding)) == NULL)     {       httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                        L"SBinetHttpStream::transferEncodingHandler",                        L"Could not get encoding.");       break;     }      if ((value = SBinetHttpUtils::expectChar(value, ",")) == NULL)     {       httpStream->Diag(MODULE_SBINET_STREAM_TAGID,                        L"SBinetHttpStream::transferEncodingHandler",                        L"Expecting ','.");       break;     }      if (::strcasecmp(encoding.c_str(), "chunked") == 0)     {       httpStream->_chunked = true;       httpStream->_leftToRead = 0;     }      // Skip comma, or if at end of string, stop parsing.

⌨️ 快捷键说明

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