📄 httpfsys.cpp
字号:
CHTTPFileObject::InitObject( char* szBaseURL, IHXFileSystemObject* pFS, IUnknown* pContext, IHXValues* pOptions){ LOGX ((szDbgTemp, "InitObject(%s)", NULLOK(szBaseURL))); if (szBaseURL) { m_szBaseURL = new_string(szBaseURL); } if (pFS) { m_pFileSystem = pFS; m_pFileSystem->AddRef(); } if (pContext) { m_pContext = pContext; m_pContext->AddRef(); m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler); m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void **)&m_pCommonClassFactory); m_pContext->QueryInterface(IID_IHXPreferences, (void **)&m_pPreferences); m_pContext->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry); m_pContext->QueryInterface(IID_IHXErrorMessages, (void**)&m_pErrorMessages); m_pContext->QueryInterface(IID_IHXInterruptState, (void**)&m_pInterruptState); m_pContext->QueryInterface(IID_IHXCookies, (void**)&m_pCookies); m_pContext->QueryInterface(IID_IHXCookies2, (void**)&m_pCookies2); // Figure out if we're on the server IHXServerControl* pServerControl = NULL; m_pContext->QueryInterface(IID_IHXServerControl, (void**)&pServerControl); if (pServerControl) { m_bOnServer = TRUE; } HX_RELEASE(pServerControl); } if (pOptions) { m_pOptions = pOptions; m_pOptions->AddRef(); } // // get proxy info for HTTP protocol // IHXBuffer* pBuffer = NULL; UINT32 ulValue = 0; if (m_pPreferences) { IHXBuffer* pBuffer = NULL; // Get Language preference, if available if (m_pLanguage==NULL) { IHXRegistry* pRegistry = NULL; if (m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry) == HXR_OK) { CHXString strTemp; strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"Language"); pRegistry->GetStrByName(strTemp, m_pLanguage); pRegistry->Release(); } } // if the language pref is an empty string, we're not // interested if (m_pLanguage) { if ( *(m_pLanguage->GetBuffer()) == '\0') { HX_RELEASE(m_pLanguage); } } // Get connection timeout, if available m_pPreferences->ReadPref("ConnectionTimeout", pBuffer); // If the connection timeout is an empty string, we're not // interested if (pBuffer && *(pBuffer->GetBuffer()) != '\0') { m_nConnTimeout = (UINT32) (atol((const char*)pBuffer->GetBuffer()) * MILLISECS_PER_SECOND); } HX_RELEASE(pBuffer); // Check the file system options last if (m_pOptions && HXR_OK == m_pOptions->GetPropertyULONG32("ConnectionTimeout", ulValue)) { m_nConnTimeout = ulValue * MILLISECS_PER_SECOND; } // Finally, fall back to the default if (m_nConnTimeout <= 0) m_nConnTimeout = DEF_HTTP_CONNECT_TIMEOUT; // Get server timeout, if available m_pPreferences->ReadPref("ServerTimeout", pBuffer); // If the connection timeout is an empty string, we're not // interested if (pBuffer && *(pBuffer->GetBuffer()) != '\0') { m_nServerTimeout = (UINT32) (atol((const char*)pBuffer->GetBuffer()) * MILLISECS_PER_SECOND); } HX_RELEASE(pBuffer); // Check the file system options last if (m_pOptions && HXR_OK == m_pOptions->GetPropertyULONG32("ServerTimeout", ulValue)) { m_nServerTimeout = ulValue * MILLISECS_PER_SECOND; } // Finally, fall back to the default if (m_nServerTimeout <= 0) m_nServerTimeout = DEF_HTTP_SERVER_TIMEOUT; // Find out if Cookie Mangling is enabled if (m_pOptions && HXR_OK == m_pOptions->GetPropertyULONG32("MangleCookies", ulValue)) { m_bMangleCookies = (BOOL)ulValue; }// if (szBaseURL && ::strncmp (szBaseURL, "http:", 5) == 0) { CacheSupport_InitObject(); } } m_pChunkyRes = new CChunkyRes; #ifdef CREATE_LOG_DUMP FILE *fp = fopen(LOG_DUMP_FILE, "a+"); if (fp) { fprintf(fp, "NewChunky %lx\n", m_pChunkyRes); fclose(fp); } #endif if (m_bOnServer) { m_pChunkyRes->DisableDiskIO(); }#if defined(HELIX_FEATURE_HTTP_GZIP) m_pDecoder = new CDecoder; if (m_pDecoder && m_pChunkyRes) { m_pDecoder->SetOutputSink(m_pChunkyRes); }#endif m_pCallback = HTTPFileObjCallback::CreateObject(); if (m_pCallback) { m_pCallback->InitObject(this); // XXXkshoop This is illegal! (it is not an interface pointer..) // m_pCallback->AddRef(); }}CHTTPFileObject::~CHTTPFileObject(){ LOGX ((szDbgTemp, "FileObject destructor (%s)", m_bClosed?"Closed":"Not closed") ); if(m_bInDestructor) { return; } m_bInDestructor = TRUE; Close();}/************************************************************************ * Method: * IHXFileObject::Init * Purpose: * Associates a file object with the file response object it should * notify of operation completness. This method should also check * for validity of the object (for example by opening it if it is * a local file). */STDMETHODIMP CHTTPFileObject::Init( ULONG32 /*IN*/ ulFlags, IHXFileResponse* /*IN*/ pFileResponse){ LOG ("Init()"); HX_RESULT theErr = HXR_OK; HX_RESULT lResult = HXR_OK; char* pTemp = NULL; char* pRes = NULL; HX_RELEASE(m_pFileResponse); m_pFileResponse = pFileResponse; if (m_pFileResponse) { m_pFileResponse->AddRef(); } /* This is temporary for Flash fileformat on Mac. We need to set a really low * value for recursion guard for flash fileformat since it puts everything * on freaki'n stack thereby blowing the system stack limit on Mac (looks like * there is one since it corrupts the heap) very easily. */ #if defined (_MACINTOSH) IHXGetRecursionLevel* pGet = NULL; HX_RESULT lThisResult = HXR_OK; lThisResult = m_pFileResponse->QueryInterface(IID_IHXGetRecursionLevel, (void**) &pGet); if (lThisResult == HXR_OK) { m_uMaxRecursionLevel = pGet->GetRecursionLevel(); pGet->Release(); }#endif if (m_bInitialized) { if (m_LastError == HXR_OK) { /* If we have already opened a file, then seek back * to zero during re-initialization */ m_ulCurrentReadPosition = 0; m_bServerPresumablyWorksWithByteRangeRequests = TRUE; m_pFileResponse->InitDone(HXR_OK); return HXR_OK; } else { m_pFileResponse->InitDone(HXR_FAILED); return HXR_FAILED; } } theErr = _OpenFile(m_pFilename, ulFlags); if (HXR_OK == theErr || HXR_WOULD_BLOCK == theErr) { if (m_bCached) { LOG (" Calling InitDone(OK) [cached]"); m_ulCurrentReadPosition = 0; m_bServerPresumablyWorksWithByteRangeRequests = TRUE; m_pFileResponse->InitDone(HXR_OK); } else { m_bInitResponsePending = TRUE; } } else { m_pFileResponse->InitDone(HXR_FAILED); } return theErr;}/************************************************************************ * Method: * IHXFileObject::GetFilename * Purpose: * Returns the filename (without any path information) associated * with a file object. */STDMETHODIMP CHTTPFileObject::GetFilename( REF(const char*) /*OUT*/ pFilename){ // Find the separator character before the file name pFilename = ::strrchr(m_pFilename, OS_SEPARATOR_CHAR); // File may not be local so try a '/' separator // it could also be a MAC on the :// protocol point... if (pFilename == NULL || ( *pFilename == ':' && *(pFilename + 1) == '/' ) ) { pFilename = ::strrchr(m_pFilename, '/'); } if (pFilename != NULL) // Found { // File name starts after the separator charactor pFilename++; } else // Not found { pFilename = m_pFilename; } return HXR_OK;}/************************************************************************ * Method: * IHXFileObject::Close * Purpose: * Closes the file resource and releases all resources associated * with the object. */STDMETHODIMP CHTTPFileObject::Close(){ LOGX ((szDbgTemp, "Close(%s)", m_pFilename)); if (m_bGetProxyInfoPending) { m_bGetProxyInfoPending = FALSE; m_pPAC->AbortProxyInfo(this); } HX_RELEASE(m_pFileSystem); HX_RELEASE(m_pRequest); HX_RELEASE(m_pRequestHeadersOrig); HX_RELEASE(m_pParams); HX_RELEASE(m_pRedirectResponse); HX_RELEASE(m_pCacheFile); HX_RELEASE(m_pInterruptState); HX_RELEASE(m_pRegistry); HX_RELEASE(m_pCookies); HX_RELEASE(m_pCookies2); HX_RELEASE(m_pPAC); HX_RELEASE(m_pMangledCookies); HX_RELEASE(m_pContext); HX_RELEASE(m_pOptions); // If there is a pending callback, be sure to remove it! if (m_pCallback && m_pCallback->m_ulPendingCallbackID && m_pScheduler) { m_pScheduler->Remove(m_pCallback->m_ulPendingCallbackID); } HX_RELEASE(m_pCallback); HX_RELEASE(m_pScheduler); HX_RELEASE(m_pCommonClassFactory); HX_RELEASE(m_pErrorMessages); if (m_pTCPResponse) { m_pTCPResponse->m_pOwner = NULL; HX_RELEASE(m_pTCPResponse); } HX_RELEASE(m_pSocket); HX_RELEASE(m_pMimeMapperResponse); HX_RELEASE(m_pFileExistsResponse); HX_RELEASE(m_pFileStatResponse); HX_RELEASE(m_pPreferences); HX_RELEASE(m_pLanguage); HX_VECTOR_DELETE(m_szBaseURL); HX_VECTOR_DELETE(m_pFilename); HX_VECTOR_DELETE(m_pPath); HX_VECTOR_DELETE(m_pHost);#if defined(HELIX_FEATURE_HTTP_GZIP) HX_DELETE(m_pDecoder);#endif HX_DELETE(m_pChunkyRes); if (m_pChunkedEncoding) { HX_VECTOR_DELETE(m_pChunkedEncoding->buf); HX_DELETE(m_pChunkedEncoding); } while (m_pPACInfoList && m_pPACInfoList->GetCount()) { PACInfo* pPACInfo = (PACInfo*)m_pPACInfoList->RemoveHead(); HX_DELETE(pPACInfo); } HX_DELETE(m_pPACInfoList); if (!m_bInDestructor) { AddRef(); if (m_pFileResponse) { // Call CloseDone() m_pFileResponse->CloseDone(HXR_OK); // Keeps us from getting into an infinite loop when // we have two FileObjects on the same file which causes the // ref counts on the objects to be such that this's m_pFileResponse // object drops the ref count on this which causes it to destruct // which causes it to call ::Close() which *used to* again call // HX_RELEASE(m_pFileResponse) which *used to* again release *this which // called ::Close()...etc until the stack blew up. This fix // keeps it from spinning out of control by setting m_pFileResponse // to NULL before releasing it via temp ptr: IHXFileResponse* pTempFileResponse = m_pFileResponse; m_pFileResponse = NULL; HX_RELEASE(pTempFileResponse); } Release(); } else if (m_pFileResponse) { HX_RELEASE(m_pFileResponse); } HX_VECTOR_DELETE(m_pLastHeader); // Flag to let us know that we've been closed m_bClosed = TRUE; return HXR_OK;}voidCHTTPFileObject::CallReadDone(HX_RESULT status, IHXBuffer* pBuffer){ m_bInReadDone = TRUE; // Let the file response sink know about the buffer... HX_ASSERT(m_pFileResponse) ; if (m_pFileResponse) { #ifdef CREATE_LOG_DUMP FILE *fp = fopen(LOG_DUMP_FILE, "a+"); if (fp) { fprintf(fp, "ReadDone %lx at %ld %d\n", m_pChunkyRes, m_ulCurrentReadPosition, pBuffer ? pBuffer->GetSize() : 0); fclose(fp); } #endif m_pFileResponse->ReadDone(status, pBuffer); } m_bInReadDone = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -