HTTPpipe.h
资源名称:cppapp.zip [点击查看]
上传用户:smh666999
上传日期:2007-01-14
资源大小:553k
文件大小:7k
源码类别:
BREW编程
开发平台:
Visual C++
- #ifndef _httppipe_h_
- #define _httppipe_h_
- #include "BrewString.h"
- #include "AEEStdlib.h"
- #include "AEENet.h"
- #include "AEEAppGen.h"
- #include "AEE.h"
- #include "CbkDispatcher.h"
- //Port address to connect to.
- #define TIMESERVER_PORT 80
- #define TIMESERVER_HOST "216.18.119.195" // IP address in a.b.c.d dot-notation
- #define WEB_ERROR_PROTOCOL AEE_NET_EBADAPP
- // Invalid Address
- #define DOTADDR_NONE 0xFFFFFFFF
- typedef enum {NO_DATA_TYPE, TEXT_DATA_TYPE, IMAGE_DATA_TYPE} DATA_TYPE;
- //A few utility macros; We shall eventually move this into the AEE Services.
- #define ISDIGIT(c) ( (unsigned) ((c) - '0') < 10)
- #define ISALPHA(c) ( (unsigned) ( ((c)|32) - 'a') < 26 )
- #define ISALNUM(c) ( ISDIGIT(c) || ISALPHA(c) )
- #define HTTP_REQUEST_TAIL " HTTP/1.0 rnrn"
- #define HTTP_HEADER_TAIL "rnrn"
- struct HDS: public IRelease
- {
- static void createHTTPDataStruct(HDS*& ds)
- {
- if (ds==0)
- ds = new HDS();
- }
- virtual void releaseResource( )
- {
- delete this;
- }
- virtual int getUID( )
- {
- return 100;
- }
- static int getID()
- {
- return 100;
- }
- template <class R>
- static HDS* initDataStruct(R* rr, char* address, const String& params )
- {
- HDS* ds=static_cast<HDS*>(rr->getRegistered(HDS::getID()));
- HDS::createHTTPDataStruct(ds);
- ds->address = address;
- ds->parameters = params;
- if (!ds->data.isEmpty())
- ds->data="";
- rr->registerResource(ds);
- return ds;
- }
- char* address;
- String parameters;
- String data;
- int error;
- DATA_TYPE dataType;
- UINT bufSize;
- private:
- HDS() : bufSize(128)
- {}
- HDS( const HDS &Value );
- const HDS &operator = ( const HDS &Rhs );
- };
- template <class Y, class F>
- struct pkCBK;
- class HTTPpipe
- {
- public:
- HTTPpipe(IShell* shell, IExecute* pp, HDS* ds) :
- shell_(shell),
- processPolicy_(pp),
- piSock_(0),
- piNet_(0),
- isHeaderProcessed_(false),
- buf_(new char[ds->bufSize+1]),
- ds_(ds)
- {
- }
- ~HTTPpipe();
- int init();
- int initConnection();
- void reset();
- private:
- void connect( int err);
- static void connectStatic(HTTPpipe* app, int err);
- void write();
- void read();
- int readHeader();
- void onError( int errorCode) ;
- void onData( ) ;
- void releaseResources();
- void releaseResource();
- private:
- IShell* shell_;
- INetMgr *piNet_;
- ISocket *piSock_;
- IExecute* processPolicy_;
- String command_;
- bool isHeaderProcessed_;
- char* buf_;
- typedef pkCBK0<HTTPpipe, void (HTTPpipe::*)()> P;
- P p_;
- typedef pkCBK1<HTTPpipe, void (HTTPpipe::*)(int)> PI;
- PI pi_;
- HDS* ds_;
- private:
- HTTPpipe( const HTTPpipe &Value );
- const HTTPpipe &operator = ( const HTTPpipe &Rhs );
- };
- static INAddr xConvertToINAddr(char *psz)
- {
- INAddr ul = 0;
- int nByte = 0;
- char c;
- if(!psz)
- return 0;
- while (ISDIGIT(*psz)) {
- int n = 0;
- while ( ISDIGIT(c=*psz)) {
- n = n*10 + (c - '0');
- ++psz;
- }
- ((char*)&ul)[nByte++] = n;
- if (nByte == 4 || *psz != '.')
- break;
- ++psz;
- }
- if (nByte < 4 || ISALNUM(*psz))
- ul = DOTADDR_NONE;
- return ul;
- }
- HTTPpipe::~HTTPpipe()
- {
- releaseResources();
- }
- void HTTPpipe::releaseResource()
- {
- if (piSock_)
- {
- ISOCKET_Cancel(piSock_, 0, 0);
- ISOCKET_Release(piSock_);
- piSock_ = 0;
- }
- }
- void HTTPpipe::reset()
- {
- releaseResource();
- isHeaderProcessed_ = false;
- command_ = "";
- }
- void HTTPpipe::releaseResources()
- {
- releaseResource();
- if (piNet_)
- {
- INETMGR_Release(piNet_);
- piNet_ = 0;
- }
- delete[] buf_;
- buf_ = 0;
- }
- int HTTPpipe::init()
- {
- int err;
- if ((err = ISHELL_CreateInstance(shell_, AEECLSID_NET, (void**)(&piNet_))) != SUCCESS)
- {
- return err;
- }
- if (!piNet_)
- {
- return EFAILED;
- }
- // INETMGR_SetLinger(piNet_, 0);
- return SUCCESS;
- }
- int HTTPpipe::initConnection()
- {
- if (piSock_)
- {
- return SUCCESS; //safe approach if a connection is tried
- //before ending the previous one - isReusable==true
- }
- int err;
- // DBGPRINTF("initConnection");
- piSock_ = INETMGR_OpenSocket(piNet_, AEE_SOCK_STREAM);
- if (!piSock_)
- {
- err = INETMGR_GetLastError(piNet_);
- return err;
- }
- INAddr nodeINAddr = xConvertToINAddr(ds_->address);
- command_ = "GET " + ds_->parameters + HTTP_REQUEST_TAIL;
- pi_.setCallback(this, &HTTPpipe::connect);
- if ((err = ISOCKET_Connect (piSock_, nodeINAddr, AEE_htons(TIMESERVER_PORT),
- (PFNCONNECTCB)PI::callbackHandler, &pi_)) != AEE_NET_SUCCESS)
- {
- return ISOCKET_GetLastError(piSock_);
- }
- return SUCCESS;
- }
- void HTTPpipe::connectStatic(HTTPpipe* app, int err)
- {
- app->connect(err);
- }
- void HTTPpipe::connect(int err)
- {
- if (err)
- {
- DBGPRINTF("error connect");
- onError(err) ;
- return;
- }
- p_.setCallback(this, &HTTPpipe::write);
- write();
- return;
- }
- void HTTPpipe::write ()
- {
- const char *psz = command_.toCharArray();
- int cbWrite = command_.length();
- while (cbWrite > 0) {
- int rv = ISOCKET_Write(piSock_,
- (byte *)psz, (uint16)cbWrite);
- if (rv == AEE_NET_WOULDBLOCK) {
- command_.partialString(command_.length()- cbWrite, command_.length());
- ISOCKET_Writeable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
- return;
- }
- else if (rv == AEE_NET_ERROR)
- {
- onError(ISOCKET_GetLastError(piSock_)) ;
- return;
- }
- cbWrite -= rv;
- psz += rv;
- }
- p_.setCallback(this,&HTTPpipe::read);
- read();
- return;
- }
- void HTTPpipe::read ()
- {
- if (!piSock_)
- {
- DBGPRINTF("piSock == 0 in read");
- onError(EFAILED);
- return;
- }
- int32 rv = ISOCKET_Read(piSock_, buf_, ds_->bufSize);
- if (rv == AEE_NET_WOULDBLOCK)
- {
- ISOCKET_Readable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
- return;
- }
- else if (rv == AEE_NET_ERROR)
- {
- onError(ISOCKET_GetLastError(piSock_)) ;
- return;
- }
- else if (rv > 0)
- {
- buf_[rv] = 0;
- ds_->data += buf_;
- if (!isHeaderProcessed_)
- {
- int err = readHeader();
- if (err == SUCCESS)
- {
- isHeaderProcessed_ = true;
- }
- else if (err == WEB_ERROR_PROTOCOL)
- {
- onError(err) ;
- return;
- }
- }
- ISOCKET_Readable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
- return;
- }
- else if (rv == 0)
- {
- onData();
- return;
- }
- }
- int HTTPpipe::readHeader()
- {
- int contentIndex = ds_->data.indexOf(HTTP_HEADER_TAIL);
- if (contentIndex == -1)
- {
- return EFAILED;
- }
- contentIndex += 4;
- // String content = "Content-Type:";
- // String cLength = "Content-Length:";
- int statusIndexStart = ds_->data.indexOf("HTTP/");
- statusIndexStart = ds_->data.indexOf(" ", statusIndexStart + 1);
- int statusIndexEnd = ds_->data.indexOf(" ", statusIndexStart + 1);
- int status = ATOI((ds_->data.substring(statusIndexStart, statusIndexEnd)).toCharArray())/100;
- if (status != 2)
- {
- return WEB_ERROR_PROTOCOL;
- }
- ds_->dataType = (ds_->data.indexOf("image/") > -1) ? IMAGE_DATA_TYPE : TEXT_DATA_TYPE;
- ds_->data.partialString(contentIndex, ds_->data.length());
- return SUCCESS;
- }
- void HTTPpipe::onError( int errorCode) {
- ds_->error = errorCode;
- ds_->data = "";
- ds_->dataType = NO_DATA_TYPE;
- processPolicy_->onCbk() ;
- }
- void HTTPpipe::onData( ) {
- ds_->error = SUCCESS;
- processPolicy_->onCbk() ;
- }
- #endif