📄 httpcli.cpp
字号:
if (H_REDIRECTED(StatusCode) || StatusCode == HTTP_MULTIPLE_CHOICES) { if (StatusCode == HTTP_MULTIPLE_CHOICES && !hs->NewLoc) return HOK; else { if(Type) delete []Type; if(AllHdr) delete []AllHdr; return NEWLOCATION; } } return HERR;}uerr_t THttpCli :: RedirectionParse(TUrl * up, HttpStat * hsp){ uerr_t err; int i; err = GetHttpInfo(up, hsp); if(err == NEWLOCATION) { for(i = 0; i < MAXREDIRECTIONS; i++) { ShowMsg("%s", hsp->NewLoc); delete up; up = new TUrl(hsp->NewLoc); up->ParseUrl();// up->DispUrl(); err = GetHttpInfo(up, hsp); if(err == HOK) break; else if(err == NEWLOCATION) { if(i == MAXREDIRECTIONS) Panic("Parse Url Error"); } else { switch (err) { case HOSTERR: Panic("failed to resolve"); break; case CONREFUSED: Panic("Rejected the Connection Attempt"); break; case CONERROR: if (errno == ETIMEDOUT) Panic("The connection Attempt to timed out"); else Panic("Error while attempting to connect to Server"); break; default: Panic("A error occured while trying to get info from Server"); break; } } } } up->FileSize = hsp->ContentLen; if((up->FileSize == -1) || (hsp->AcceptRanges == -1) || (hsp->AcceptRanges == 0)) up->ResumeSupport = false; else up->ResumeSupport = true; return err;}uerr_t THttpCli :: RetrFileKnownSize(TThread * This){ long Total = 0, BytesRead = 0, Length; char szBuffer[HTTP_BUF_SIZE]; FILE * fp = NULL; int Tos = IPTOS_THROUGHPUT; float Per; int Sock = Sckp->GetSockfd(); Length = This->RemoteEndPos - This->RemoteStartPos; if (!(fp = fopen(This->LocalFile, This->FileMode))) { ShowMsg("Error opening file %s for writing: %s", This->LocalFile, strerror(errno)); close(Sock); This->Status = LOCALFATAL; return FOPENERR; } /* * prioritize packets */ setsockopt(Sock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos)); /* * Make sure all writes go directly to the file */ setvbuf(fp, NULL, _IONBF, 0); This->Status = DOWNLOADING; //gettimeofday(&This->BeginTime, NULL); while(Length > 0) { if(Length < HTTP_BUF_SIZE && Length > 0) { while(Length > 0) { // Cancelation-point pthread_testcancel(); BytesRead = Recv(Sock, szBuffer, HTTP_BUF_SIZE, 0); pthread_testcancel(); if(BytesRead == -1) { ShowMsg("Error receving data"); fclose(fp); Disconnect(); if (errno == ETIMEDOUT) { ShowMsg("connection timed out"); This->Status = TIMEDOUT; return HERR; } This->Status = REMOTEFATAL; return READERR; } if(BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp)) { ShowMsg("write failed"); fclose(fp); Disconnect(); This->Status = LOCALFATAL; return FWRITEERR; } Length -= BytesRead; Total += BytesRead; This->RemoteBytesReceived += BytesRead;#ifdef DEBUG Per = This->RemoteBytesReceived * 100 / This->BlkSize; ShowMsg("%s has finished %.1f%%", This->Name, Per); #endif } break; } // Cancelation-point pthread_testcancel(); BytesRead = Recv(Sock, szBuffer, HTTP_BUF_SIZE, 0); pthread_testcancel(); if(BytesRead == -1) { ShowMsg("Error receving data"); fclose(fp); Disconnect(); if (errno == ETIMEDOUT) { ShowMsg("connection timed out"); This->Status = TIMEDOUT; return HERR; } This->Status = REMOTEFATAL; return READERR; } if (BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp)) { ShowMsg("write failed"); fclose(fp); Disconnect(); This->Status = LOCALFATAL; return FWRITEERR; } Length -= BytesRead; Total += BytesRead; This->RemoteBytesReceived += BytesRead;#ifdef DEBUG Per = This->RemoteBytesReceived * 100 / This->BlkSize; ShowMsg("%s has finished %.1f%%", This->Name, Per); #endif } fclose(fp); This->Status = ALLDONE; Disconnect(); ShowMsg("download for this connection completed"); ShowMsg("%s : %ld received", This->LocalFile, Total); return HOK;}uerr_t THttpCli :: RetrFileUnknownSize(TThread * This){ long Total = 0, BytesRead = 0, Length; char szBuffer[HTTP_BUF_SIZE]; FILE * fp = NULL; int Tos = IPTOS_THROUGHPUT; int Sock = Sckp->GetSockfd(); if(!(fp = fopen(This->LocalFile, This->FileMode))) { ShowMsg("Error opening file %s for writing: %s", This->LocalFile, strerror(errno)); close(Sock); This->Status = LOCALFATAL; return FOPENERR; } /* * prioritize packets */ setsockopt(Sock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos)); /*Make sure all writes go directly to the file */ setvbuf(fp, NULL, _IONBF, 0); This->RemoteBytesReceived = 0; This->Status = DOWNLOADING; /* * lets store the start time in the TThreads structure */ //gettimeofday(&This->BeginTime, NULL); do { // Cancelation-point pthread_testcancel(); BytesRead = Recv(Sock, szBuffer, HTTP_BUF_SIZE, 0); pthread_testcancel(); if(BytesRead > 0) { if(fwrite(szBuffer, sizeof(char), BytesRead, fp) < BytesRead) { ShowMsg("Error writing to file %s : %s", This->LocalFile, strerror(errno)); fclose(fp); close(Sock); This->Status = LOCALFATAL; return FWRITEERR; } } This->RemoteBytesReceived += BytesRead; }while(BytesRead > 0); if(BytesRead == -1) { if(errno == ETIMEDOUT) { ShowMsg("TThread timed out"); This->Status = TIMEDOUT; return READERR; } This->Status = REMOTEFATAL; return READERR; } fclose(fp); This->Status = ALLDONE; close(Sock); return HOK;} uerr_t THttpCli :: GetFileChunk(TThread * This){ uerr_t err; HttpStat hs; int Sock; char Buffer[HTTP_BUF_SIZE]; FILE *fp = NULL; char * Path; int Len = strlen(This->u->HostDirName) + strlen(This->u->HostFileName) + 2; Path = new char[Len]; sprintf(Path, "/%s/%s",This->u->HostDirName, This->u->HostFileName); /* * set the thread attributes */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); hs.Len = 0L; hs.ContentLen = -1; hs.Result = -1; hs.NewLoc = NULL; hs.RemoteTime = NULL; hs.Error = NULL; /* * if there is nothing to download then return */ if (This->Status == ALLDONE) { gettimeofday(&This->BeginTime, NULL); return HOK; } /* * Lets test and see wether the file length to be got is zero * If so then there is no point in connecting.. * just create the file (zero length) and return * have to resort to a ugly method to detect this :( */ if (This->RemoteStartPos == 0 && This->RemoteEndPos < 0) { if (!(fp = fopen(This->LocalFile, This->FileMode))) { ShowMsg("Error opening file %s for writing: %s", This->LocalFile, strerror(errno)); This->Status = LOCALFATAL; return WRITEERR; } fclose(fp); This->Status = ALLDONE; return HOK; } This->Status = CONNECTING; err = Connect(); if (err != HOK) { ShowMsg("Error connecting to %s", This->u->HostName); This->Status = REMOTEFATAL; return err; } Sock = Sckp->GetSockfd(); /* * get the headers by sending GET */ sprintf(Buffer, "GET %s HTTP/1.0\r\nUser-Agent:%s%s\r\nHost:%s\r\nAccept: */*\r\nPragma: no-cache\r\nRange:bytes=%ld-%ld\r\n\r\n", Path, SOFTWARE_NAME, SOFTWARE_VERSION, This->u->HostName, This->RemoteStartPos, This->RemoteEndPos); err = FetchHeaders(Sock, This->u, &hs, Buffer); if (err != HOK) { close(Sock); This->Status = REMOTEFATAL; return err; } err = RetrFileKnownSize(This); delete []Path; return err;}uerr_t THttpCli :: GetCompleteFile(TThread * This){ uerr_t err; int Sock; char Buffer[HTTP_BUF_SIZE]; HttpStat hs; char * Path; int Len = strlen(This->u->HostDirName) + strlen(This->u->HostFileName) + 2; Path = new char[Len]; sprintf(Path, "/%s/%s",This->u->HostDirName, This->u->HostFileName); /* * set the thread attributes */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); hs.Len = 0L; hs.ContentLen = -1; hs.Result = -1; hs.NewLoc = NULL; hs.RemoteTime = NULL; hs.Error = NULL; /* * if there is nothing to download then return */ if(This->Status == ALLDONE) { gettimeofday(&This->BeginTime, NULL); return HOK; } This->Status = CONNECTING; err = Connect(); if(err != HOK) { ShowMsg("Error connecting to %s", This->u->HostName); This->Status = REMOTEFATAL; return err; } Sock = Sckp->GetSockfd(); /* * lets fetch the headers and since we want to retreive the file * we will use the GET command */ sprintf(Buffer, "GET %s HTTP/1.0\r\nUser-Agent: %s%s\r\nHost: %s\r\nAccept: */*\r\n\r\n", Path, SOFTWARE_NAME, SOFTWARE_VERSION, This->u->HostName); err = FetchHeaders(Sock, This->u, &hs, Buffer); if(err != HOK) { close(Sock); return err; } if(This->u->FileSize == -1) err = RetrFileUnknownSize(This); else err = RetrFileKnownSize(This); delete []Path; return err;}/*uerr_t THttpCli :: SearchMirrorSite(TThread * This){}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -