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

📄 http.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

        buffer = (char*)malloc(bufferSize);

        result = kError_OutOfMemory;

        if(buffer)
        {
            Error err;
            result = kError_NoErr;

            do
            {
                if(total >= bufferSize - 1)
                {
                    bufferSize *= 2;

                    buffer = (char*) realloc(buffer, bufferSize);

                    if(!buffer)
                    {
                        result = kError_OutOfMemory;
                        break;
                    }
                }

                err = Recv(s, buffer + total, bufferSize - total - 1, 0, count);
                if (IsError(err))
                    result = kError_UserCancel;

                if(count > 0)
                    total += count;
                else
                {
                    result = kError_IOError;
                }

            }while(IsntError(result) && !IsHTTPHeaderComplete(buffer, total));
        }

        // parse header
        if(IsntError(result))
        {
            uint32 returnCode = atoi(buffer+9);
            buffer[total] = 0x00;
            //cout << buffer << endl;

            //cout << returnCode << endl;
            switch(buffer[9])
            {
                // 1xx: Informational - Request received, continuing process
                case '1':
                {
                    // not sure what to do here... continue receiving???
                }    

                // 2xx: Success - The action was successfully received,
                // understood, and accepted
                case '2':
                {
                    Error err;
                    result = kError_UnknownErr;

                    int32 fileSize = GetContentLengthFromHeader(buffer);


                    result = kError_NoErr;
                    int wcount = 0;

                    char* cp;

                    cp = strstr(buffer, "\r\n\r\n");
                    if(cp)
                        cp += 4;
                    if(cp)
                    {
                        if(cp - buffer < (int)total)
                        {
                            if (fileDownload)
                               wcount = WriteToFile((unsigned char *)cp,
                                                    total - (cp - buffer));
                            else
                               wcount = WriteToBuffer((unsigned char *)cp,
                                                      total - (cp-buffer));
                            bytesReceived = total - (cp - buffer);
                        }
                    }

                    do
                    {
                        if (min(bufferSize, fileSize - bytesReceived) != 0)
						{
							err = Recv(s, buffer,
									min(bufferSize, fileSize - bytesReceived),
									0, count);
						}
						else
							count = 0;
                        if (IsError(err))
                            result = kError_UserCancel;
                        else
                           if(count > 0)
                           {
                               if (fileDownload)
                                  wcount = WriteToFile((unsigned char *)buffer,
                                                       (unsigned int)count);
                               else
                                  wcount = WriteToBuffer((unsigned char *)buffer
,
                                                       (unsigned int)count);
                               bytesReceived += count;
                               Progress(bytesReceived, fileSize);
                           }

                        if(count < 0)
                            result = kError_IOError;

                        if(wcount < 0)
                            result = kError_WriteFile;

                    }while(count > 0 && IsntError(result) &&
                           !m_exit && wcount >= 0 &&
                           (int)bytesReceived != fileSize);

                break;   
                }

                // 3xx: Redirection - Further action must be taken in order to
                // complete the request
                case '3':
                {
                    char* cp = strstr(buffer, "Location:");
                    //int32 length;

                    if(cp)
                    {
                        cp += 9;

                        if(*cp == 0x20)
                            cp++;

                        char *end;
                        for(end = cp; end < buffer + total; end++)
                            if(*end=='\r' || *end == '\n') break;

                        *end = 0x00;

                        if (305 == returnCode) // proxy
                        {
                            char* proxy = new char[strlen(cp) + 
                                                   strlen(url.c_str()) + 1];

                            sprintf(proxy, "%s%s", cp, url.c_str());

                            result = Download(string(proxy), fileDownload);
                            delete [] proxy;
                        }
                        else // redirect of some type
                        {
                            result = Download(string(cp), fileDownload);
                        }
                    }
                    
                    break;
                }

                // 4xx: Client Error - The request contains bad syntax or cannot
                // be fulfilled
                case '4':
                {
                    switch(returnCode)
                    {
                        case 400:
                            result = kError_BadHTTPRequest;
                            break;

                        case 401:
                            result = kError_AccessNotAuthorized;
                            break;                           

                        case 403:
                            result = kError_DownloadDenied;
                            break;

                        case 404:
                            result = kError_HTTPFileNotFound;
                            break;

                        default:
                            result = kError_UnknownErr;
                            break;
                    }

                    break;
                }

                // 5xx: Server Error - The server failed to fulfill an apparently
                // valid request
                case '5':
                {
                    result = kError_UnknownServerError;
                    break;
                }
            }

        }

        // cleanup
        if(buffer)
            free(buffer);            
    }

    // cleanup
    if(s > 0)
        closesocket(s);

    return result;
}

Error Http::Connect(int hHandle, const sockaddr *pAddr, int &iRet)
{
    fd_set              sSet; 
    struct timeval      sTv;

#if defined(WIN32)
	unsigned long lMicrosoftSucksBalls = 1;
	ioctlsocket(hHandle, FIONBIO, &lMicrosoftSucksBalls);
#elif defined(__BEOS__)
//	int on = 1;
//	setsockopt( hHandle, SOL_SOCKET, SO_NONBLOCK, &on, sizeof( on ) );
#else
    fcntl(hHandle, F_SETFL, fcntl(hHandle, F_GETFL) | O_NONBLOCK);
#endif

    iRet = connect(hHandle, (const sockaddr *)pAddr,sizeof(*pAddr));
#ifndef WIN32
    if (iRet == -1 && errno != EINPROGRESS)
       return kError_NoErr;
#endif  
    for(; iRet && !m_exit;)
    {
        sTv.tv_sec = 0; sTv.tv_usec = 0;
        FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
        iRet = select(hHandle + 1, NULL, &sSet, NULL, &sTv);
        if (!iRet)
        {
           usleep(100000);
           continue;
        }

        if (iRet < 0)
           return kError_NoErr;
           
        break;
    }
    
    if (m_exit)
       return kError_Interrupt;
       
    return kError_NoErr;
}

Error Http::Recv(int hHandle, char *pBuffer, int iSize, 
                 int iFlags, int &iRead)
{
    fd_set              sSet; 
    struct timeval      sTv;
    int                 iRet;

    iRead = 0;
    for(; !m_exit;)
    {
        sTv.tv_sec = 0; sTv.tv_usec = 0;
        FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
        iRet = select(hHandle + 1, &sSet, NULL, NULL, &sTv);
        if (!iRet)
        {
           usleep(10000);
           continue;
        }
        iRead = recv(hHandle, pBuffer, iSize, iFlags);
        if (iRead < 0)
        {
           return kError_NoErr;
        }
        break;
    }

    if (m_exit)
       return kError_Interrupt;
       
    return kError_NoErr;
}                            

Error Http::Send(int hHandle, char *pBuffer, int iSize, 
                 int iFlags, int &iRead)
{
    fd_set              sSet; 
    struct timeval      sTv;
    int                 iRet;

    iRead = 0;
    for(; !m_exit;)
    {
        sTv.tv_sec = 0; sTv.tv_usec = 0;
        FD_ZERO(&sSet); FD_SET(hHandle, &sSet);
        iRet = select(hHandle + 1, NULL, &sSet, NULL, &sTv);
        if (!iRet)
        {
		   usleep(10000);
           continue;
        }
        iRead = send(hHandle, pBuffer, iSize, iFlags);
        if (iRead < 0)
        {
           return kError_NoErr;
        }
        break;
    }

    if (m_exit)
       return kError_Interrupt;
       
    return kError_NoErr;
}                            

void Http::Progress(unsigned int bytesReceived, unsigned int maxBytes)
{

}

bool Http::IsHTTPHeaderComplete(char* buffer, uint32 length)
{
    bool result = false;

    for(char* cp = buffer; cp < buffer + length; cp++)
    {
        if(!strncmp(cp, "\n\n", 2) || !strncmp(cp, "\r\n\r\n", 4))
        {
            result = true;
            break;
        }
    }

    return result;
}

int32 Http::GetContentLengthFromHeader(const char* buffer)
{
    int32 result = -1;

    char* cp = strstr(buffer, "Content-Length:");

    if(cp)
    {
        cp += strlen("Content-Length:") + 1;

        result = atoi(cp);
    }

    return result;
} 

⌨️ 快捷键说明

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