Ejemplo n.º 1
0
std::string WideToUTF8(const WString &inWideString)
{
  int len = 0;
  const wchar_t *chars = inWideString.c_str();
  for(int i=0;i<inWideString.length();i++)
   {
      int c = chars[i];
      if( c <= 0x7F ) len++;
      else if( c <= 0x7FF ) len+=2;
      else if( c <= 0xFFFF ) len+=3;
      else len+= 4;
   }


   std::string result;
   result.resize(len);
   unsigned char *data =  (unsigned char *) &result[0];
   for(int i=0;i<inWideString.length();i++)
   {
      int c = chars[i];
      if( c <= 0x7F )
         *data++ = c;
      else if( c <= 0x7FF )
      {
         *data++ = 0xC0 | (c >> 6);
         *data++ = 0x80 | (c & 63);
      }
      else if( c <= 0xFFFF )
Ejemplo n.º 2
0
///////////////////////////////////////////////////////////////
//
// DelTree
//
//
//
///////////////////////////////////////////////////////////////
bool SharedUtil::DelTree ( const SString& strPath, const SString& strInsideHere )
{
    // Safety: Make sure strPath is inside strInsideHere
    WString wstrPath = FromUTF8( strPath );
    WString wstrInsideHere = FromUTF8( strInsideHere );
    if ( !wstrPath.BeginsWithI( wstrInsideHere ) )
    {
        assert ( 0 );
        return false;
    }

    DWORD dwBufferSize = ( wstrPath.length() + 3 ) * sizeof( wchar_t );
    wchar_t *szBuffer = static_cast < wchar_t* > ( alloca ( dwBufferSize ) );
    memset ( szBuffer, 0, dwBufferSize );
    wcsncpy ( szBuffer, wstrPath, wstrPath.length() );
    SHFILEOPSTRUCTW sfos;

    sfos.hwnd = NULL;
    sfos.wFunc = FO_DELETE;
    sfos.pFrom = szBuffer;  // Double NULL terminated
    sfos.pTo = NULL;
    sfos.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;

    int status = SHFileOperationW(&sfos);
    return status == 0;
}
Ejemplo n.º 3
0
//
// Remove szOlds from the end of the string.
//
WString WString::TrimEnd ( const wchar_t* szOld ) const
{
    const size_t uiOldLength = wcslen ( szOld );
    WString strResult = *this;
    while ( strResult.length () >= uiOldLength && strResult.substr ( strResult.length () - uiOldLength ) == szOld )
        strResult = strResult.substr ( 0, strResult.length () - uiOldLength );
    return strResult;
}
Ejemplo n.º 4
0
	String md5(const WString& source)
	{
		MD5 md5;
		md5.update((UINT8*)source.c_str(), (UINT32)source.length() * sizeof(WString::value_type));
		md5.finalize();

		UINT8 digest[16];
		md5.decdigest(digest, sizeof(digest));

		char buf[33];
		for (int i = 0; i < 16; i++)
			sprintf(buf + i * 2, "%02x", digest[i]);
		buf[32] = 0;
		
		return String(buf);
	}
Ejemplo n.º 5
0
//
// Split into parts
//
void WString::Split ( const WString& strDelim, std::vector < WString >& outResult, unsigned int uiMaxAmount, unsigned int uiMinAmount ) const
{
    outResult.clear ();
    unsigned long ulStartPoint = 0;

    while ( true )
    {
        size_t ulPos = find ( strDelim, ulStartPoint );

        if ( ulPos == npos || ( uiMaxAmount > 0 && uiMaxAmount <= outResult.size () + 1 ) )
        {
            if ( ulStartPoint <= length () )
                outResult.push_back ( substr ( ulStartPoint ) );
            break;
        }

        outResult.push_back ( substr ( ulStartPoint, ulPos - ulStartPoint ) );

        ulStartPoint = ulPos + strDelim.length ();
    }

    while ( outResult.size () < uiMinAmount )
        outResult.push_back ( L"" );        
}
Ejemplo n.º 6
0
	//-----------------------------------------------------------------------
	void UnicodeFileSystemArchive::FileFinder::_run(const String& _dir, const WString& _wFullDir)
	{
		wchar_t wFindPattern[MAX_PATH];
		wcscpy(wFindPattern, _wFullDir.c_str());
		wcscpy(&wFindPattern[_wFullDir.length()], L"*");
       
        long lHandle;
		struct _wfinddata_t wTagData;
        lHandle = _wfindfirst(wFindPattern, &wTagData);

		String  tagDataName;
		String  dir2;
		WString wFullDir2;

		while(lHandle != -1)
		{
			bool isSubDir = ((wTagData.attrib & _A_SUBDIR) != 0);
			bool isHidden = ((wTagData.attrib & _A_HIDDEN) != 0);
			if((!mIgnoreHidden || !isHidden)
				&& !isReservedDir(wTagData.name)
				&& ((isSubDir == mDirs) || (isSubDir && mRecursive)))
			{
				tagDataName = mArchive->toString(wTagData.name);

				if(isSubDir == mDirs
					&& (mMask.empty() || StrUtil::match(tagDataName, mMask)))
				{
					if (mSimpleList)
					{
						mSimpleList->push_back(String());
						String& back = mSimpleList->back();
						back = _dir;
						back += tagDataName;
					}
					else if (mDetailList)
					{
						FileInfo fi;
						fi.archive = mArchive;
						fi.filename = _dir;
						fi.filename += tagDataName;
						fi.basename = tagDataName;
						fi.path = _dir;
						fi.compressedSize = wTagData.size;
						fi.uncompressedSize = wTagData.size;
						mDetailList->push_back(fi);
					}
				}

				if(isSubDir && mRecursive)
				{
					dir2 = _dir;
					dir2 += tagDataName;
					dir2 += '/';
					
					wFullDir2 = _wFullDir;
					wFullDir2 += wTagData.name;
					wFullDir2 += '/';
					
					_run(dir2, wFullDir2);
				}
			}
			
			if(_wfindnext( lHandle, &wTagData ) == -1)
			{
				_findclose(lHandle);
				lHandle = -1;
			}
        }
    }
Ejemplo n.º 7
0
bool WString::BeginsWithI ( const WString& strOther ) const
{
    return _wcsicmp ( Left ( (int)strOther.length () ), strOther ) == 0;
}
Ejemplo n.º 8
0
bool WString::BeginsWith ( const WString& strOther ) const
{
    return Left ( (int)strOther.length () ) == strOther;
}
Ejemplo n.º 9
0
bool WString::EndsWithI ( const WString& strOther ) const
{
    return _wcsicmp ( Right ( (int)strOther.length () ), strOther ) == 0;
}
Ejemplo n.º 10
0
bool WString::EndsWith ( const WString& strOther ) const
{
    return Right ( (int)strOther.length () ) == strOther;
}
Ejemplo n.º 11
0
//
// Split in two
//
// eg  "a.b.c.d.e" with strDelim == "." and iIndex == 1  gives "a" and "b.c.d.e"
//     "a.b.c.d.e" with strDelim == "." and iIndex == -2 gives "a.b.c" and "d.e"
//
bool WString::Split ( const WString& strDelim, WString* pstrLeft, WString* pstrRight, int iIndex ) const
{
    // Check for self-overwrite
    if ( this == pstrLeft || this == pstrRight )
        return WString ( *this ).Split ( strDelim, pstrLeft, pstrRight, iIndex );

    assert ( iIndex );
    bool bFromEnd = iIndex < 0;
    size_t ulPos;
    if ( !bFromEnd )
    {
        ulPos = 0;
        for ( int i = 0 ; i < iIndex && ulPos != npos ; i++ )
        {
            if ( i )
                ulPos += strDelim.length ();
            if ( ulPos < length () )
            {
                ulPos = find ( strDelim, ulPos );
            }
            else
            {
                ulPos = npos;
                break;
            }
        }
    }
    else
    {
        ulPos = length ();
        for ( int i = 0 ; i < -iIndex && ulPos != npos ; i++ )
        {
            if ( ulPos >= strDelim.length () )
            {
                ulPos -= strDelim.length ();
                ulPos = rfind ( strDelim, ulPos );
            }
            else
            {
                ulPos = npos;
                break;
            }
        }
    }

    if ( ulPos == npos )
    {
        if ( pstrLeft )
            *pstrLeft = bFromEnd ? L"" : c_str ();
        if ( pstrRight )
            *pstrRight = bFromEnd ? c_str () : L"";
        return false;
    }

    if ( pstrLeft )
        *pstrLeft = substr ( 0, ulPos );

    if ( pstrRight )
        *pstrRight = substr ( ulPos + strDelim.length (), length () - ( ulPos + strDelim.length () ) );
 
    return true;
}
Ejemplo n.º 12
0
int HttpConnection::request(InputStream& data, OutputStream& response, bool log_request)
{
    int readBytes = 0; 
    int totalBytesRead = 0;
    DWORD bytesWritten = 0;
    int ret = HTTP_STATUS_OK;
    WString headers;
    bool sendDataAtOnce = false;
    char *chunkToSend = NULL;
    int64_t contentLen = 0; 
    INTERNET_BUFFERS BufferIn = {0};
    DWORD errorCode = 0;
    char tmpbuff[1024];

#ifdef USE_ZLIB
    Bytef* cBuf = NULL;
    uLong  cBufLen  = 0;
    int64_t uncompressedContentLen = 0;
#endif
    
    // Timeout to receive a rensponse from server (default = 30 sec).
    DWORD reqTimeoutMsec = requestTimeout * 1000;
    DWORD resTimeoutMsec = responseTimeout == 0 ? 30 * 1000 : responseTimeout * 1000;
    InternetSetOption(req, INTERNET_OPTION_RECEIVE_TIMEOUT, &reqTimeoutMsec, sizeof(DWORD));
    InternetSetOption(req, INTERNET_OPTION_SEND_TIMEOUT,    &resTimeoutMsec, sizeof(DWORD));
    // InternetSetOption(req, SECURITY_FLAG_IGNORE_REVOCATION, NULL, 0);
    
    if (auth) {
        if (auth->getType() == HttpAuthentication::Basic) {
           StringBuffer authCred = auth->getAuthenticationHeaders();
           StringBuffer authHeader;
           authHeader.sprintf("Basic %s", authCred.c_str());

           setRequestHeader(HTTP_HEADER_AUTHORIZATION, authHeader);
        } else {
            LOG.error("%s: authentication type not supported [%d]", __FUNCTION__, auth->getType());
            return StatusInternalError;
        }
    }

    // For user agent, content length and accept encoding, override property
    // values, even if set by the caller.
    setRequestHeader(HTTP_HEADER_USER_AGENT, userAgent);
    
    contentLen = data.getTotalSize() - data.getPosition();

#ifdef USE_ZLIB
    if (compression_enabled) {
        chunkToSend = new char [contentLen];   

        if (data.read((void *)chunkToSend, contentLen) != contentLen) {
            LOG.error("error reading data from input stream");  
            delete [] chunkToSend;
            return StatusInternalError;
        }

        sendDataAtOnce = true;

        cBufLen = contentLen;

        // DEFLATE (compress data)
        cBuf =  new Bytef[contentLen];
 
        // compress the source buffer into the destination buffer.
        int err = compress(cBuf, &cBufLen, (Bytef*)chunkToSend, contentLen);

        if (err != Z_OK) {
            LOG.error("%s: error compressing data buffer [%d]", __FUNCTION__, err);

            setError(ERR_HTTP_DEFLATE, "ZLIB: error occurred compressing data.");
            delete [] chunkToSend;
            delete [] cBuf;

            return StatusInternalError;
        }
        
        uncompressedContentLen = contentLen;
        contentLen = cBufLen;

       
        sprintf(tmpbuff, "%llu", contentLen); 
        setRequestHeader(HTTP_HEADER_CONTENT_LENGTH, tmpbuff);
        setRequestHeader(HTTP_HEADER_ACCEPT_ENCODING, "deflate");
        setRequestHeader(HTTP_HEADER_CONTENT_ENCODING, "deflate");

        sprintf(tmpbuff, "%llu", uncompressedContentLen); 
        setRequestHeader(HTTP_HEADER_UNCOMPRESSED_CONTENT_LENGTH, tmpbuff);
    } else {
        sprintf(tmpbuff, "%llu", contentLen); 
        setRequestHeader(HTTP_HEADER_CONTENT_LENGTH, tmpbuff);
    }
#else
    sprintf(tmpbuff, "%llu", contentLen); 
    setRequestHeader(HTTP_HEADER_CONTENT_LENGTH, tmpbuff);
#endif

    writeHttpHeaders(headers);

    // header in the log are written in writeHttpHeaders function
    // LOG.debug("Request header:\n\n%ls", headers.c_str());

    // if the client allows to sync over https even if the server
    // has an invalid certificate, the flag is false. By default it is true
    //if (getSSLVerifyServer() == false) {
    /*DWORD extraSSLDwFlags = 0;
	DWORD dwBuffLen = sizeof(extraSSLDwFlags);
    extraSSLDwFlags |= SECURITY_FLAG_IGNORE_REVOCATION | SECURITY_FLAG_IGNORE_WRONG_USAGE 
                    | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;

 	InternetSetOption (req, INTERNET_OPTION_SECURITY_FLAGS,
                         &extraSSLDwFlags, sizeof (extraSSLDwFlags) );
*/
    if (url.isSecure()) {
        DWORD dwFlags, dwBuffLen = sizeof(dwFlags);
        InternetQueryOption (req, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &dwBuffLen);    
        if (getSSLVerifyServer() == false) {            
            dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_REVOCATION | SECURITY_FLAG_IGNORE_WRONG_USAGE 
                    | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
            
        } else {
             dwFlags = dwFlags| INTERNET_FLAG_SECURE;
        }
        InternetSetOption (req, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));     
    }
     
    bool retry = false;

    // give a chance to submit again if error is ERROR_INTERNET_SEC_CERT_REV_FAILED
    bool retryFlagRevocation = true;

    BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
    BufferIn.Next = NULL;
    BufferIn.lpcszHeader = headers.c_str();
    BufferIn.dwHeadersLength = headers.length(); 
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = 0; //contentLen;
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0;

    do {
        retry = false;
        if (!HttpSendRequestEx(req, &BufferIn, NULL, HSR_INITIATE, 0)) {
            DWORD err = GetLastError();
            if (err == ERROR_INTERNET_SEC_CERT_REV_FAILED && retryFlagRevocation) {
                LOG.info("%s: error ERROR_INTERNET_SEC_CERT_REV_FAILED: retry once a time", __FUNCTION__);
                DWORD dwFlags, dwBuffLen = sizeof(dwFlags);
                InternetQueryOption (req, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &dwBuffLen);    
                dwFlags |= SECURITY_FLAG_IGNORE_REVOCATION;
                InternetSetOption (req, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));    
                retryFlagRevocation = false;
                retry = true;
                continue;
            }
                
            const char* msg = createHttpErrorMessage(err);
            LOG.error("HttpSendRequestEx failed: code %d: %s", err, msg);
            delete [] msg;
            return StatusNetworkError;
        }

#ifdef USE_ZLIB
        if (compression_enabled) {        
            if (sendData((const char *)cBuf, cBufLen) != 0) {
                delete [] cBuf;
                delete [] chunkToSend;

                return StatusWritingError;
            }

            delete [] cBuf;
        }
#endif

        if (!sendDataAtOnce) {
            int64_t bufferSize = std::min(requestChunkSize, contentLen);
            chunkToSend = new char[bufferSize+1];   

            while ((readBytes = data.read((void *)chunkToSend, bufferSize))) {
                if (sendData(chunkToSend, readBytes) != 0) {
                    delete [] chunkToSend;
                    return StatusWritingError;
                }
                fireTransportEvent(readBytes, DATA_SENT);
            }
        }

        delete [] chunkToSend;
	
	    if (data.error()) {
		    LOG.error("[%s] Input stream read error: %d on %d bytes read", __FUNCTION__, data.getPosition(), data.getTotalSize());
		    return StatusStreamReadingError;
	    }

        if (!HttpEndRequest(req, NULL, 0, 0)) {
            DWORD err = GetLastError();
            const char* msg = createHttpErrorMessage(err);
            LOG.error("HttpEndRequest failed: code %d: %s", err, msg);
            delete [] msg;
            return StatusNetworkError;
        }

        readResponseHeaders();

        ret = checkResponseStatus(); 
        if (ret == ERROR_INTERNET_FORCE_RETRY) {
            retry = true;
        }

    } while (retry == true);

    if (isErrorStatus(ret)) {      
        return ret;
    }
   
    StringBuffer nullval(NULL);
    if ((getRequestHeaders().get(HTTP_HEADER_RANGE) != nullval) && ret == 200) {
        // it means the client asks a partial response but the server doesn't support it.
        // the right answer from server is HTTP 206
        LOG.info("%s: client asks a Range, but server responds 200 instead of 206 (Partial Content). Reset the outputstream and start from scratch.", __FUNCTION__);
        response.reset();
    }

    if (readResponse(response) != 0) {
        return StatusReadingError;
    }

    return ret;
}