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

📄 sphttp.cpp

📁 spserver 是一个实现了半同步/半异步(Half-Sync/Half-Async)和领导者/追随者(Leader/Follower) 模式的服务器框架
💻 CPP
字号:
/* * Copyright 2007 Stephen Liu * For license terms, see the file COPYING along with this library. */#include <stdio.h>#include <time.h>#include <string.h>#include "sphttp.hpp"#include "sphttpmsg.hpp"#include "spbuffer.hpp"#include "sprequest.hpp"#include "spresponse.hpp"#include "spmsgblock.hpp"SP_HttpHandler :: ~SP_HttpHandler(){}void SP_HttpHandler :: error(){}void SP_HttpHandler :: timeout(){}//---------------------------------------------------------SP_HttpHandlerFactory :: ~SP_HttpHandlerFactory(){}//---------------------------------------------------------class SP_HttpRequestDecoder : public SP_MsgDecoder {public:	SP_HttpRequestDecoder();	virtual ~SP_HttpRequestDecoder();	virtual int decode( SP_Buffer * inBuffer );	SP_HttpRequest * getMsg();private:	SP_HttpMsgParser * mParser;};SP_HttpRequestDecoder :: SP_HttpRequestDecoder(){	mParser = new SP_HttpMsgParser();}SP_HttpRequestDecoder :: ~SP_HttpRequestDecoder(){	delete mParser;}int SP_HttpRequestDecoder :: decode( SP_Buffer * inBuffer ){	if( inBuffer->getSize() > 0 ) {		int len = mParser->append( inBuffer->getBuffer(), inBuffer->getSize() );		inBuffer->erase( len );		return mParser->isCompleted() ? eOK : eMoreData;	} else {		return eMoreData;	}}SP_HttpRequest * SP_HttpRequestDecoder :: getMsg(){	return mParser->getRequest();}//---------------------------------------------------------class SP_HttpResponseMsgBlock : public SP_MsgBlock {public:	SP_HttpResponseMsgBlock( SP_HttpResponse * response );	virtual ~SP_HttpResponseMsgBlock();	virtual const void * getData() const;	virtual size_t getSize() const;private:	SP_HttpResponse * mResponse;};SP_HttpResponseMsgBlock :: SP_HttpResponseMsgBlock( SP_HttpResponse * response ){	mResponse = response;}SP_HttpResponseMsgBlock :: ~SP_HttpResponseMsgBlock(){	if( NULL != mResponse ) delete mResponse;	mResponse = NULL;}const void * SP_HttpResponseMsgBlock :: getData() const{	return mResponse->getContent();}size_t SP_HttpResponseMsgBlock :: getSize() const{	return mResponse->getContentLength();}//---------------------------------------------------------class SP_HttpHandlerAdapter : public SP_Handler {public:	SP_HttpHandlerAdapter( SP_HttpHandler * handler );	virtual ~SP_HttpHandlerAdapter();	// return -1 : terminate session, 0 : continue	virtual int start( SP_Request * request, SP_Response * response );	// return -1 : terminate session, 0 : continue	virtual int handle( SP_Request * request, SP_Response * response );	virtual void error( SP_Response * response );	virtual void timeout( SP_Response * response );	virtual void close();private:	SP_HttpHandler * mHandler;};SP_HttpHandlerAdapter :: SP_HttpHandlerAdapter( SP_HttpHandler * handler ){	mHandler = handler;}SP_HttpHandlerAdapter :: ~SP_HttpHandlerAdapter(){	delete mHandler;}int SP_HttpHandlerAdapter :: start( SP_Request * request, SP_Response * response ){	request->setMsgDecoder( new SP_HttpRequestDecoder() );	return 0;}int SP_HttpHandlerAdapter :: handle( SP_Request * request, SP_Response * response ){	SP_HttpRequestDecoder * decoder = ( SP_HttpRequestDecoder * ) request->getMsgDecoder();	SP_HttpRequest * httpRequest = ( SP_HttpRequest * ) decoder->getMsg();	httpRequest->setClinetIP( request->getClientIP() );	SP_HttpResponse * httpResponse = new SP_HttpResponse();	httpResponse->setVersion( httpRequest->getVersion() );	mHandler->handle( httpRequest, httpResponse );	SP_Buffer * reply = response->getReply()->getMsg();	char buffer[ 512 ] = { 0 };	snprintf( buffer, sizeof( buffer ), "%s %i %s\r\n", httpResponse->getVersion(),		httpResponse->getStatusCode(), httpResponse->getReasonPhrase() );	reply->append( buffer );	// check keep alive header	if( httpRequest->isKeepAlive() ) {		if( NULL == httpResponse->getHeaderValue( SP_HttpMessage::HEADER_CONNECTION ) ) {			httpResponse->addHeader( SP_HttpMessage::HEADER_CONNECTION, "Keep-Alive" );		}	}	// check Content-Length header	httpResponse->removeHeader( SP_HttpMessage::HEADER_CONTENT_LENGTH );	if( httpResponse->getContentLength() > 0 ) {		snprintf( buffer, sizeof( buffer ), "%d", httpResponse->getContentLength() );		httpResponse->addHeader( SP_HttpMessage::HEADER_CONTENT_LENGTH, buffer );	}	// check date header	httpResponse->removeHeader( SP_HttpMessage::HEADER_DATE );	time_t tTime = time( NULL );	struct tm tmTime;	localtime_r( &tTime, &tmTime );	strftime( buffer, sizeof( buffer ), "%a, %d %b %Y %H:%M:%d %Z", &tmTime );	httpResponse->addHeader( SP_HttpMessage::HEADER_DATE, buffer );	// check Content-Type header	if( NULL == httpResponse->getHeaderValue( SP_HttpMessage::HEADER_CONTENT_TYPE ) ) {		httpResponse->addHeader( SP_HttpMessage::HEADER_CONTENT_TYPE,			"text/html; charset=ISO-8859-1" );	}	// check Server header	httpResponse->removeHeader( SP_HttpMessage::HEADER_SERVER );	httpResponse->addHeader( SP_HttpMessage::HEADER_SERVER, "sphttp/spserver" );	for( int i = 0; i < httpResponse->getHeaderCount(); i++ ) {		snprintf( buffer, sizeof( buffer ), "%s: %s\r\n",			httpResponse->getHeaderName( i ), httpResponse->getHeaderValue( i ) );		reply->append( buffer );	}	reply->append( "\r\n" );		if( NULL != httpResponse->getContent() ) {		response->getReply()->getFollowBlockList()->append(				new SP_HttpResponseMsgBlock( httpResponse ) );	}	const char * keepAlive = httpResponse->getHeaderValue( SP_HttpMessage::HEADER_CONNECTION );	request->setMsgDecoder( new SP_HttpRequestDecoder() );	return ! ( NULL != keepAlive && 0 == strcasecmp( keepAlive, "Keep-Alive" ) );}void SP_HttpHandlerAdapter :: error( SP_Response * response ){	mHandler->error();}void SP_HttpHandlerAdapter :: timeout( SP_Response * response ){	mHandler->timeout();}void SP_HttpHandlerAdapter :: close(){}//---------------------------------------------------------SP_HttpHandlerAdapterFactory :: SP_HttpHandlerAdapterFactory( SP_HttpHandlerFactory * factory ){	mFactory = factory;}SP_HttpHandlerAdapterFactory :: ~SP_HttpHandlerAdapterFactory(){	delete mFactory;}SP_Handler * SP_HttpHandlerAdapterFactory :: create() const{	return new SP_HttpHandlerAdapter( mFactory->create() );}

⌨️ 快捷键说明

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