diff options
Diffstat (limited to 'indra/llmessage')
-rw-r--r-- | indra/llmessage/llhttpnode.cpp | 10 | ||||
-rw-r--r-- | indra/llmessage/llhttpnode.h | 15 | ||||
-rw-r--r-- | indra/llmessage/lliohttpserver.cpp | 71 | ||||
-rw-r--r-- | indra/llmessage/lliohttpserver.h | 12 | ||||
-rw-r--r-- | indra/llmessage/llservicebuilder.cpp | 22 |
5 files changed, 113 insertions, 17 deletions
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 0114ad0713..2ba900a533 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -36,8 +36,8 @@ #include <boost/tokenizer.hpp> #include "llstl.h" +#include "lliohttpserver.h" // for string constants -static const std::string CONTEXT_REQUEST("request"); static const std::string CONTEXT_WILDCARD("wildcard"); /** @@ -181,7 +181,8 @@ void LLHTTPNode::options(ResponsePtr response, const LLSD& context) const //llinfos << "options context: " << context << llendl; // default implementation constructs an url to the documentation. - std::string host = context[CONTEXT_REQUEST]["headers"]["host"].asString(); + std::string host( + context[CONTEXT_REQUEST][CONTEXT_HEADERS]["host"].asString()); if(host.empty()) { response->status(400, "Bad Request -- need Host header"); @@ -475,6 +476,11 @@ void LLSimpleResponse::result(const LLSD& result) status(200, "OK"); } +void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const LLSD& headers) +{ + status(code,body); +} + void LLSimpleResponse::status(S32 code, const std::string& message) { mCode = code; diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index a6f14f6545..4f80db47f1 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -38,7 +38,6 @@ class LLChainIOFactory; - /** * These classes represent the HTTP framework: The URL tree, and the LLSD * REST interface that such nodes implement. @@ -101,6 +100,11 @@ public: virtual void result(const LLSD&) = 0; /** + * @brief return status code and message with headers. + */ + virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) = 0; + + /** * @brief return status code and reason string on http header, * but do not return a payload. */ @@ -218,6 +222,14 @@ public: const LLHTTPNode* rootNode() const; const LLHTTPNode* findNode(const std::string& name) const; + + enum EHTTPNodeContentType + { + CONTENT_TYPE_LLSD, + CONTENT_TYPE_TEXT + }; + + virtual EHTTPNodeContentType getContentType() const { return CONTENT_TYPE_LLSD; } //@} /* @name Description system @@ -277,6 +289,7 @@ public: static LLPointer<LLSimpleResponse> create(); void result(const LLSD& result); + void extendedResult(S32 code, const std::string& body, const LLSD& headers); void status(S32 code, const std::string& message); void print(std::ostream& out) const; diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 6486e5e3e0..0895af091b 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -57,15 +57,15 @@ #include <boost/tokenizer.hpp> static const char HTTP_VERSION_STR[] = "HTTP/1.0"; -static const std::string CONTEXT_REQUEST("request"); -static const std::string CONTEXT_RESPONSE("response"); -static const std::string CONTEXT_VERB("verb"); -static const std::string CONTEXT_HEADERS("headers"); -static const std::string HTTP_VERB_GET("GET"); -static const std::string HTTP_VERB_PUT("PUT"); -static const std::string HTTP_VERB_POST("POST"); -static const std::string HTTP_VERB_DELETE("DELETE"); -static const std::string HTTP_VERB_OPTIONS("OPTIONS"); +const std::string CONTEXT_REQUEST("request"); +const std::string CONTEXT_RESPONSE("response"); +const std::string CONTEXT_VERB("verb"); +const std::string CONTEXT_HEADERS("headers"); +const std::string HTTP_VERB_GET("GET"); +const std::string HTTP_VERB_PUT("PUT"); +const std::string HTTP_VERB_POST("POST"); +const std::string HTTP_VERB_DELETE("DELETE"); +const std::string HTTP_VERB_OPTIONS("OPTIONS"); static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL; static void* sTimingCallbackData = NULL; @@ -104,6 +104,7 @@ private: // from LLHTTPNode::Response virtual void result(const LLSD&); + virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers); virtual void status(S32 code, const std::string& message); void nullPipe(); @@ -122,7 +123,8 @@ private: STATE_DELAYED, STATE_LOCKED, STATE_GOOD_RESULT, - STATE_STATUS_RESULT + STATE_STATUS_RESULT, + STATE_EXTENDED_RESULT }; State mState; @@ -180,14 +182,32 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( { LLPerfBlock putblock("http_put"); LLSD input; - LLSDSerialize::fromXML(input, istr); + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::stringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_POST) { LLPerfBlock postblock("http_post"); LLSD input; - LLSDSerialize::fromXML(input, istr); + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::stringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_DELETE) @@ -262,7 +282,16 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage; LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage << std::ends; + ostr << mStatusMessage; + + return STATUS_DONE; + } + case STATE_EXTENDED_RESULT: + { + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders; + context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; + LLBufferStream ostr(channels, buffer.get()); + ostr << mStatusMessage; return STATUS_DONE; } @@ -309,6 +338,21 @@ void LLHTTPPipe::Response::result(const LLSD& r) mPipe->unlockChain(); } +void LLHTTPPipe::Response::extendedResult(S32 code, const std::string& body, const LLSD& headers) +{ + if(! mPipe) + { + llwarns << "LLHTTPPipe::Response::status: NULL pipe" << llendl; + return; + } + + mPipe->mStatusCode = code; + mPipe->mStatusMessage = body; + mPipe->mHeaders = headers; + mPipe->mState = STATE_EXTENDED_RESULT; + mPipe->unlockChain(); +} + // virtual void LLHTTPPipe::Response::status(S32 code, const std::string& message) { @@ -409,6 +453,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( } ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n"; + S32 content_length = buffer->countAfter(channels.in(), NULL); if(0 < content_length) { diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h index fef3f9fc77..d1c9bdde85 100644 --- a/indra/llmessage/lliohttpserver.h +++ b/indra/llmessage/lliohttpserver.h @@ -40,6 +40,18 @@ class LLPumpIO; +// common strings use for populating the context. bascally 'request', +// 'wildcard', and 'headers'. +extern const std::string CONTEXT_REQUEST; +extern const std::string CONTEXT_RESPONSE; +extern const std::string CONTEXT_VERB; +extern const std::string CONTEXT_HEADERS; +extern const std::string HTTP_VERB_GET; +extern const std::string HTTP_VERB_PUT; +extern const std::string HTTP_VERB_POST; +extern const std::string HTTP_VERB_DELETE; +extern const std::string HTTP_VERB_OPTIONS; + class LLIOHTTPServer { public: diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp index dcce00c138..3f07147ebc 100644 --- a/indra/llmessage/llservicebuilder.cpp +++ b/indra/llmessage/llservicebuilder.cpp @@ -86,6 +86,14 @@ void LLServiceBuilder::createServiceDefinition( } } +static +bool starts_with(const std::string& text, const char* prefix) +{ + return text.substr(0, strlen(prefix)) == prefix; +} + +// TODO: Build a real services.xml for windows development. +// and remove the base_url logic below. std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) { std::ostringstream service_url; @@ -96,7 +104,19 @@ std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) LLApp* app = LLApp::instance(); if(app) { - LLSD base_url = app->getOption("services-base-url"); + // We define a base-url for some development configurations + // In production neither of these are defined and all services have full urls + LLSD base_url; + + if (starts_with(service_name,"cap")) + { + base_url = app->getOption("cap-base-url"); + } + + if (base_url.asString().empty()) + { + base_url = app->getOption("services-base-url"); + } service_url << base_url.asString(); } service_url << mServiceMap[service_name]; |