📄 http.cpp
字号:
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 + -