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

📄 xpt-http.c

📁 SyncML ToolKits,学习syncml的参考工具包.非常好用.
💻 C
📖 第 1 页 / 共 5 页
字号:
         if (!xppStricmp (pszToken, "stale") && !xppStricmp (pszValue, "true"))            ad.bStale = true;         else            ad.bStale = false;         if (!xppStricmp (pszToken, "domain"))            ad.szDomain = pszParm;         }      authSetType (auth, dest, typ);      authSetAuthenticationData (auth, dest, &ad);      }   }#define EVALUATE_FIELD(f,n,p,t,v) if (!xppStricmp ((t),(f))) {(n)((p),(v)); }#define EVALUATE_AUTH_FIELD(f,n,p,t,v,a,d) if (!xppStricmp ((t),(f))&&((a)!=NULL)) {(n)((p),(v),(a),(d));}/*************************************************************************//* Function: Analyze one line from the HTTP header block, and update     *//* the HTTP object store if something interesting was found.             *//* In case of an empty string, the function returns true:                *//* An empty string indicates the end of the HTTP header block            *//*************************************************************************/Bool_t evaluateHttpHeaderLine (HttpBufferPtr_t p,           // i: instance object                               StringBuffer_t pszLine, // i: one HTTP header line                               HttpAuthenticationPtr_t auth) // i/o: authorization info   {   Bool_t bFinished = false;   CString_t pszToken = NULL;   /*******************************************************/   /* An empty line indicates the end of the HTTP header. */   /*******************************************************/   if (pszLine == NULL)      return true;        // this should never occur.   if  (pszLine [0] == '\0')      {      if (    (p->fOpenMode == MODE_HTTP_SERVER)           || (p->bEox == false)           || (p->iHttpStatus == 204) || (p->iHttpStatus == 205) || (p->iHttpStatus == 304)           || (p->iHttpStatus == 100) || (p->iHttpStatus == 101) )         bFinished = true;               // Empty Line indicates end of HTTP header!      }   else      {      pszLine = splitToken (pszLine, &pszToken); // get the keyword of the HTTP header line      if (!pszToken)         {         bFinished = true; // this could be an error!!!         }      else         {         /*********************************************************/         /* The first line of the HTTP header is handled this way */         /*********************************************************/         if ((p->pchRequest == NULL) && (p->fOpenMode == MODE_HTTP_SERVER))            {            p->pchRequest = makeString (pszToken);            pszLine = splitToken (pszLine, &pszToken);            if (pszToken != NULL)               {               const char *pszURL = getResourceName (pszToken);               /*********************/               /* Get the URL name. */               /*********************/               p->pchURI = makeString (pszURL);               }            }         else if ((p->iHttpStatus == HTTP_STATUS_UNDEFINED) &&                  (p->fOpenMode != MODE_HTTP_SERVER))            {            while (pszLine [xppStrlen(pszLine)-1] == ' ')               pszLine [xppStrlen(pszLine)-1] = '\0'; /* cut trailing blanks */            p->iHttpStatus = xppAtoi (pszLine);            }         /******************************************************/         /* Look for the keywords that are interesting for me: */         /* Host - IP address of the host                      */         /* Referer - name of the referenced document          */         /* Content-Length - size of the document to receive   */         /* Content-Type - Document mime type                  */         /* Connection - Connection type                       */         /* Authorization -client authorization data           */         /* Authentication-Info - server authentication data   */         /*                                                    */         /* If Content-Length or Transfer-Encoding is speci-   */         /* fied, we recognize that a document is attached to  */         /* the HTTP header.                                   */         /*                                                    */         /* ignore the other keywords                          */         /******************************************************/         else            {            EVALUATE_FIELD ("Host:", evaluateHdrHost, p, pszToken, pszLine)            EVALUATE_FIELD ("From:", evaluateHdrFrom, p, pszToken, pszLine)            EVALUATE_FIELD ("Referer:", evaluateHdrReferer, p, pszToken, pszLine)            EVALUATE_FIELD ("Content-Length:", evaluateHdrContentLength, p, pszToken, pszLine)            EVALUATE_FIELD ("Content-Type:", evaluateHdrContentType, p, pszToken, pszLine)            EVALUATE_FIELD ("Connection:", evaluateHdrConnection, p, pszToken, pszLine)            EVALUATE_FIELD ("Transfer-Encoding:", evaluateHdrTransferEncoding, p, pszToken, pszLine)			EVALUATE_FIELD ("x-syncml-hmac:", evaluateHdrXSyncmlHmac, p, pszToken, pszLine)            EVALUATE_AUTH_FIELD ("Authorization:", evaluateHdrAuthorization, p, pszToken, pszLine, auth, DEST_SERVER)            EVALUATE_AUTH_FIELD ("Authentication-Info:", evaluateHdrAuthenticationInfo, p, pszToken, pszLine, auth, DEST_NONE)            EVALUATE_AUTH_FIELD ("WWW-Authenticate:", evaluateHdrWWWAuthenticateInfo, p, pszToken, pszLine, auth, DEST_SERVER)            EVALUATE_AUTH_FIELD ("Proxy-Authenticate:", evaluateHdrWWWAuthenticateInfo, p, pszToken, pszLine, auth, DEST_PROXY)            }         }      }   return bFinished;   }/***********************************************************************************//* Function: Some data have been received to the transfer buffer before, and it is *//* assumed that the data contain HTTP header information. Go and analyze the block *//* The function returns true if the end of the HTTP header has been detected.      *//* Those parts of the incoming data that could not be processed remain in the      *//* transfer buffer.                                                                *//***********************************************************************************/Bool_t evaluateHttpHeaderBlock (HttpBufferPtr_t p,            // i: instance object                                HttpAuthenticationPtr_t auth) // i/o: authorization info   {   Bool_t bHeaderCompleted = false;         // end of HTTP header detected?   Ptr_t pszEnd = (Ptr_t )(p->pbCache + p->cbCacheUsed); // end mark   StringBuffer_t pszCurrent = (StringBuffer_t) p->pbCache;   StringBuffer_t pszLine;   /***********************************************/   /* Loop thru the data in the transfer buffer,  */   /* and parse the HTTP header data line-by-line */   /***********************************************/   p->pbCache [p->cbCacheUsed] = '\0';   while ((pszCurrent != NULL) && (pszCurrent < (StringBuffer_t) pszEnd) && (bHeaderCompleted == false))      {      pszLine = pszCurrent;      pszCurrent = splitLine (pszCurrent);      if (pszCurrent == NULL)         {         /*********************************************/         /* We are still waiting for additional data. */         /* We must read the next block!              */         /*********************************************/         p->cbCacheUsed -= (BufferSize_t) (pszLine - (StringBuffer_t) p->pbCache);         if (p->cbCacheUsed > 0)            {            xppMemmove (p->pbCache, pszLine, p->cbCacheUsed);            p->pbCache [p->cbCacheUsed] = '\0';            }         }      else if (evaluateHttpHeaderLine (p, pszLine, auth))        {          /* T.K. Microsoft IIS 4/5 hack                                          */          /* IIS has the behavior of sending HTTP/1.1 100 Continue just           */          /* before sending the HTTP/1.1 200 OK - so we 'peek' in the remaining   */          /* buffer and see wether we are really finished or wether we need to go */          /* further. */                    /* %%% luz 2002-05-23: this is the wrong place for that, as IIS might                 choose to delay that "200 OK" header a little. We need to                 continue reading (in readHttpHeader()) if status was "100 Continue"                 and check if following data is "HTTP/1.1" again          		      int dummyInt = xppStrncmp(pszCurrent, "HTTP/1.1",8);          if (dummyInt == 0) {            p->iHttpStatus = HTTP_STATUS_UNDEFINED; // reset the unused status          } else          */          {            /****************************************************************************/            /* The header finished here. Copy the non-processed data (this is the first */            /* block of the data section) to the beginning of the cache, then return to */            /* the caller                                                               */            /****************************************************************************/            p->cbCacheUsed = (BufferSize_t) (pszEnd - pszCurrent);            if (p->cbCacheUsed > 0)              xppMemmove (p->pbCache, pszCurrent, p->cbCacheUsed);            bHeaderCompleted = true;          }        }      }   return bHeaderCompleted;   }#if SYDEBUG>1// %%% luzvoid DebugPrintf(const char *text, ...);#endif/****************************************************************************//* Function: read the HTTP header                                           *//* The function waits for incoming data and processes the HTTP header data. *//* When the function returns, the transfer buffer may already contain the   *//* first bytes of the document!                                             *//****************************************************************************/TcpRc_t readHttpHeader (HttpBufferPtr_t p, // i: instance object                        HttpAuthenticationPtr_t auth) // i/o: authorization info   {   BufferSize_t uBytesTransmitted;   Bool_t bHeaderProcessed = false;   /* %%% luz:2002-05-23: several changes (iispeek), see comments below */   Bool_t iispeek;   /****************/   /* Set defaults */   /****************/// p->fEncoding = FLAT;   p->fTransferCoding = NOT_CHUNKED;   p->fTransferMode = MODE_READING;   p->bEox = true;   p->cbDataLength = UNDEFINED_CONTENT_LENGTH;   freeString(p->sXSyncmlHmac.pchHmac);   p->sXSyncmlHmac.pchHmac = NULL;   p->sXSyncmlHmac.hmacInfo.mac = NULL;   p->sXSyncmlHmac.hmacInfo.username = NULL;   p->sXSyncmlHmac.hmacInfo.algorithm = NULL;   /*****************************************************************/   /* Go and receive all incoming TCP/IP packets                    */   /* until the HTTP header information has been parsed completely. */   /*****************************************************************/   /* %%% luz:2002-05-23: several changes (iispeek), see comment below */   iispeek=false; // no IIS peek done yet   while ((bHeaderProcessed == false) && (p->iRc == TCP_RC_OK))   {            /* get the next block of data */      uBytesTransmitted = (BufferSize_t)(sizeof (p->pbCache) - p->cbCacheUsed);      p->iRc = tcpReadData (p->pSession, p->pbCache+p->cbCacheUsed, &uBytesTransmitted);      if (p->iRc == TCP_RC_OK) {        p->cbCacheUsed += uBytesTransmitted;        do {                  // first check if we must peek for IIS before checking header          if (iispeek) {            // we have already processed a "100 continue" header.            // - check if we have at least 7 chars to check if another header is following            if (p->cbCacheUsed>7) {              iispeek=false; // we can check now, peek ends here              // NOTE: under some strange circumstances (special Auth software on IIS              //       which somehow intervenes normal IIS response, we can have the 100 Continue              //       followed by a HTTP 1.0 (!!). So we only check for "HTTP/1." here.              if (xppStrncmp((StringBuffer_t)p->pbCache, "HTTP/1.",7)==0) {                // - yes, parse it as if it was the first one                #if SYDEBUG>1 && !defined(__PALM_OS__)                // PalmOS has no %0.80s type formatting                DebugPrintf("########### p->cbCacheUsed=%ld, p->pbCache[0..79]='%0.80s'",p->cbCacheUsed,p->pbCache);                #endif                p->iHttpStatus = HTTP_STATUS_UNDEFINED; // reset the unused status              }              else {                // - no, this is NOT IIS 100 continue special case                bHeaderProcessed=true; // we are done now                break; // done with header (and some bytes in the cache)              }            }            else {              // else: iispeek remains pending, we need more data first              break;            }          }          // process header only if no iispeek is pending any more          if (!iispeek) {            bHeaderProcessed = evaluateHttpHeaderBlock (p, auth);            /* T.K. Microsoft IIS 4/5 hack */            /* %%% luz:2002-05-23: modified to work, moved here from                   evaluateHttpHeaderBlock().               IIS has the behavior of sending HTTP/1.1 100 Continue just               before sending the HTTP/1.1 200 OK - so we continue reading after               status==100 and see wether we are really finished or wether we need               to go further. */            if (bHeaderProcessed && p->iHttpStatus==100) {              iispeek=true; // we need to do IIS peek              bHeaderProcessed=false; // do not stop yet            }          } // if not peek pending        } while(iispeek);      } // if TCP read ok      else {        // %%% luz:2002-11-11 added to allow setting breakpoint on error        break;      }   } // while   /*************************************************************************/   /* Dependent on the HTTP header settings,                                */   /* the instance variable DataToRead must be set:                         */   /* if CHUNKED transfer coding is selected, the variable keeps the number */   /* of bytes that have not been for the current chunk, if NON_CHUNKED     */   /* transfer coding is selected, the number of bytes of the HTTP document */   /* itself is returned.                                                   */   /*************************************************************************/   if (p->iRc == TCP_RC_OK)      {      if (p->fTransferCoding == NOT_CHUNKED)         p->cbDataToRead = p->cbDataLength;      else         p->cbDataToRead = 0L;      }   return p->iRc;   }HttpRc_t continueHttpRequest (HttpBufferPtr_t p,                              HttpAuthenticationPtr_t auth) // i: ptr to authorization info   {   HttpRc_t rc = HTTP_RC_OK;   p->cbDataLength = 0;   writeRequestHeader (p, auth);   p->iRc = tcpSendData (p->pSession, p->pbCache, p->cbCacheUsed);   if (p->iRc != TCP_RC_OK)      rc = HTTP_RC_COMMUNICATION;   return rc;   }/********************************************************************//* Function: Create an instance of a HTTP object for a client       *//* The HTTP doc type is denoted by pszMode.                         *//********************************************************************/HttpRc_t openClient (HttpBufferPtr_t p,    // io: allocated instance object                     SocketPtr_t pSession, // i: ptr to created TCP/IP socket                     CString_t pszMode,    // i: Type of HTTP document                     HttpDocumentContextPtr_t settings, // i: document properties                     HttpAuthenticationPtr_t auth) // i: ptr to authorization info   {

⌨️ 快捷键说明

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