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

📄 httpcli.cpp

📁 dget是一个基于Linux平台的多线程下载工具, 采用C++开发。主要支持FTP, HTTP, MMS, RTSP协议下载, 目前为止主要实现了FTP, HTTP, MMS,RTSP协议的多线程下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * by balancesli * balancesli@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <ctype.h>#include <netdb.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/time.h>#include <pthread.h>#include <assert.h>#include <linux/ip.h>#include "Utils.h"#include "HttpCli.h"#include "Task.h"#include "dget.h"#include "Utils.h"THttpCli :: THttpCli(TUrl * url) : Sckp(NULL){	up = url;}	THttpCli :: ~THttpCli(void){	if(Sckp != NULL) delete Sckp;}uerr_t THttpCli :: Connect(void){	uerr_t err;	if(Sckp == NULL)		Sckp = new TSocketCli(up->HostName);	err = Sckp->Connect(80);	if(err != NOCONERROR)		return err;	else		return HOK;}	uerr_t THttpCli :: Disconnect(void){	int Sock; 	Sock = Sckp->GetSockfd();	close(Sock);}int THttpCli :: BufReadChar(int fd, char *ret){    int retval = Recv(fd, ret, 1, 0);	    if (retval <= 0)		return retval;    return 1;}int THttpCli :: BufPeek(int fd, char *ret){    int retval = Recv(fd, ret, 1, MSG_PEEK);	    if (retval <= 0)		return retval;    return 1;}uerr_t THttpCli :: FetchNextHeader(int fd, char **hdr){    int i, BufSize, retval;    char Next;    BufSize = DYNAMIC_LINE_BUFFER;    *hdr = new char[DYNAMIC_LINE_BUFFER];    	for (i = 0; 1; i++)    {		if (i > BufSize - 1)		{			char * t = new char[BufSize <<= 1];			strcpy(t, *hdr);			delete []*hdr;			*hdr = t;					}		retval = BufReadChar(fd, *hdr + i);		if (retval == 1)		{	    	if ((*hdr)[i] == '\n')	    	{				if (!(i == 0 || (i == 1 && (*hdr)[0] == '\r')))				{		    		retval = BufPeek(fd, &Next);		    		if (retval == 0)						return HEOF;		    		else if 						(retval == -1)					return HERR;		    		if (Next == '\t' || Next == ' ')						continue;				}		 						(*hdr)[i] = '\0';		 						if (i > 0 && (*hdr)[i - 1] == '\r')		    		(*hdr)[i - 1] = '\0';				break;	    	}		} 		else if (retval == 0)	    	return HEOF;		else	    	return HERR;    }    return HOK;}int THttpCli :: ParseStatLine(const char *hdr, const char **rp){    int Major, Minor;    int StatusCode;	    const char *p;    *rp = NULL;    	if(strncmp(hdr, "HTTP/", 5) != 0)		return -1;	hdr += 5;    p = hdr;	    for (Major = 0; isdigit(*hdr); hdr++)		Major = 10 * Major + (*hdr - '0');    	if (*hdr != '.' || p == hdr)		return -1;    	++hdr;    p = hdr;    	for (Minor = 0; isdigit(*hdr); hdr++)		Minor = 10 * Minor + (*hdr - '0');	    if (*hdr != ' ' || p == hdr)		return -1;    	if (Major < 1)		return -1;    	++hdr;    	if (!(isdigit(*hdr) && isdigit(hdr[1]) && isdigit(hdr[2])))		return -1;    	StatusCode = 100 * (*hdr - '0') + 10 * (hdr[1] - '0') + (hdr[2] - '0');    	if (hdr[3] != ' ')    {		if (!hdr[3])	    	*rp = hdr + 3;		else	    	return -1;    } 	else		*rp = hdr + 4;	    return StatusCode;}int THttpCli :: SkipLws(const char *hdr){    int i;    for (i = 0; *hdr == ' ' || *hdr == '\t' || *hdr == '\r' || *hdr == '\n'; ++hdr)		++i;    return i;}long THttpCli :: GetLen(const char *hdr){    const int l = 15; //strlen("content-length:")     long Len;    if (strncasecmp(hdr, "content-length:", l))		return -1;    	hdr += (l + SkipLws(hdr + l));    	if (!*hdr)		return -1;    	if (!isdigit(*hdr))		return -1;    	for (Len = 0; isdigit(*hdr); hdr++)		Len = 10 * Len + (*hdr - '0');	return Len;}long THttpCli :: GetRange(const char *hdr){    const int l = 14; //strlen("content-range:")     long Len;    if(strncasecmp(hdr, "content-range:", l))		return -1;    	hdr += (l + SkipLws(hdr + l));    	if(!*hdr)		return -1;    	if(!strncasecmp(hdr, "bytes", 5))    {		hdr += 5;		hdr += SkipLws(hdr);		if (!*hdr)	    	return -1;    }    	if(!isdigit(*hdr))		return -1;    	for(Len = 0; isdigit(*hdr); hdr++)		Len = 10 * Len + (*hdr - '0');	return Len;}char * THttpCli :: GetLocation(const char *hdr){    static const int l = 9;	// strlen("location:")     if (strncasecmp(hdr, "location:", l))		return NULL;    	hdr += (l + SkipLws(hdr + l));    	return strdup(hdr);}char * THttpCli :: GetModified(const char *hdr){    const int l = 14; //strlen("last-modified:")     if (strncasecmp(hdr, "last-modified:", l))		return NULL;    	hdr += (l + SkipLws(hdr + l));    	return strdup(hdr);}int THttpCli :: GetAcceptRanges(const char *hdr){    const int l = 14;	//strlen("accept-ranges:")     if (strncasecmp(hdr, "accept-ranges:", l))		return -1;    	hdr += (l + SkipLws(hdr + l));    	if (strstr(hdr, "none"))		return 0;    else		return 1;}uerr_t THttpCli :: GetHttpInfo(TUrl * up, HttpStat * hs){    uerr_t err;    int Sock;    char Buffer[HTTP_BUF_SIZE];	int Len;	char * Path;		Len = strlen(up->HostDirName) + strlen(up->HostFileName) + 2;	Path = new char[Len];	sprintf(Path, "/%s/%s",up->HostDirName, up->HostFileName);	//	ShowMsg("%s\n", Path);				    err = Connect();	if(err != HOK)    {		ShowMsg("Error connecting to %s", up->HostName);		return err;    }	Sock = Sckp->GetSockfd();	/* We will get http info about the file by calling http_fetch_headers */	/* with HEAD */	const char * www_auth = GetAuthStr(up->UserName, up->PassWord, "Authorization");	www_auth = www_auth ? www_auth : "" ;//  sprintf(Buffer, //	"HEAD %s HTTP/1.0\r\nUser-Agent: %s%s\r\nHost:%s\r\nAccept: */*\r\n\r\n", //		Path, SOFTWARE_NAME, SOFTWARE_VERSION, up->HostName);   sprintf(Buffer, 		"HEAD %s HTTP/1.0\r\nUser-Agent:%s%s\r\nHost:%s\r\nAccept:*/*\r\n%s\r\n%s\r\n", 		Path, SOFTWARE_NAME, SOFTWARE_VERSION, 		up->HostName, www_auth);      err = FetchHeaders(Sock, up, hs, Buffer);	    close(Sock);		delete []Path;    return err;}/* function to fetch the http headers from the socket *//* to a specific command string */uerr_t THttpCli :: FetchHeaders(int Sock, TUrl * up, HttpStat * hs, char * Cmd){    uerr_t err;    int BytesWritten, Count, StatusCode;	char *hdr, *Type, *AllHdr;    long ContentLen, ContentRange;	int AllLength;    const char *error;    hs->Len = 0L;    hs->ContentLen = -1;    hs->AcceptRanges = -1;    hs->Result = -1;    hs->NewLoc = NULL;    hs->RemoteTime = NULL;    hs->Error = NULL;    /*     * send the command to the server      */    BytesWritten = Send(Sock, Cmd, strlen(Cmd), 0);	    if (BytesWritten != strlen(Cmd))    {		ShowMsg("Failed writing HTTP request");		return WRITEERR;    }    AllLength = 0;    ContentLen = ContentRange = -1;    StatusCode = -1;	AllHdr = NULL;	Type = NULL;	    /*     * Header-fetching loop.      */    Count = 0;    for ( ; ; )    {		++Count;		//Get the header. 		err = FetchNextHeader(Sock, &hdr);		if (err == HEOF)		{	    	ShowMsg("End of file while parsing headers");	    	delete [] hdr;			if(Type) delete []Type;			if(AllHdr) delete []AllHdr;				    	return HEOF;		}		else if (err == HERR)		{	    	ShowMsg("Read error in headers");			delete []hdr;						if(Type) delete []Type;			if(AllHdr) delete []AllHdr;	    	return HERR;		}				if (!*hdr)		{	    	delete []hdr;	    	break;		}		if (Count == 1)		{		    StatusCode = ParseStatLine(hdr, &error);		    hs->StatusCode = StatusCode;				   		//Store the descriptive response. 	   		if (StatusCode == -1) // malformed request 				hs->Error = strdup("UNKNOWN");	   		else if (!*error)				hs->Error = strdup("(no description)");	    	else				hs->Error = strdup(error);		}				if (ContentLen == -1)		{	    	ContentLen = GetLen(hdr);	    	hs->ContentLen = ContentLen;		}		if (!hs->NewLoc)	    	hs->NewLoc = GetLocation(hdr);		if (!hs->RemoteTime)	    	hs->RemoteTime = GetModified(hdr);		if (hs->AcceptRanges == -1)		{	   		hs->AcceptRanges = GetAcceptRanges(hdr);		}		if (!hs->NewLoc)	    	hs->NewLoc = GetLocation(hdr);		delete []hdr;    }    if (H_20X(StatusCode))		return HOK;

⌨️ 快捷键说明

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