📄 sphttp.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 + -