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

📄 spnkhttpcli.cpp

📁 linux 下的程序源代码
💻 CPP
字号:
/* * Copyright 2008 Stephen Liu * For license terms, see the file COPYING along with this library. */#include <string.h>#include <stdlib.h>#include <assert.h>#include <ctype.h>#include "spnkhttpcli.hpp"#include "spnkhttpmsg.hpp"#include "spnksocket.hpp"#include "spnklist.hpp"#include "spnkstr.hpp"#include "spnklog.hpp"int SP_NKHttpProtocol :: get( SP_NKSocket * socket,		const SP_NKHttpRequest * req, SP_NKHttpResponse * resp ){	int sockRet = sendReqHeader( socket, "GET", req );	if( sockRet > 0 ) sockRet = socket->printf( "\r\n" );	if( sockRet > 0 ) {		sockRet = recvRespHeader( socket, resp );		if( sockRet > 0 ) {			sockRet = recvRespBody( socket, resp );		}	}	return sockRet > 0 ? 0 : -1;}int SP_NKHttpProtocol :: post( SP_NKSocket * socket,		const SP_NKHttpRequest * req, SP_NKHttpResponse * resp ){	int sockRet = sendReqHeader( socket, "POST", req );	if( sockRet > 0 ) {		if( NULL != req->getContent() && req->getContentLength() > 0 ) {			sockRet = socket->printf( "%s: %d\r\n\r\n",					SP_NKHttpMessage::HEADER_CONTENT_LENGTH, req->getContentLength() );			if( sockRet > 0 ) {				sockRet = socket->writen( req->getContent(), req->getContentLength() );			}		} else {			sockRet = socket->printf( "\r\n" );		}	}	if( sockRet > 0 ) {		sockRet = recvRespHeader( socket, resp );		if( sockRet > 0 ) {			sockRet = recvRespBody( socket, resp );		}	}	return sockRet > 0 ? 0 : -1;}int SP_NKHttpProtocol :: head( SP_NKSocket * socket,		const SP_NKHttpRequest * req, SP_NKHttpResponse * resp ){	int sockRet = sendReqHeader( socket, "HEAD", req );	if( sockRet > 0 ) sockRet = socket->printf( "\r\n" );	if( sockRet > 0 ) sockRet = recvRespHeader( socket, resp );	return sockRet > 0 ? 0 : -1;}int SP_NKHttpProtocol :: sendReqHeader( SP_NKSocket * socket,		const char * method, const SP_NKHttpRequest * req ){	int sockRet = socket->printf( "%s %s %s\r\n", method,			req->getURI(), req->getVersion() );	for( int i = 0; i < req->getHeaderCount() && sockRet > 0; i++ ) {		const char * name = req->getHeaderName( i );		const char * val = req->getHeaderValue( i );		if( 0 != strcasecmp( SP_NKHttpMessage::HEADER_CONTENT_LENGTH, name ) ) {			sockRet = socket->printf( "%s: %s\r\n", name, val );		}	}	return sockRet > 0 ? 1 : -1;}int SP_NKHttpProtocol :: recvRespHeader( SP_NKSocket * socket, SP_NKHttpResponse * resp ){	static const char * thisFunc = "SP_NKHttpProtocol::recvRespHeader";	char * line = (char*)malloc( MAX_RECV_LEN );	assert( NULL != line );	*line = '\0';	int sockRet = socket->readline( line, MAX_RECV_LEN );	if( 0 == strncasecmp( line, "HTTP", strlen( "HTTP" ) ) ) {		char * pos = line;		char * first = SP_NKStr::strsep( &pos, " " );		char * second = SP_NKStr::strsep( &pos, " " );		if( NULL != first ) resp->setVersion( first );		if( NULL != second ) resp->setStatusCode( atoi( second ) );		if( NULL != pos ) resp->setReasonPhrase( strtok( pos, "\r\n" ) );	} else {		sockRet = -1;		SP_NKLog::log( LOG_WARNING, "WARN: Invalid response <%s>, ignored", line );	}	SP_NKStringList multiLine;	for( ; sockRet > 0 && '\0' != *line; ) {		*line = '\0';		sockRet = socket->readline( line, MAX_RECV_LEN );		if( ( ! isspace( *line ) ) || '\0' == *line ) {			if( multiLine.getCount() > 0 ) {				char * header = multiLine.getMerge();				char * pos = header;				SP_NKStr::strsep( &pos, ":" );				for( ; NULL != pos && '\0' != *pos && isspace( *pos ); ) pos++;				resp->addHeader( header, NULL == pos ? "" : pos );				free( header );			}			multiLine.clean();		}		const char * pos = line;		for( ; '\0' != *pos && isspace( *pos ); ) pos++;		if( '\0' != *pos ) multiLine.append( pos );	}	free( line );	line = NULL;	SP_NKLog::log( LOG_DEBUG, "RETN: %s = %d", thisFunc, sockRet );	return sockRet > 0 ? 1 : -1;}int SP_NKHttpProtocol :: recvRespBody( SP_NKSocket * socket, SP_NKHttpResponse * resp ){	int sockRet = 1;	const char * encoding = resp->getHeaderValue( SP_NKHttpMessage::HEADER_TRANSFER_ENCODING );	char * buff = (char*)malloc( MAX_RECV_LEN );	assert( NULL != buff );	if( NULL != encoding && 0 == strcasecmp( encoding, "chunked" ) ) {		// read chunked, refer to rfc2616 section[19.4.6]		for( ; sockRet > 0; ) {			sockRet = socket->readline( buff, MAX_RECV_LEN );			if( sockRet <= 0 ) break;			int size = strtol( buff, NULL, 16 );			if( size > 0 ) {				for( ; size > 0; ) {					int readLen = size > MAX_RECV_LEN ? MAX_RECV_LEN : size;					sockRet = socket->readn( buff, readLen );					if( sockRet > 0 ) {						size -= sockRet;						resp->appendContent( buff, sockRet );					} else {						break;					}				}			} else {				break;			}		}	} else {		const char * strLen = resp->getHeaderValue( SP_NKHttpMessage::HEADER_CONTENT_LENGTH );		if( NULL != strLen ) {			int size = atoi( NULL == strLen ? "" : strLen );			for( ; size > 0 && sockRet > 0; ) {				int readLen = size > MAX_RECV_LEN ? MAX_RECV_LEN : size;				sockRet = socket->readn( buff, readLen );				if( sockRet > 0 ) {					size -= sockRet;					resp->appendContent( buff, sockRet );				} else {					break;				}			}		} else {			// hasn't Content-Length header, read until socket close			for( ; sockRet > 0; ) {				sockRet = socket->read( buff, MAX_RECV_LEN );				if( sockRet > 0 ) resp->appendContent( buff, sockRet );			}			if( 0 == sockRet ) sockRet = 1;		}	}	free( buff );	return sockRet > 0 ? 1 : -1;}

⌨️ 快捷键说明

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