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

📄 url.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Copyright (C) 2001-2005 Open Source Telecom Corporation.//// 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.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#ifdef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/file.h>#include <cc++/thread.h>#include <cc++/exception.h>#include <cc++/address.h>#include <cc++/socket.h>#ifndef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/url.h>#include <string>#include <cstdio>#include <cstdlib>#include <fcntl.h>#include <cerrno>#include <iostream>#ifdef	WIN32#include <io.h>#endif#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endif#include <cctype>#ifndef WIN32// cause problem on Solaris#if !defined(__sun) && !defined(__SUN__)#ifdef	HAVE_NET_IF_H#include <net/if.h>#endif#endif#include <sys/ioctl.h>#endif#ifdef	CCXX_NAMESPACESnamespace ost {using namespace std;#endifURLStream::URLStream(Family fam, timeout_t to) :TCPStream(fam){	persistent = false;	proxyPort = 0;	timeout = to;	protocol = protocolHttp1_0;	follow = true;	proxyAuth = authAnonymous;	encoding = encodingBinary; 	proxyUser = proxyPasswd = NULL;	auth = authAnonymous;	cookie = agent = pragma = referer = user = password = NULL;	localif = NULL;	setError(false);}int URLStream::aRead(char *buffer, size_t len, timeout_t timer){#ifndef __MINGW32__	return ::read((int)so, buffer, _IOLEN64 len);#else        return ::recv(so, buffer, _IOLEN64 len, 0);#endif}int URLStream::aWrite(char *buffer, size_t len, timeout_t timer){#ifndef __MINGW32__	return ::write((int)so, buffer, _IOLEN64 len);#else        return ::send((int)so, buffer, _IOLEN64 len, 0);#endif}void URLStream::httpHeader(const char *header, const char *value){}char **URLStream::extraHeader(void){	return NULL;}int URLStream::underflow(void){	ssize_t len, rlen;	char *buf;	if(bufsize == 1)		return TCPStream::underflow();	if(!gptr())		return EOF;	if(gptr() < egptr())		return (unsigned char)*gptr();	rlen = (ssize_t)((gbuf + bufsize) - eback());	if(encoding == encodingChunked)	{		buf = (char *)eback();		*buf = '\n';		while(!chunk && (*buf == '\n' || *buf == '\r'))		{			*buf = 0;			len = readLine(buf, rlen, timeout);		}		if(len)		{			if(!chunk)				chunk = strtol(buf, NULL, 16);			if(rlen > (int)chunk)				rlen = chunk;		}		else			rlen = -1;	}	if(rlen > 0)	{		if(Socket::state == STREAM)			rlen = aRead((char *)eback(), rlen, timeout);		else if(timeout)		{			if(Socket::isPending(pendingInput, timeout))				rlen = ::recv(so, (char *)eback(), rlen, 0);			else				rlen = -1;		}		else			rlen = ::recv(so, (char *)eback(), rlen, 0);	}	if(encoding == encodingChunked && rlen > 0)		chunk -= rlen;	if(rlen < 1)	{		if(rlen < 0)			clear(ios::failbit | rdstate());		return EOF;	}	setg(eback(), eback(), eback() + rlen);	return (unsigned char)*gptr();}	void URLStream::setProxy(const char *host, tpport_t port){	switch(family)	{#ifdef	CCXX_IPV6	case IPV6:		v6proxyHost = host;		break;#endif	case IPV4:		proxyHost = host;	}	proxyPort = port;}URLStream::Error URLStream::submit(const char *path, const char **vars, size_t buf){	Error status = errInvalid, saved;	if(!strnicmp(path, "http:", 5))	{		urlmethod = methodHttpGet;		path = strchr(path + 5, '/');		status = sendHTTPHeader(path, vars, buf);	}	if((status == errInvalid || status == errTimeout))	{		if(Socket::state != AVAILABLE)			close();		return status;	}	else	{		saved = status;		status = getHTTPHeaders();		if(status == errSuccess)			return saved;		else if(status == errTimeout)		{			if(Socket::state != AVAILABLE)				close();		}		return status;	}}URLStream::Error URLStream::post(const char *path, MIMEMultipartForm &form, size_t buf){	Error status = errInvalid, saved;	if(!strnicmp(path, "http:", 5))	{		urlmethod = methodHttpPostMultipart;		path = strchr(path + 5, '/');		status = sendHTTPHeader(path, (const char **)form.getHeaders(), buf);	}	if(status == errInvalid || status == errTimeout)	{		if(Socket::state != AVAILABLE)			close();		return status;	}	saved = status;	status = getHTTPHeaders();	if(status == errSuccess)	{		form.body(dynamic_cast<std::ostream *>(this));		return saved;	}	if(status == errTimeout)	{		if(Socket::state != AVAILABLE)			close();	}	return status;}URLStream::Error URLStream::post(const char *path, const char **vars, size_t buf){	Error status = errInvalid, saved;	if(!strnicmp(path, "http:", 5))	{		urlmethod = methodHttpPost;		path = strchr(path + 5, '/');		status = sendHTTPHeader(path, vars, buf);	}	if((status == errInvalid || status == errTimeout))	{		if(Socket::state != AVAILABLE)			close();		return status;	}	saved = status;	status = getHTTPHeaders();	if(status == errSuccess)		return saved;	if(status == errTimeout)	{		if(Socket::state != AVAILABLE)			close();	}	return status;}URLStream::Error URLStream::head(const char *path, size_t buf){	Error status = errInvalid, saved;	if(!strnicmp(path, "http:", 5))	{		urlmethod = methodHttpGet;		path = strchr(path + 5, '/');		status = sendHTTPHeader(path, NULL, buf);	}	if((status == errInvalid || status == errTimeout))	{		if(Socket::state != AVAILABLE)			close();		return status;	}	else	{		saved = status;		status = getHTTPHeaders();		if(status == errSuccess)			return saved;		else if(status == errTimeout)		{			if(Socket::state != AVAILABLE)				close();		}		return status;	}}URLStream &URLStream::getline(char *buffer, size_t size){	size_t len;	*buffer = 0;	// TODO: check, we mix use of streambuf with Socket::readLine...	iostream::getline(buffer, (unsigned long)size);	len = strlen(buffer);		while(len)	{		if(buffer[len - 1] == '\r' || buffer[len - 1] == '\n')			buffer[len - 1] = 0;		else			break;		--len;	}	return *this;}URLStream::Error URLStream::get(size_t buffer){	String path = String("http://") + m_host;	if ( m_address.operator[](0) != '/' )		path += "/";	path += m_address;	return get(path.c_str(), buffer);}URLStream::Error URLStream::get(const char *urlpath, size_t buf){	const char *path = urlpath;	Error status = errInvalid, saved;	urlmethod = methodFileGet;	if(Socket::state != AVAILABLE)		close();		if(!strnicmp(path, "file:", 5))	{		urlmethod = methodFileGet;		path += 5;	}	else if(!strnicmp(path, "http:", 5))	{		urlmethod = methodHttpGet;		path = strchr(path + 5, '/');	}	switch(urlmethod)	{	case methodHttpGet:		status = sendHTTPHeader(path, NULL, buf);		break;	case methodFileGet:		if(so != INVALID_SOCKET)			::close((int)so);		so = ::open(path, O_RDWR);		if(so == INVALID_SOCKET)			so = ::open(path, O_RDONLY);                // FIXME: open return the same handle type as socket call ??		if(so == INVALID_SOCKET)			return errInvalid;		Socket::state = STREAM;		allocate(buf);		return errSuccess;	case methodHttpPut:	case methodHttpPost:	case methodHttpPostMultipart:	case methodFtpGet:	case methodFtpPut:	case methodFilePut:    	        break;	}	if((status == errInvalid || status == errTimeout))	{		if(Socket::state != AVAILABLE)			close();		return status;	}	else	{		saved = status;		status = getHTTPHeaders();		if(status == errSuccess)			return saved;		else if(status == errTimeout)		{			if(Socket::state != AVAILABLE)				close();		}		return status;	}}URLStream::Error URLStream::getHTTPHeaders(){	char buffer[512];	size_t buf = sizeof(buffer);	Error status = errSuccess;	char *cp, *ep;	ssize_t len = 1;	char nc = 0;	chunk = ((unsigned)-1) / 2;	encoding = encodingBinary;	while(len > 0)	{		len = readLine(buffer, buf, timeout);		if(len < 1)			return errTimeout;				// FIXME: for multiline syntax ??		if(buffer[0] == ' ' || buffer[0] == '\r' || buffer[0] == '\n')			break;		cp = strchr(buffer, ':');		if(!cp)			continue;		*(cp++) = 0;		while(*cp == ' ' || *cp == '\t')			++cp;		ep = strchr(cp, '\n');		if(!ep)			ep = &nc;		while(*ep == '\n' || *ep == '\r' || *ep == ' ')		{			*ep = 0;			if((--ep) < cp)				break;

⌨️ 快捷键说明

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