From 35eaded540f31378845b7a88e212a86a68825040 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Wed, 7 Jul 2010 11:40:20 -0700 Subject: Updated hipporestrequest code to hippo 0.6.3 --- linden/indra/llmessage/llhttpclient.cpp | 22 ++- linden/indra/llmessage/llhttpclient.h | 3 +- linden/indra/llxml/llxmlnode.cpp | 8 +- linden/indra/llxml/llxmlnode.h | 4 +- linden/indra/llxml/llxmlparser.cpp | 2 +- linden/indra/llxml/llxmlparser.h | 2 +- linden/indra/llxml/llxmltree.cpp | 119 +++++++++++- linden/indra/llxml/llxmltree.h | 19 +- linden/indra/newview/hippoGridManager.cpp | 5 +- linden/indra/newview/hippoRestRequest.cpp | 298 +++++++++++++++++++++++++++++- linden/indra/newview/hippoRestRequest.h | 98 +++++++++- 11 files changed, 551 insertions(+), 29 deletions(-) (limited to 'linden') diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index c26ef5e..7c7fe59 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -161,10 +161,9 @@ namespace fstream.seekg(0, std::ios::end); U32 fileSize = fstream.tellg(); fstream.seekg(0, std::ios::beg); - char* fileBuffer; - fileBuffer = new char [fileSize]; - fstream.read(fileBuffer, fileSize); - ostream.write(fileBuffer, fileSize); + std::vector fileBuffer(fileSize); + fstream.read(&fileBuffer[0], fileSize); + ostream.write(&fileBuffer[0], fileSize); fstream.close(); eos = true; return STATUS_DONE; @@ -191,11 +190,9 @@ namespace LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ); S32 fileSize = vfile.getSize(); - U8* fileBuffer; - fileBuffer = new U8 [fileSize]; - vfile.read(fileBuffer, fileSize); - ostream.write((char*)fileBuffer, fileSize); - delete [] fileBuffer; + std::vector fileBuffer(fileSize); + vfile.read(&fileBuffer[0], fileSize); + ostream.write((char*)&fileBuffer[0], fileSize); eos = true; return STATUS_DONE; } @@ -528,3 +525,8 @@ bool LLHTTPClient::hasPump() { return theClientPump != NULL; } + +LLPumpIO &LLHTTPClient::getPump() +{ + return *theClientPump; +} diff --git a/linden/indra/llmessage/llhttpclient.h b/linden/indra/llmessage/llhttpclient.h index a0c9fac..ab8afe8 100644 --- a/linden/indra/llmessage/llhttpclient.h +++ b/linden/indra/llmessage/llhttpclient.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -148,6 +148,7 @@ public: ///< must be called before any of the above calls are made static bool hasPump(); ///< for testing + static LLPumpIO &getPump(); }; #endif // LL_LLHTTPCLIENT_H diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp index 800b135..5bb5012 100644 --- a/linden/indra/llxml/llxmlnode.cpp +++ b/linden/indra/llxml/llxmlnode.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2005&license=viewergpl$ * - * Copyright (c) 2005-2009, Linden Research, Inc. + * Copyright (c) 2005-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -677,7 +677,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML U32 length = ftell(fp); fseek(fp, 0, SEEK_SET); - U8* buffer = new U8[length+1]; + char *buffer = new char[length+1]; size_t nread = fread(buffer, 1, length, fp); buffer[nread] = 0; fclose(fp); @@ -689,7 +689,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML // static bool LLXMLNode::parseBuffer( - U8* buffer, + const char *buffer, U32 length, LLXMLNodePtr& node, LLXMLNode* defaults) @@ -708,7 +708,7 @@ bool LLXMLNode::parseBuffer( XML_SetUserData(my_parser, (void *)file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, (const char *)buffer, length, TRUE) != XML_STATUS_OK) + if (XML_Parse(my_parser, buffer, length, TRUE) != XML_STATUS_OK) { llwarns << "Error parsing xml error code: " << XML_ErrorString(XML_GetErrorCode(my_parser)) diff --git a/linden/indra/llxml/llxmlnode.h b/linden/indra/llxml/llxmlnode.h index d4e127b..ab1a772 100644 --- a/linden/indra/llxml/llxmlnode.h +++ b/linden/indra/llxml/llxmlnode.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewergpl$ * - * Copyright (c) 2000-2009, Linden Research, Inc. + * Copyright (c) 2000-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -141,7 +141,7 @@ public: LLXMLNodePtr& node, LLXMLNode* defaults_tree); static bool parseBuffer( - U8* buffer, + const char *buffer, U32 length, LLXMLNodePtr& node, LLXMLNode* defaults); diff --git a/linden/indra/llxml/llxmlparser.cpp b/linden/indra/llxml/llxmlparser.cpp index 7d887f4..7304730 100644 --- a/linden/indra/llxml/llxmlparser.cpp +++ b/linden/indra/llxml/llxmlparser.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llxml/llxmlparser.h b/linden/indra/llxml/llxmlparser.h index d7595f6..9e7d256 100644 --- a/linden/indra/llxml/llxmlparser.h +++ b/linden/indra/llxml/llxmlparser.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llxml/llxmltree.cpp b/linden/indra/llxml/llxmltree.cpp index 1bce5d2..aa34f79 100644 --- a/linden/indra/llxml/llxmltree.cpp +++ b/linden/indra/llxml/llxmltree.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -50,6 +50,7 @@ LLStdStringTable LLXmlTree::sAttributeKeys(1024); LLXmlTree::LLXmlTree() : mRoot( NULL ), + mParser(0), mNodeNames(512) { } @@ -83,6 +84,39 @@ BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents) return success; } +bool LLXmlTree::parseBufferStart(bool keep_contents) +{ + if (mRoot) delete mRoot; + mRoot = NULL; + + if (mParser) delete mParser; + mParser = new LLXmlTreeParser(this); + mParser->parseBufferStart(keep_contents); + return (mParser != 0); +} + +bool LLXmlTree::parseBuffer(const char *buf, int len) +{ + bool success = mParser->parseBuffer(buf, len); + if (!success) { + S32 line_number = mParser->getCurrentLineNumber(); + const char* error = mParser->getErrorString(); + llwarns << "LLXmlTree parse failed in line " << line_number << ": " << error << llendl; + delete mParser; + mParser = 0; + } + return success; +} + +bool LLXmlTree::parseBufferFinalize() +{ + bool success = mParser->parseBufferFinalize(&mRoot); + delete mParser; + mParser = 0; + return success; +} + + void LLXmlTree::dump() { if( mRoot ) @@ -102,6 +136,25 @@ void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix ) } } +void LLXmlTree::write(std::string &buffer) const +{ + if (mRoot) writeNode(mRoot, buffer, ""); +} + +void LLXmlTree::writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const +{ + if (!node->getFirstChild()) { + node->writeNoChild(buffer, indent); + } else { + node->writeStart(buffer, indent); + std::string newIndent = indent + " "; + for (LLXmlTreeNode *child=node->getFirstChild(); child; child=node->getNextChild()) + writeNode(child, buffer, newIndent); + node->writeEnd(buffer, indent); + } +} + + ////////////////////////////////////////////////////////////// // LLXmlTreeNode @@ -139,6 +192,43 @@ void LLXmlTreeNode::dump( const std::string& prefix ) llcont << llendl; } +void LLXmlTreeNode::writeNoChild(std::string &buffer, const std::string &indent) const +{ + if (!mContents.empty()) { + writeStart(buffer, indent); + writeEnd(buffer, indent); + } else { + buffer += indent + '<' + mName; + writeAttributes(buffer); + buffer += "/>\n"; + } +} + +void LLXmlTreeNode::writeStart(std::string &buffer, const std::string &indent) const +{ + buffer += indent + '<' + mName; + writeAttributes(buffer); + buffer += ">\n"; +} + +void LLXmlTreeNode::writeEnd(std::string &buffer, const std::string &indent) const +{ + if (!mContents.empty()) { + buffer += indent + " " + mContents + '\n'; + } + buffer += indent + "\n"; +} + +void LLXmlTreeNode::writeAttributes(std::string &buffer) const +{ + attribute_map_t::const_iterator it, end = mAttributes.end(); + for (it=mAttributes.begin(); it!=end; ++it) { + LLStdStringHandle key = it->first; + const std::string *value = it->second; + buffer += ' ' + *key + "=\"" + *value + '"'; + } +} + BOOL LLXmlTreeNode::hasAttribute(const std::string& name) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); @@ -527,7 +617,7 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B BOOL success = LLXmlParser::parseFile(path); - *root = mRoot; + if (root) *root = mRoot; mRoot = NULL; if( success ) @@ -539,6 +629,31 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B return success; } +void LLXmlTreeParser::parseBufferStart(BOOL keep_contents) +{ + llassert(!mRoot); + llassert(!mCurrent); + mKeepContents = keep_contents; +} + +bool LLXmlTreeParser::parseBuffer(const char *buf, int len) +{ + return (LLXmlParser::parse(buf, len, false) != 0); +} + +bool LLXmlTreeParser::parseBufferFinalize(LLXmlTreeNode** root) +{ + bool success = (LLXmlParser::parse(0, 0, true) != 0); + + if (root) *root = mRoot; + mRoot = NULL; + + llassert(!success || !mCurrent); + mCurrent = NULL; + + return success; +} + const std::string& LLXmlTreeParser::tabs() { diff --git a/linden/indra/llxml/llxmltree.h b/linden/indra/llxml/llxmltree.h index 1a020f2..31f89de 100644 --- a/linden/indra/llxml/llxmltree.h +++ b/linden/indra/llxml/llxmltree.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -63,11 +63,18 @@ public: virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE); + bool parseBufferStart(bool keep_contents = true); + bool parseBuffer(const char *buf, int len); + bool parseBufferFinalize(); + LLXmlTreeNode* getRoot() { return mRoot; } void dump(); void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); + void write(std::string &buffer) const; + void writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const; + static LLStdStringHandle addAttributeString( const std::string& name) { return sAttributeKeys.addString( name ); @@ -79,6 +86,7 @@ public: protected: LLXmlTreeNode* mRoot; + LLXmlTreeParser *mParser; // local LLStdStringTable mNodeNames; @@ -175,6 +183,11 @@ private: void dump( const std::string& prefix ); + void writeNoChild(std::string &buffer, const std::string &indent) const; + void writeStart(std::string &buffer, const std::string &indent) const; + void writeEnd(std::string &buffer, const std::string &indent) const; + void writeAttributes(std::string &buffer) const; + protected: typedef std::map attribute_map_t; attribute_map_t mAttributes; @@ -207,6 +220,10 @@ public: BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents ); + void parseBufferStart(BOOL keep_contents); + bool parseBuffer(const char *buf, int len); + bool parseBufferFinalize(LLXmlTreeNode** root); + protected: const std::string& tabs(); diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp index 0160233..e89e3ff 100644 --- a/linden/indra/newview/hippoGridManager.cpp +++ b/linden/indra/newview/hippoGridManager.cpp @@ -160,7 +160,10 @@ const std::string& HippoGridInfo::getRealCurrencySymbol() const void HippoGridInfo::setPlatform(Platform platform) { mPlatform = platform; - mCurrencySymbol = (mPlatform == PLATFORM_SECONDLIFE)? "L$": "OS$"; + if (mPlatform == PLATFORM_SECONDLIFE) + { + mCurrencySymbol = "L$"; + } } diff --git a/linden/indra/newview/hippoRestRequest.cpp b/linden/indra/newview/hippoRestRequest.cpp index 20e6187..ed15907 100644 --- a/linden/indra/newview/hippoRestRequest.cpp +++ b/linden/indra/newview/hippoRestRequest.cpp @@ -10,7 +10,303 @@ #include #include +#include #include +#include +#include +#include + + +// ******************************************************************** + + +class HippoRestComplete : public LLURLRequestComplete +{ + public: + HippoRestComplete(HippoRestHandler *handler) : + mHandler(handler), + mStatus(499), + mReason("Request completed w/o status") + { + } + + ~HippoRestComplete() + { + delete mHandler; + } + + // Called once for each header received, prior to httpStatus + void header(const std::string& header, const std::string& value) + { + mHandler->addHeader(header, value); + } + + // Always called on request completion, prior to complete + void httpStatus(U32 status, const std::string& reason) + { + LLURLRequestComplete::httpStatus(status, reason); + mStatus = status; + mReason = reason; + } + + void complete(const LLChannelDescriptors &channels, const buffer_ptr_t &buffer) + { + mHandler->handle(mStatus, mReason, channels, buffer); + } + + private: + HippoRestHandler *mHandler; + int mStatus; + std::string mReason; +}; + + +// ******************************************************************** + + +static std::string gEmptyString; + +void HippoRestHandler::addHeader(const std::string &header, const std::string &content) +{ + mHeaders[header] = content; +} + +bool HippoRestHandler::hasHeader(const std::string &header) const +{ + return (mHeaders.find(header) != mHeaders.end()); +} + +const std::string &HippoRestHandler::getHeader(const std::string &header) const +{ + std::map::const_iterator it; + it = mHeaders.find(header); + if (it != mHeaders.end()) { + return it->second; + } else { + return gEmptyString; + } +} + + +// ******************************************************************** + + +void HippoRestHandlerRaw::handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) +{ + if (status == 200) { + std::string data; + LLBufferArray *buffer = body.get(); + LLBufferArray::segment_iterator_t it, end = buffer->endSegment(); + for (it=buffer->beginSegment(); it!=end; ++it) + if (it->isOnChannel(channels.in())) + data.append((char*)it->data(), it->size()); + result(data); + } else { + llwarns << "Rest request error " << status << ": " << reason << llendl; + } +} + +void HippoRestHandlerXml::handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) +{ + if (status == 200) { + LLXmlTree *tree = new LLXmlTree(); + bool success = tree->parseBufferStart(); + LLBufferArray *buffer = body.get(); + LLBufferArray::segment_iterator_t it, end = buffer->endSegment(); + for (it=buffer->beginSegment(); success && (it!=end); ++it) + if (it->isOnChannel(channels.in())) + success = success && tree->parseBuffer((char*)it->data(), it->size()); + success = success && tree->parseBufferFinalize(); + if (success) result(tree); + delete tree; + } else { + llwarns << "Rest request error " << status << ": " << reason << llendl; + } +} + + +// ******************************************************************** + + +class BodyData : public LLIOPipe +{ + public: + virtual ~BodyData() { } + virtual const char *getContentMimeType() const = 0; +}; + +class BodyDataRaw : public BodyData +{ + public: + explicit BodyDataRaw(const std::string &data) : + mData(data) + { + } + virtual ~BodyDataRaw() { } + + const char *getContentMimeType() const { return "application/octet-stream"; } + + EStatus process_impl(const LLChannelDescriptors &channels, + buffer_ptr_t &buffer, bool &eos, + LLSD &context, LLPumpIO *pump) + { + LLBufferStream ostream(channels, buffer.get()); + ostream.write(mData.data(), mData.size()); + eos = true; + return STATUS_DONE; + } + + private: + std::string mData; +}; + +class BodyDataXml : public BodyData +{ + public: + explicit BodyDataXml(const LLXmlTree *tree) : + mTree(tree) + { + } + + virtual ~BodyDataXml() + { + if (mTree) delete mTree; + } + + const char *getContentMimeType() const { return "application/xml"; } + + EStatus process_impl(const LLChannelDescriptors &channels, + buffer_ptr_t &buffer, bool &eos, + LLSD &context, LLPumpIO *pump) + { + std::string data; + mTree->write(data); + LLBufferStream ostream(channels, buffer.get()); + ostream.write(data.data(), data.size()); + eos = true; + return STATUS_DONE; + } + + private: + const LLXmlTree *mTree; +}; + + +// ******************************************************************** + + +static void request(const std::string &url, + LLURLRequest::ERequestAction method, + BodyData *body, + HippoRestHandler *handler, float timeout); + + +// static +void HippoRestRequest::get(const std::string &url, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_GET, 0, handler, timeout); +} + +// static +void HippoRestRequest::put(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_PUT, new BodyDataRaw(body), handler, timeout); +} + +// static +void HippoRestRequest::put(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_PUT, new BodyDataXml(body), handler, timeout); +} + +// static +void HippoRestRequest::post(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_POST, new BodyDataRaw(body), handler, timeout); +} + +// static +void HippoRestRequest::post(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_POST, new BodyDataXml(body), handler, timeout); +} + + +// ******************************************************************** + + +static void request(const std::string &url, + LLURLRequest::ERequestAction method, + BodyData *body, + HippoRestHandler *handler, float timeout) +{ + if (!LLHTTPClient::hasPump()) + { + // !!! responder->completed(U32_MAX, "No pump", LLSD()); + return; + } + LLPumpIO::chain_t chain; + + LLURLRequest *req = new LLURLRequest(method, url); + req->checkRootCertificate(true); + + /* + // Insert custom headers if the caller sent any + if (headers.isMap()) + { + LLSD::map_const_iterator iter = headers.beginMap(); + LLSD::map_const_iterator end = headers.endMap(); + + for (; iter != end; ++iter) + { + std::ostringstream header; + //if the header is "Pragma" with no value + //the caller intends to force libcurl to drop + //the Pragma header it so gratuitously inserts + //Before inserting the header, force libcurl + //to not use the proxy (read: llurlrequest.cpp) + static const std::string PRAGMA("Pragma"); + if ((iter->first == PRAGMA) && (iter->second.asString().empty())) + { + req->useProxy(false); + } + header << iter->first << ": " << iter->second.asString() ; + lldebugs << "header = " << header.str() << llendl; + req->addHeader(header.str().c_str()); + } + } + */ + + if ((method != LLURLRequest::HTTP_PUT) && (method != LLURLRequest::HTTP_POST)) { + std::string accept = "Accept: "; + accept += handler->getAcceptMimeType(); + req->addHeader(accept.c_str()); + } + + req->setCallback(new HippoRestComplete(handler)); + + if ((method == LLURLRequest::HTTP_PUT) || (method == LLURLRequest::HTTP_POST)) { + std::string content = "Content-Type: "; + content += body->getContentMimeType(); + req->addHeader(content.c_str()); + chain.push_back(LLIOPipe::ptr_t(body)); + } + + chain.push_back(LLIOPipe::ptr_t(req)); + LLHTTPClient::getPump().addChain(chain, timeout); +} + + +// ******************************************************************** static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) @@ -22,7 +318,7 @@ static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) } -//static +// static int HippoRestRequest::getBlocking(const std::string &url, std::string *result) { llinfos << "Requesting: " << url << llendl; diff --git a/linden/indra/newview/hippoRestRequest.h b/linden/indra/newview/hippoRestRequest.h index 1dcb4a0..727dbf7 100644 --- a/linden/indra/newview/hippoRestRequest.h +++ b/linden/indra/newview/hippoRestRequest.h @@ -1,15 +1,103 @@ -#ifndef __HIPPO_REST_REQTUEST_H__ -#define __HIPPO_REST_REQTUEST_H__ +#ifndef __HIPPO_REST_REQUEST_H__ +#define __HIPPO_REST_REQUEST_H__ +#include #include +#include + +class LLBufferArray; +class LLChannelDescriptors; +class LLXmlTree; + + +#define HIPPO_REST_TIMEOUT 60.f + + +// ******************************************************************** + + +class HippoRestHandler +{ + public: + virtual ~HippoRestHandler() { } + + virtual const char *getAcceptMimeType() const = 0; + + bool hasHeader(const std::string &header) const; + const std::string &getHeader(const std::string &header) const; + + private: + // These functions are called by the request engine + void addHeader(const std::string &header, const std::string &content); + virtual void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) = 0; + + std::map mHeaders; + + friend class HippoRestComplete; +}; + + +class HippoRestHandlerRaw : public HippoRestHandler +{ + public: + virtual ~HippoRestHandlerRaw() { } + + const char *getAcceptMimeType() const { return "application/octet-stream"; } + + private: + // This function must be implemented to receive the content + // it is executed on (status == 200) only + virtual void result(const std::string &content) = 0; + + // This function is called by the request engine + void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body); +}; + + +class HippoRestHandlerXml : public HippoRestHandler +{ + public: + virtual ~HippoRestHandlerXml() { } + + const char *getAcceptMimeType() const { return "application/xml"; } + + private: + // This function must be implemented to receive the content + virtual void result(LLXmlTree *content) = 0; + + // This function is called by the request engine + void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body); +}; + + +// ******************************************************************** + class HippoRestRequest { - public: - static int getBlocking(const std::string &url, std::string *result); - + public: + // asynchronous interface + static void get(const std::string &url, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void put(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void put(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void post(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void post(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + + // synchronous interface + static int getBlocking(const std::string &url, std::string *result); }; -- cgit v1.1