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

📄 sbinethttpstream.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 
     // Skip comma, or if at end of string, stop parsing.
     if (*value)
       value++;
     else
       break;
   }
 }
 
 void SBinetHttpStream::defaultHeaderHandler(HeaderInfo *headerInfo,
                                             const char *value,
                                             SBinetHttpStream *httpStream,
                                             VXIMap *streamInfo)
 {
   VXIValue* vxi_value = NULL;
   bool listF = (headerInfo->value_type & HANDLER_LIST) == HANDLER_LIST;
   int value_type = headerInfo->value_type & ~HANDLER_LIST;
   const VXIchar *property = NULL;
   SBinetString *propTmp = NULL;
 
   if (headerInfo->inet_property != NULL)
   {
     property = headerInfo->inet_property;
   }
   else
   {
     propTmp = new SBinetString(headerInfo->header);
     property = propTmp->c_str();
   }
 
   switch (value_type)
   {
    case HANDLER_INT:
      vxi_value = (VXIValue *) VXIIntegerCreate(atoi(value));
      break;
    case HANDLER_STRING:
      if (listF)
      {
        const VXIchar *v = SBinetUtils::getString(streamInfo, property);
        if (v != NULL)
        {
          SBinetString tmp = v;
          tmp += L", ";
          tmp += value;
          vxi_value = (VXIValue *) VXIStringCreate(tmp.c_str());
        }
      }
      if (vxi_value == NULL)
      {
        vxi_value = (VXIValue *) VXIStringCreate(SBinetString(value).c_str());
      }
      break;
    case HANDLER_DATE:
      {
        // FIXME: Portability issue. This code assumes that a time_t can be
        // stored in a VXIint32 without losing any information.  Two possible
        // options: extend VXIValue with a VXILong type or use VXIContent.
        time_t timestamp = ap_parseHTTPdate(value);
        vxi_value = (VXIValue *) VXIIntegerCreate(timestamp);
      }
      break;
    case HANDLER_CONTENT:
      if (listF)
      {
        const char *content;
        VXIulong contentLength;
 
        if (SBinetUtils::getContent(streamInfo, property, content, contentLength))
        {
          SBinetNString tmp = content;
          tmp += ", ";
          tmp += value;
          vxi_value = (VXIValue *) SBinetUtils::createContent(tmp.c_str());
        }
      }
      if (vxi_value == NULL)
      {
        vxi_value = (VXIValue *) SBinetUtils::createContent(value);
      }
      break;
    default:
      break;
   }
 
   if (vxi_value != NULL)
   {
     VXIMapSetProperty(streamInfo, property, vxi_value);
   }
   else
   {
     httpStream->Diag(MODULE_SBINET_STREAM_TAGID,
                      L"SBinetHttpStream::defaultHeaderHandler",
                      L"Could not create VXI value, header: <%S>, value: <%S>",
                      headerInfo->header,
                      value);
   }
 
   delete propTmp;
 }
 
 SBinetHttpStream::HeaderInfo *SBinetHttpStream::findHeaderInfo(const char *header)
 {
   for (int i = 0; headerInfoMap[i].header != NULL; i++)
   {
     if (::strcasecmp(headerInfoMap[i].header, header) == 0)
     {
       return &headerInfoMap[i];
     }
   }
 
   return NULL;
 }
 
 void SBinetHttpStream::processHeader(const char *header,
                                      const char *value,
                                      VXIMap* streamInfo)
 {
   HeaderInfo *headerInfo = findHeaderInfo(header);
 
   // If it is not found, we ignore it.
   if (headerInfo == NULL) return;
 
   HeaderHandler handler = headerInfo->handler;
   if (handler == NULL) handler = defaultHeaderHandler;
 
   (*handler)(headerInfo, value, this, streamInfo);
 }
 
 static const unsigned long BREAK_AT_INITIAL_NEWLINE = 0x01;
 static const unsigned long CONTINUE_AT_NEWLINE = 0x02;
 
 int SBinetHttpStream::getValue(char *&value, unsigned long mask)
 {
   char c;
   bool done = false;
 
   // skip white spaces.
   for (;;)
   {
     if ((c = _channel->readChar(_inputStream)) < 0)
       return -8;
 
     if (!ap_isspace(c))
       break;
 
     switch (c)
     {
      case '\r':
        if ((c = _channel->readChar(_inputStream)) != '\n')
          return -5;
        // no break: intentional
 
      case '\n':
        if (mask & BREAK_AT_INITIAL_NEWLINE)
        {
          if ((c = _inputStream->peek()) < 0) return -6;
          if (!ap_isspace(c)) done = true;
        }
 
        if (done)
        {
          value = new char[2];
          *value = '\0';
          Diag(MODULE_SBINET_STREAM_TAGID,
               L"SBinetHttpStream::getValue",
               L"value = '%S'", value);
          return 0;
        }
        break;
 
      default:
        break;
     }
   }
 
   int len = 0;
   int bufSize = 32;
   value = new char[bufSize];
 
   for (;;)
   {
     if (len == bufSize)
     {
       int newBufSize = (bufSize << 1);
       char *new_value = ::strncpy(new char[newBufSize], value, bufSize);
       delete [] value;
       value = new_value;
       bufSize = newBufSize;
     }
 
     if (c == '\r')
     {
       if ((c = _channel->readChar(_inputStream)) != '\n')
         break;
     }
 
     // We need to verify if the value continues on the next line.
     if (c == '\n')
     {
       if (mask & CONTINUE_AT_NEWLINE)
       {
         if ((c = _inputStream->peek()) < 0)
           break;
 
         if (!ap_isspace(c) || c == '\r' || c == '\n')
           done = true;
       }
       else
         done = true;
 
       if (done)
       {
         // remove trailing blanks and terminate string.
         while (len > 0 && ap_isspace(value[len-1])) len--;
         value[len] = '\0';
         Diag(MODULE_SBINET_STREAM_TAGID,
              L"SBinetHttpStream::getValue",
              L"value = '%S'", value);
         return 0;
       }
     }
 
     value[len++] = c;
 
     if ((c = _channel->readChar(_inputStream)) < 0)
       break;
   }
 
   // If we get here, we got an error parsing the line.
   delete [] value;
   value = NULL;
   return -7;
 }
 
 int SBinetHttpStream::getHeader(char *&header, char delimiter)
 {
   int c;
 
   if ((c = _channel->readChar(_inputStream)) < 0)
     return -1;
 
   // Check for end of headers.
   if (c == '\r')
   {
     if ((c = _channel->readChar(_inputStream)) != '\n')
       return -2;
     return 1;
   }
 
   if (c == '\n') return 2;
 
   if (ap_isspace(c) || c == (unsigned char) delimiter)
     return -3;
 
   int len = 0;
   int bufSize = 32;
   header = new char[bufSize];
 
   for (;;)
   {
     if (len == bufSize)
     {
       int newBufSize = bufSize << 1;
       char *new_header = ::strncpy(new char[newBufSize], header, bufSize);
       delete [] header;
       header = new_header;
       bufSize = newBufSize;
     }
     if (c == (unsigned char) delimiter)
     {
       header[len++] = '\0';
       Diag(MODULE_SBINET_STREAM_TAGID,
            L"SBinetHttpStream::getHeader",
            L"header = '%S'", header);
       return 0;
     }
     header[len++] = c;
 
     if ((c = _channel->readChar(_inputStream)) < 0 || ap_isspace(c))
       break;
   }
 
   delete [] header;
   header = NULL;
   return -4;
 }
 
 int SBinetHttpStream::getHeaderValue(char *&header, char *&value)
 {
   int rc = getHeader(header, ':');
 
   if (rc == 0)
   {
     rc = getValue(value, CONTINUE_AT_NEWLINE | BREAK_AT_INITIAL_NEWLINE);
     if (rc != 0)
     {
       Error(250, NULL);
       delete [] header;
       header = NULL;
     }
   }
   else if (rc < 0)
     Error(250, NULL);
 
   return rc;
 }
 
 VXIinetResult SBinetHttpStream::parseHeaders(VXIMap* streamInfo)
 {
   char *header = NULL;
   char *value  = NULL;
   VXIinetResult rc1;
   int rc2;
 
   while (((rc1 = waitStreamReady()) == VXIinet_RESULT_SUCCESS) &&
          ((rc2 = getHeaderValue(header, value)) == 0))
   {
     if (streamInfo) processHeader(header, value, streamInfo);
     delete [] header;
     delete [] value;
   }
 
   if (rc1 == VXIinet_RESULT_SUCCESS && rc2 < 0)
   {
     Diag(MODULE_SBINET_STREAM_TAGID,
          L"SBinetHttpStream::parseHeaders",
          L"Error in parsing header line: URL = <%s>, METHOD = %s, rc2 = %d",
          _url->getAbsolute(),
          _method == GET_METHOD ? L"GET" : L"POST",
          rc2);
     rc1 = VXIinet_RESULT_NON_FATAL_ERROR;
   }
   return rc1;
 }
 
 
 void SBinetHttpStream::processHeaderInfo(VXIMap *streamInfo)
 {
   // Extract the content-length to find out how many bytes are left to be
   // read from the stream.  If the stream is chunked, ignore
   // content-length from the server.  If we don't have the content, we
   // have to set the property to 0.
   VXIulong contentSize = (_chunked || _leftToRead == ~0) ? 0 : _leftToRead;
   VXIMapSetProperty(streamInfo, INET_INFO_SIZE_BYTES,
                     (VXIValue *) VXIIntegerCreate((int) contentSize));
 
   const VXIchar *tmp = _url->getAbsolute();
   if (tmp != NULL)
   {
     Diag(MODULE_SBINET_STREAM_TAGID,
          L"SBinetHttpStream::processHeaderInfo", L"%s%s",
          L"absolute", tmp);
     VXIMapSetProperty(streamInfo,
                       INET_INFO_ABSOLUTE_NAME,
                       (VXIValue*)VXIStringCreate(tmp));
   }
 
   const VXIString *contentType =
     (const VXIString *) VXIMapGetProperty(streamInfo, INET_INFO_MIME_TYPE);
 
   tmp = contentType != NULL ? VXIStringCStr(contentType) : NULL;
 
   if (!tmp || !*tmp
       || ::wcscmp(tmp, _channel->getDefaultMimeType()) == 0)
   {
     VXIString *newContentType = _url->getContentTypeFromUrl();
     if (newContentType != NULL)
     {
       Error (300, L"%s%s%s%s",
              L"URL", _url->getAbsolute(),
              L"mime-type", VXIStringCStr(newContentType));
     }
     else
     {
       newContentType = VXIStringCreate(_channel->getDefaultMimeType());
       Error (301, L"%s%s", L"URL", _url->getAbsolute());
     }
     VXIMapSetProperty(streamInfo, INET_INFO_MIME_TYPE,
 		      (VXIValue *) newContentType);
   }
 }
 
 
 void SBinetHttpStream::setValidatorInfo(VXIMap *streamInfo, time_t requestTime)
 {
   _validator = new SBinetValidator(GetLog(), GetDiagBase());
 
   if (_validator->Create(_url->getAbsolute(), requestTime, streamInfo) == VXIinet_RESULT_SUCCESS)
   {
     SBinetUtils::setValidatorInfo(streamInfo, _validator);
   }
 }
 
 
 VXIinetResult SBinetHttpStream::getHeaderInfo(VXIMap* streamInfo)
 {
   SWITimeWatch timeWatch;
   timeWatch.start();
 
   VXIinetResult rc = getStatus();
   Diag(MODULE_SBINET_TIMING_TAGID, L"SBinetHttpStream::getStatus",
        L"%i msecs, Wait for HTTP response", timeWatch.getElapsed());
 
   if (rc == VXIinet_RESULT_SUCCESS)
   {
     rc = parseHeaders(streamInfo);
   }
 
   Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetHttpStream::getHeaderInfo",
        L"rc = %d, HttpStatus = %d", rc, _HttpStatus);

⌨️ 快捷键说明

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