summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llhttpnode.cpp10
-rw-r--r--indra/llmessage/llhttpnode.h15
-rw-r--r--indra/llmessage/lliohttpserver.cpp71
-rw-r--r--indra/llmessage/lliohttpserver.h12
-rw-r--r--indra/llmessage/llservicebuilder.cpp22
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];