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

📄 sbinethttpstream.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 /****************License************************************************  *  * Copyright 2000-2003.  ScanSoft, Inc.      *  * Use of this software is subject to notices and obligations set forth   * in the SpeechWorks Public License - Software Version 1.2 which is   * included with this software.   *  * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,   * SpeechWorks and the SpeechWorks logo are registered trademarks or   * trademarks of SpeechWorks International, Inc. in the United States   * and other countries.  *  ***********************************************************************/ #ifndef _SB_USE_STD_NAMESPACE #define _SB_USE_STD_NAMESPACE #endif  #ifdef WIN32  #ifndef UNICODE #define UNICODE #endif #ifndef _UNICODE #define _UNICODE #endif  #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #endif  #include <sys/timeb.h>                  // for _ftime( )/ftime( )  #include "VXIvalue.h" #include "VXIinet.h" #include "VXItrd.h"  #include "SBinetLog.h" #include "SBinetURL.h" #include "SBinetHttpStream.hpp" #include "SBinetChannel.h" #include "SBinetHttpConnection.hpp" #include "SBinetValidator.h" #include "SBinetCookie.h" #include "SBinetUtils.hpp" #include "SWITimeWatch.hpp"  #include "util_date.h" #include "ap_ctype.h" #include "HttpUtils.hpp" #include <SWIsocket.hpp> #include <SWIdataOutputStream.hpp> #include <SWIbufferedInputStream.hpp> #include <SWIbufferedOutputStream.hpp>  #define HTTP_UNDEFINED -1234  /* No HTTP error code yet */  #define READ_CHUNK_SIZE 128 * 1024 // Read from socket in 128 Kb chunks  SBinetHttpStream::SBinetHttpStream(SBinetURL* url,                                    SubmitMethod method,                                    SBinetChannel* ch,                                    VXIlogInterface *log,                                    VXIunsigned diagLogBase):   SBinetStoppableStream(url, log, diagLogBase),   _HttpStatus(HTTP_UNDEFINED), _leftToRead(~0), _chunked(false),   _method(method), _channel(ch), _connection(NULL),   _inputStream(NULL), _outputStream(NULL),   _closeConnection(TRUE), _validator(NULL), _connectionAborted(FALSE) {}  SBinetHttpStream::~SBinetHttpStream() {   delete _validator;   Close(); }  VXIinetResult SBinetHttpStream::initSocket(SubmitMethod method,                                            const VXIMap *properties,                                            VXIMap *streamInfo) {   _connection = _channel->getHttpConnection(_url, properties);    if (_connection == NULL)   {     Error(262, L"%s%s", L"URL", _url->getAbsolute());     return VXIinet_RESULT_FETCH_ERROR;   }    SWITimeWatch timeWatch;   timeWatch.start();    switch (_connection->connect(getDelay()))   {    case SWIstream::TIMED_OUT:      Error(241, NULL);      return VXIinet_RESULT_FETCH_TIMEOUT;      break;    case SWIstream::SUCCESS:      break;    default:      Error(244, L"%s%s", L"URL", _url->getAbsolute());      return VXIinet_RESULT_FETCH_ERROR;   }    _inputStream = _connection->getInputStream();   _outputStream = _connection->getOutputStream();    Diag(MODULE_SBINET_TIMING_TAGID, L"SBinetHttpStream::initSocket",        L"%i msecs, Connect to socket", timeWatch.getElapsed());    writeDebugTimeStamp();    if (method == SBinetHttpStream::GET_METHOD)     _channel->writeString(_outputStream, "GET ");   else     _channel->writeString(_outputStream, "POST ");    if (_connection->usesProxy())     _channel->writeString(_outputStream, _url->getNAbsolute());   else     _channel->writeString(_outputStream, _url->getNPath());    _channel->writeString(_outputStream, " HTTP/1.1" CRLF);   _channel->writeString(_outputStream, "Accept: */*" CRLF);    // Write HOST header.   _channel->writeString(_outputStream, "Host: ");   _channel->writeString(_outputStream, _url->getNHost());   int defaultPort = _url->getProtocol() == SBinetURL::HTTP_PROTOCOL ? 80 : 443;   int port = _url->getPort();    if (port != defaultPort)   {     _channel->writeString(_outputStream, ":");     _channel->writeInt(_outputStream, port);   }   _channel->writeString(_outputStream, CRLF);    // Write USER-AGENT header.   _channel->writeString(_outputStream, "User-Agent: ");   _channel->writeString(_outputStream, _channel->getUserAgent());   _channel->writeString(_outputStream, CRLF);    // Write REFERER header.   SBinetNString baseUrl = _url->getNBase();   if (baseUrl.length() > 0)   {     // Cut query arguments, if present     VXIunsigned queryArgsSeparator = baseUrl.find('?');     if (queryArgsSeparator < baseUrl.length())       baseUrl.resize(queryArgsSeparator);      if (baseUrl.length() > 0)     {       _channel->writeString(_outputStream, "Referer: ");       _channel->writeString(_outputStream, baseUrl.c_str());       _channel->writeString(_outputStream, CRLF);     }   }    SBinetUtils::getInteger(properties, INET_CLOSE_CONNECTION, _closeConnection);    if (_closeConnection)   {     _channel->writeString(_outputStream, "Connection: close" CRLF);   }    VXIint32 maxAge = -1;   VXIint32 maxStale = -1;    getCacheInfo(properties, maxAge, maxStale);    if (maxAge != -1)   {     _channel->writeString(_outputStream, "Cache-Control: max-age=");     _channel->writeInt(_outputStream, maxAge);     _channel->writeString(_outputStream, CRLF);   }    if (maxStale != -1)   {     _channel->writeString(_outputStream, "Cache-Control: max-stale=");     _channel->writeInt(_outputStream, maxStale);     _channel->writeString(_outputStream, CRLF);   }    time_t lastModified = (time_t) -1;   SBinetNString etag;    getModInfo(properties, lastModified, etag);    if (method == SBinetHttpStream::GET_METHOD && lastModified != (time_t) -1)   {     char lastModStr[32];     ap_gm_timestr_822(lastModStr, lastModified);     _channel->writeString(_outputStream, "If-Modified-Since: ");     _channel->writeString(_outputStream, lastModStr);     _channel->writeString(_outputStream, CRLF);   }    if (etag[0])   {     _channel->writeString(_outputStream, "If-None-Match: ");     _channel->writeString(_outputStream, etag.c_str());     _channel->writeString(_outputStream, CRLF);   }    if (_channel->cookiesEnabled())   {     _channel->collectCookies(_outputStream, _url->getNHost(), _url->getNPath());   }    return VXIinet_RESULT_SUCCESS; }  VXIinetResult SBinetHttpStream::doGet(VXIint32 flags,                                       const VXIMap *properties,                                       VXIMap *streamInfo)  {   VXIinetResult rc = initSocket(GET_METHOD, properties, streamInfo);   if (rc != VXIinet_RESULT_SUCCESS)     return rc;    _channel->writeString(_outputStream, CRLF);    if (_outputStream->flush() != SWIstream::SUCCESS)     rc = VXIinet_RESULT_IO_ERROR;    return rc; }  /*  * POST simple form data. Don't know how to combine Form data and audio in multipart POST  */ VXIinetResult SBinetHttpStream::doPost(VXIint32 flags,                                        const VXIMap *properties,                                        VXIMap *streamInfo) {   const VXIMap *queryArgs =     (const VXIMap *)VXIMapGetProperty(properties, INET_URL_QUERY_ARGS);    SBinetNString queryArgsStr;   VXIint argsLen;    EncodingType encodingType = getEncodingType(properties);   const char *encodingStr;    if (encodingType == TYPE_MULTIPART)   {     encodingStr = SB_MULTIPART;     queryArgsStr = _url->queryArgsToMultipart(queryArgs);     argsLen = queryArgsStr.length();     Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetHttpStream::doPost",          L"Performing multipart POST, data size %i", argsLen);   }   else   {     encodingStr = SB_URLENCODED;     queryArgsStr = _url->queryArgsToNString(queryArgs);     argsLen = queryArgsStr.length();     Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetHttpStream::doPost",          L"Performing URL-encoded POST, data size %i", argsLen);   }    VXIinetResult rc = initSocket(POST_METHOD, properties, streamInfo);    if (rc != VXIinet_RESULT_SUCCESS)     return rc;    _channel->writeString(_outputStream, "Expect: 100-continue" CRLF);    _channel->writeString(_outputStream, "Content-Length: ");   _channel->writeInt(_outputStream, argsLen);   _channel->writeString(_outputStream, CRLF);    _channel->writeString(_outputStream, "Content-Type: ");   _channel->writeString(_outputStream, encodingStr);   _channel->writeString(_outputStream, CRLF CRLF);    if (_outputStream->flush() != SWIstream::SUCCESS)   {     return VXIinet_RESULT_IO_ERROR;   }    // Wait for input stream to be ready.  If time-out, just send data anyway.   // If we don't time out, we should be able to get an HTTP_CONTINUE.   VXIint32 continueTimeout = SBinetChannel::getPostContinueTimeout();   int maxDelay = getDelay();   if (continueTimeout < 0 ||       (maxDelay >=0 && continueTimeout > maxDelay))     continueTimeout = maxDelay;    switch (_inputStream->waitReady(continueTimeout))   {    case SWIstream::SUCCESS:      // Read the HTTP_CONTINUE header      if ((rc = getHeaderInfo(streamInfo)) != VXIinet_RESULT_SUCCESS)        return rc;       if (_HttpStatus != SBinetHttpUtils::HTTP_CONTINUE)        return VXIinet_RESULT_FETCH_ERROR;       break;    case SWIstream::TIMED_OUT:      // We still have to send the body of the message.  This is done      // after the switch anyway so we do nothing.      break;    default:      // I/O error on the stream.  Just return an error.      return VXIinet_RESULT_FETCH_ERROR;   }    if (encodingType == TYPE_MULTIPART)   {     _channel->writeData(_outputStream, queryArgsStr.data(), argsLen);   }   else   {     _channel->writeString(_outputStream, queryArgsStr.c_str());   }    if (_outputStream->flush() != SWIstream::SUCCESS)     rc = VXIinet_RESULT_IO_ERROR;    return rc; }  bool SBinetHttpStream::handleRedirect(VXIMap *streamInfo) {   const VXIchar *location;    switch (_HttpStatus)   {     case SBinetHttpUtils::HTTP_SEE_OTHER:      // This return code implies that we change a POST into a GET.      _method = GET_METHOD;      // no break: intentional     case SBinetHttpUtils::HTTP_MULTIPLE_CHOICES:    case SBinetHttpUtils::HTTP_PERM_REDIRECT:    case SBinetHttpUtils::HTTP_FOUND:    case SBinetHttpUtils::HTTP_TEMP_REDIRECT:      location = SBinetUtils::getString(streamInfo, L"Location");      if (location == NULL || !*location)      {        Error(247, L"%s%s", L"URL", _url->getAbsolute());        return false;      }       if (_url->parse(location, _url->getAbsolute()) != VXIinet_RESULT_SUCCESS)      {        Error(248, L"%s%s%s%s", L"URL", _url->getAbsolute(),              L"Location", location);        return false;      }       return true;      break;    default:      return false;   } }  // stupid function required because the people who designed VXIMap, in their // great wisdom, did not include a VXIMapClear function or the ability for the // iterator to delete the current entry. static void clearMap(VXIMap *streamInfo) {   VXIunsigned n = VXIMapNumProperties(streamInfo);   const VXIchar **keys = new const VXIchar *[n];   const VXIchar *key;   const VXIValue *value;    int i = 0;    VXIMapIterator *mapIterator = VXIMapGetFirstProperty(streamInfo,                                                        &key,                                                        &value );   do   {     if (key != NULL)     {       keys[i++] = key;     }   }   while (VXIMapGetNextProperty(mapIterator, &key, &value) == VXIvalue_RESULT_SUCCESS);    VXIMapIteratorDestroy(&mapIterator);   i--;    while (--i >= 0)   {     VXIMapDeleteProperty(streamInfo, keys[i]);   }    delete [] keys; }   VXIinetResult SBinetHttpStream::Open(VXIint32                  flags, 		       const VXIMap             *properties,

⌨️ 快捷键说明

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