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

📄 sbinethttpstream.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Rather than Sleep and Wake on timers, lets try increasing timeouts    //  worse case, process should take 128ms more than necessary.    if(sleepTime < 100) sleepTime *= 2;  }  if((m_HttpStatus < 0) || !((m_HttpStatus/100 == 2) || (m_HttpStatus == 304))){    Error(219, L"%s%s%s%s%s%d", L"URL", m_url->GetAbsolute(),           L"Method", (m_method == GET_METHOD) ? L"GET" : L"POST",          L"Error", m_HttpStatus);    Close();      return(MapError(m_HttpStatus));  }  /*   * Success   */  // Init for reading  m_ReadSoFar = 0;  SBinetInterface::LockLibwww( );  // clean up -- we seem to be able to delete and flush in either order.  //                flush calls the after filters, so delete first??  HTRequest_deleteAfterAll(m_request);  // Why do we flush?? -- If we don't we crash!!!  HTRequest_forceFlush(m_request);  // Get header info  GetHeaderInfo(streamInfo);  SBinetInterface::UnlockLibwww( );  if((validatorVal != NULL) && (m_HttpStatus == 304)) {    Close();    return VXIinet_RESULT_NOT_MODIFIED;  }  return VXIinet_RESULT_SUCCESS;}//// Read is the same for all HTTP requests (GET and POST)//   At the moment, Read is not locks as merely copies data out of chunk//VXIinetResultSBinetHttpStream::Read(VXIbyte                 *buffer,		       VXIulong                 buflen,		       VXIulong                *nread){  if(nread != NULL) *nread = 0L;  if(m_chunk == NULL) {    Error(221, NULL);    return VXIinet_RESULT_FAILURE;  }  int len = HTChunk_size(m_chunk);  int toRead = buflen;  int remaining = len - m_ReadSoFar;  if(remaining <= 0) return(VXIinet_RESULT_END_OF_STREAM);  if(toRead > remaining) toRead = remaining;  char* data = HTChunk_data(m_chunk);  if(data == NULL) {    Error(220, NULL);    return VXIinet_RESULT_FAILURE;  }  data += m_ReadSoFar;  ::memcpy( (void*)buffer, (void*)data, toRead );  m_ReadSoFar += toRead;  if(nread != NULL) *nread = toRead;  return(VXIinet_RESULT_SUCCESS);}VXIinetResultSBinetHttpStream::Close(){  // If no request (multiple calls to Close() are allowed),   // check lock to make sure.  if(m_request == NULL){    if(m_lock){      m_lock->FreeReadLock(m_request);   // free lock on anchor      m_lock = NULL;      return(VXIinet_RESULT_SUCCESS);    }  }  /* Clean up the request    *  Note: we might want to do the delete in the destructor to give libwww extra time   *   to settle down   */  SBinetInterface::LockLibwww( );  if(m_chunk){    HTChunk_delete(m_chunk);    m_chunk = NULL;  }  if(m_request){    HTRequest_kill( m_request );    HTRequest_delete(m_request);    m_request = NULL;  }  if(m_lock){    m_lock->FreeReadLock(m_request);   // free lock on anchor    m_lock = NULL;  }  SBinetInterface::UnlockLibwww( );  /*   * Might need to do Sleep here to let libwww timers settle out   */  return(VXIinet_RESULT_SUCCESS);}SBinetHttpStream::SBinetHttpStream(SBinetURL* url, SBinetChannel* ch,                          VXIlogInterface *log, VXIunsigned diagLogBase):  SBinetLogger(MODULE_SBINET_STREAM, log, diagLogBase),   m_submitMimeType(), m_content_type(){  m_request = NULL;  m_chunk = NULL;  m_argstring = L"";  // string representation of query ares for GET  m_queryArgs = NULL;  m_Done = 0;  m_ReadSoFar = 0;  m_HttpStatus = 0;      m_url = url;  m_iMaxAge = -1;  m_iMaxStale = 0;  m_nTimeoutOpen = 0;  m_nTimeoutIO = 0;  m_method = GET_METHOD;  m_newAnchor = NULL;  m_lock = NULL;  m_content_length = 0;  m_reader = 2;  m_ch = ch;}SBinetHttpStream::~SBinetHttpStream(){  Close();  if(m_url) delete m_url;}voidSBinetHttpStream::SetProperties(VXIMap* properties){  const VXIString* strCachingMode =     (const VXIString*)VXIMapGetProperty( properties, INET_CACHING );  const VXIInteger* intMaxAge =     (const VXIInteger*)VXIMapGetProperty( properties, 					  INET_CACHE_CONTROL_MAX_AGE );  const VXIInteger* intMaxStale =     (const VXIInteger*)VXIMapGetProperty( properties, 					  INET_CACHE_CONTROL_MAX_STALE );  // Cache control, INET_CACHING overrides the individual settings  m_iMaxAge = -1;  m_iMaxStale = 0;  if ( intMaxAge != NULL )     m_iMaxAge = VXIIntegerValue(intMaxAge);  if ( intMaxStale != NULL )    m_iMaxStale = VXIIntegerValue(intMaxStale);  if (( strCachingMode != NULL ) &&       ( VXIStringCompareC( strCachingMode, INET_CACHING_SAFE  ) == 0 )) {    m_iMaxAge = 0;    m_iMaxStale = 0;  }  // Open timeout  m_nTimeoutOpen = INET_TIMEOUT_OPEN_DEFAULT * 10; // TBD wrong!  VXIInteger *timeoutOpen =     (VXIInteger *)VXIMapGetProperty( properties, INET_TIMEOUT_OPEN );  if( timeoutOpen != NULL )     m_nTimeoutOpen = VXIIntegerValue( timeoutOpen );  // IO timeout  m_nTimeoutIO = INET_TIMEOUT_IO_DEFAULT;  VXIInteger *timeoutIO =     (VXIInteger *)VXIMapGetProperty( properties, INET_TIMEOUT_IO );  if( timeoutIO != NULL )     m_nTimeoutIO = VXIIntegerValue( timeoutIO );  // Get the submit MIME type from the properties, if defined  const VXIchar* wType = INET_SUBMIT_MIME_TYPE_DEFAULT;  VXIString *strType =     (VXIString *)VXIMapGetProperty( properties, INET_SUBMIT_MIME_TYPE );  if ( strType ) wType = VXIStringCStr( strType );  m_submitMimeType = "";  size_t len = ::wcslen( wType );  for (size_t i = 0; i < len; i++)    m_submitMimeType += (char) wType[i];  // Get the SUBMIT method from the properties, if defined  wType = INET_SUBMIT_METHOD_DEFAULT;  m_method = GET_METHOD;  strType = (VXIString *)VXIMapGetProperty( properties, INET_SUBMIT_METHOD );  if ( strType ) {    wType = VXIStringCStr( strType );    if ( !::wcscmp( wType, INET_SUBMIT_METHOD_GET  ))      m_method = GET_METHOD;    else if ( !::wcscmp( wType, INET_SUBMIT_METHOD_POST  ))      m_method = POST_METHOD;  }  // Get the query arguments, if defined  m_queryArgs = (VXIMap *)VXIMapGetProperty( properties, INET_URL_QUERY_ARGS );}VXIinetResult SBinetHttpStream::SetCachingMode( ){    if ( m_iMaxAge == 0 )    {       // We always want to check Modified and Validator       HTRequest_addRqHd(m_request, HT_C_IF_NONE_MATCH );       HTRequest_addRqHd(m_request, HT_C_IMS);       // We may have to use _VALIDATE rather then _END_VALIDATE  for       //  the non-proxy case to avoid gratuitous downloads       HTRequest_setReloadMode( m_request, HT_CACHE_END_VALIDATE );    }    else    {       HTRequest_setReloadMode( m_request, HT_CACHE_OK );    }    return VXIinet_RESULT_SUCCESS;}void SBinetHttpStream::GetHeaderInfo(VXIMap* streamInfo){  HTParentAnchor* anchor      = HTRequest_anchor(m_request);  int nStatus = m_HttpStatus;  // Check if the HTTP return status is 200 (OK) or 304 (NOT_MODIFIED)  if (( streamInfo != NULL ) && (( nStatus == 200 ) || ( nStatus == 304 ))){    // Set HTTP status    VXIMapSetProperty(streamInfo, INET_INFO_HTTP_STATUS,			  (VXIValue*)VXIIntegerCreate( nStatus ));    // Set the ABSOLUTE_NAME property to the URL returned by the server    char *serverURL = HTAnchor_address((HTAnchor *)anchor);    if(( serverURL != NULL ) && ( serverURL[0] != '\0' )){	VXIint len = ::strlen( serverURL ) + 1;	VXIchar *wServerURL = new VXIchar [len];	::mbstowcs( wServerURL, serverURL, len );	VXIMapSetProperty(streamInfo, INET_INFO_ABSOLUTE_NAME, 			  (VXIValue*)VXIStringCreate( wServerURL ));	delete [] wServerURL;    }    HT_FREE(serverURL); // HTAnchor_address does MALLOC or copy    // Get relevant response fields    m_content_length = HTAnchor_length(anchor);    m_content_type = L"";    VXIbool haveValidator = FALSE;    SBinetValidator validator(GetLog(), GetDiagBase());    if (validator.Create(m_url->GetAbsolute(), HTAnchor_lastModified(anchor),			 HTAnchor_expires(anchor), m_content_length,			 HTAnchor_etag(anchor), HTAnchor_header(anchor))              == VXIinet_RESULT_SUCCESS) {      validator.Log(MODULE_SBINET_STREAM_TAGID, 		    L"SBinetHttpStream::GetHeaderInfo");      haveValidator = TRUE;    }    const char *contentType = HTAtom_name(HTAnchor_format(anchor));    if (( contentType ) && ( contentType[0] ) &&	( ::strcmp(contentType, DEFAULT_GENERIC_MIME_TYPE_N) != 0 )) {      size_t len = ::strlen(contentType);      for (size_t i = 0; i < len; i++)	    m_content_type += (VXIchar) contentType[i];    } else {      VXIinetResult rc = m_url->ContentTypeFromUrl(&m_content_type);      if(rc == VXIinet_RESULT_SUCCESS) {        Error (300, L"%s%s%s%s", L"url", m_url->GetAbsolute(), 	       L"mime", m_content_type.c_str());      } else {	    m_content_type = DEFAULT_GENERIC_MIME_TYPE;        Error (301, L"%s%s", L"url", m_url->GetAbsolute());      }    }    // Fill properties     VXIMapSetProperty( streamInfo, INET_INFO_SIZE_BYTES, 		       (VXIValue*)VXIIntegerCreate(m_content_length));    VXIMapSetProperty( streamInfo, INET_INFO_MIME_TYPE, 		       (VXIValue*)VXIStringCreate(m_content_type.c_str()));    if (haveValidator)      VXIMapSetProperty(streamInfo, INET_INFO_VALIDATOR, 			(VXIValue*)validator.Serialize());      } // Ends if (streamInfo && HTTP200/304)  }VXIinetResult SBinetHttpStream::MapError(int ht_error){  switch(ht_error)    {    case HT_NO_ACCESS: /* Unauthorized */    case HT_FORBIDDEN: /* Access forbidden */    case HT_NOT_ACCEPTABLE:/* Not Acceptable */    case HT_NO_PROXY_ACCESS:    /* Proxy Authentication Failed */    case HT_CONFLICT:    /* Conflict */    case HT_LENGTH_REQUIRED:    /* Length required */    case HT_PRECONDITION_FAILED:    /* Precondition failed */    case  HT_TOO_BIG:    /* Request entity too large */    case HT_URI_TOO_BIG:    /* Request-URI too long */    case HT_UNSUPPORTED:    /* Unsupported */    case HT_BAD_RANGE:    /* Request Range not satisfiable */    case HT_EXPECTATION_FAILED:    /* Expectation Failed */    case HT_REAUTH:    /* Reauthentication required */    case HT_PROXY_REAUTH:    /* Proxy Reauthentication required */    case HT_RETRY:	/* If service isn't available */    case HT_BAD_VERSION:	/* Bad protocol version */      return VXIinet_RESULT_FETCH_ERROR;    case HT_INTERNAL:    /* Weird -- should never happen. */      return VXIinet_RESULT_NON_FATAL_ERROR;    case  HT_WOULD_BLOCK:    /* If we are in a select */      return VXIinet_RESULT_WOULD_BLOCK;    case HT_INTERRUPTED:    /* Note the negative value! */    case HT_PAUSE:    /* If we want to pause a stream */    case HT_RECOVER_PIPE:    /* Recover pipe line */      return VXIinet_RESULT_SUCCESS;    case HT_TIMEOUT:    /* Connection timeout */      return VXIinet_RESULT_FETCH_TIMEOUT;    case HT_NOT_FOUND: /* Not found */    case HT_NO_HOST:    /* Can't locate host */      return VXIinet_RESULT_NOT_FOUND;    default:      return VXIinet_RESULT_NON_FATAL_ERROR;    }}/* * Return one if there is a non-expired cache copy and we can use it without validation */staticint CacheValid (HTRequest * request){    HTParentAnchor * anchor = HTRequest_anchor(request);    char * default_name = HTRequest_defaultPutName (request);     HTCache * cache = NULL;    HTReload reload = HTRequest_reloadMode(request);    HTMethod method = HTRequest_method(request);    HTDisconnectedMode disconnect = HTCacheMode_disconnected();    BOOL validate = NO;    /*    **  If the cache is disabled all together then it won't help looking, huh?    */    if (!HTCacheMode_enabled()) return(0);    /*    **  Now check the cache...    */    if (method != METHOD_GET) {      return(0);    } else if (reload == HT_CACHE_FLUSH) {      return(0);    } else {	/*	** Check the persistent cache manager. If we have a cache hit then	** continue to see if the reload mode requires us to do a validation	** check. This filter assumes that we can get the cached version	** through one of our protocol modules (for example the file module)	*/	cache = HTCache_find(anchor, default_name);	if (cache) {	    HTReload cache_mode = HTCache_isFresh(cache, request);	    if (cache_mode == HT_CACHE_ERROR) cache = NULL;	    reload = HTMAX(reload, cache_mode);	    /*	    **  Now check the mode and add the right headers for the validation	    **  If we are to validate a cache entry then we get a lock	    **  on it so that not other requests can steal it.	    */	    if (reload == HT_CACHE_RANGE_VALIDATE) {	      return(0);	    } else if (reload == HT_CACHE_END_VALIDATE) {	      return(0);	    } else if (reload == HT_CACHE_VALIDATE) {	      return(0);	    } else if (cache) {		/*		**  The entity does not require any validation at all. We		**  can just go ahead and get it from the cache. In case we		**  have a fresh subpart of the entity, then we issue a 		**  conditional GET request with the range set by the cache		**  manager. Issuing the conditional range request is 		**  equivalent to a validation as we have to go out on the		**  net. This may have an effect if running in disconnected		**  mode. We disable all BEFORE filters as they don't make		**  sense while loading the cache entry.		*/	      return(1);	    }	}    }    return(0);}

⌨️ 快捷键说明

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