aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llmessage/llhttpclient.cpp22
-rw-r--r--linden/indra/llmessage/llhttpclient.h3
-rw-r--r--linden/indra/llxml/llxmlnode.cpp8
-rw-r--r--linden/indra/llxml/llxmlnode.h4
-rw-r--r--linden/indra/llxml/llxmlparser.cpp2
-rw-r--r--linden/indra/llxml/llxmlparser.h2
-rw-r--r--linden/indra/llxml/llxmltree.cpp119
-rw-r--r--linden/indra/llxml/llxmltree.h19
-rw-r--r--linden/indra/newview/hippoGridManager.cpp5
-rw-r--r--linden/indra/newview/hippoRestRequest.cpp298
-rw-r--r--linden/indra/newview/hippoRestRequest.h98
11 files changed, 551 insertions, 29 deletions
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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2006&license=viewergpl$ 5 * $LicenseInfo:firstyear=2006&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2006-2009, Linden Research, Inc. 7 * Copyright (c) 2006-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -161,10 +161,9 @@ namespace
161 fstream.seekg(0, std::ios::end); 161 fstream.seekg(0, std::ios::end);
162 U32 fileSize = fstream.tellg(); 162 U32 fileSize = fstream.tellg();
163 fstream.seekg(0, std::ios::beg); 163 fstream.seekg(0, std::ios::beg);
164 char* fileBuffer; 164 std::vector<char> fileBuffer(fileSize);
165 fileBuffer = new char [fileSize]; 165 fstream.read(&fileBuffer[0], fileSize);
166 fstream.read(fileBuffer, fileSize); 166 ostream.write(&fileBuffer[0], fileSize);
167 ostream.write(fileBuffer, fileSize);
168 fstream.close(); 167 fstream.close();
169 eos = true; 168 eos = true;
170 return STATUS_DONE; 169 return STATUS_DONE;
@@ -191,11 +190,9 @@ namespace
191 190
192 LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ); 191 LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
193 S32 fileSize = vfile.getSize(); 192 S32 fileSize = vfile.getSize();
194 U8* fileBuffer; 193 std::vector<U8> fileBuffer(fileSize);
195 fileBuffer = new U8 [fileSize]; 194 vfile.read(&fileBuffer[0], fileSize);
196 vfile.read(fileBuffer, fileSize); 195 ostream.write((char*)&fileBuffer[0], fileSize);
197 ostream.write((char*)fileBuffer, fileSize);
198 delete [] fileBuffer;
199 eos = true; 196 eos = true;
200 return STATUS_DONE; 197 return STATUS_DONE;
201 } 198 }
@@ -528,3 +525,8 @@ bool LLHTTPClient::hasPump()
528{ 525{
529 return theClientPump != NULL; 526 return theClientPump != NULL;
530} 527}
528
529LLPumpIO &LLHTTPClient::getPump()
530{
531 return *theClientPump;
532}
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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2006&license=viewergpl$ 5 * $LicenseInfo:firstyear=2006&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2006-2009, Linden Research, Inc. 7 * Copyright (c) 2006-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -148,6 +148,7 @@ public:
148 ///< must be called before any of the above calls are made 148 ///< must be called before any of the above calls are made
149 static bool hasPump(); 149 static bool hasPump();
150 ///< for testing 150 ///< for testing
151 static LLPumpIO &getPump();
151}; 152};
152 153
153#endif // LL_LLHTTPCLIENT_H 154#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 @@
5 * 5 *
6 * $LicenseInfo:firstyear=2005&license=viewergpl$ 6 * $LicenseInfo:firstyear=2005&license=viewergpl$
7 * 7 *
8 * Copyright (c) 2005-2009, Linden Research, Inc. 8 * Copyright (c) 2005-2010, Linden Research, Inc.
9 * 9 *
10 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 11 * 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
677 U32 length = ftell(fp); 677 U32 length = ftell(fp);
678 fseek(fp, 0, SEEK_SET); 678 fseek(fp, 0, SEEK_SET);
679 679
680 U8* buffer = new U8[length+1]; 680 char *buffer = new char[length+1];
681 size_t nread = fread(buffer, 1, length, fp); 681 size_t nread = fread(buffer, 1, length, fp);
682 buffer[nread] = 0; 682 buffer[nread] = 0;
683 fclose(fp); 683 fclose(fp);
@@ -689,7 +689,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML
689 689
690// static 690// static
691bool LLXMLNode::parseBuffer( 691bool LLXMLNode::parseBuffer(
692 U8* buffer, 692 const char *buffer,
693 U32 length, 693 U32 length,
694 LLXMLNodePtr& node, 694 LLXMLNodePtr& node,
695 LLXMLNode* defaults) 695 LLXMLNode* defaults)
@@ -708,7 +708,7 @@ bool LLXMLNode::parseBuffer(
708 XML_SetUserData(my_parser, (void *)file_node_ptr); 708 XML_SetUserData(my_parser, (void *)file_node_ptr);
709 709
710 // Do the parsing 710 // Do the parsing
711 if (XML_Parse(my_parser, (const char *)buffer, length, TRUE) != XML_STATUS_OK) 711 if (XML_Parse(my_parser, buffer, length, TRUE) != XML_STATUS_OK)
712 { 712 {
713 llwarns << "Error parsing xml error code: " 713 llwarns << "Error parsing xml error code: "
714 << XML_ErrorString(XML_GetErrorCode(my_parser)) 714 << 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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2000&license=viewergpl$ 5 * $LicenseInfo:firstyear=2000&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2000-2009, Linden Research, Inc. 7 * Copyright (c) 2000-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -141,7 +141,7 @@ public:
141 LLXMLNodePtr& node, 141 LLXMLNodePtr& node,
142 LLXMLNode* defaults_tree); 142 LLXMLNode* defaults_tree);
143 static bool parseBuffer( 143 static bool parseBuffer(
144 U8* buffer, 144 const char *buffer,
145 U32 length, 145 U32 length,
146 LLXMLNodePtr& node, 146 LLXMLNodePtr& node,
147 LLXMLNode* defaults); 147 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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc. 7 * Copyright (c) 2002-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * 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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc. 7 * Copyright (c) 2002-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * 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 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc. 7 * Copyright (c) 2002-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -50,6 +50,7 @@ LLStdStringTable LLXmlTree::sAttributeKeys(1024);
50 50
51LLXmlTree::LLXmlTree() 51LLXmlTree::LLXmlTree()
52 : mRoot( NULL ), 52 : mRoot( NULL ),
53 mParser(0),
53 mNodeNames(512) 54 mNodeNames(512)
54{ 55{
55} 56}
@@ -83,6 +84,39 @@ BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents)
83 return success; 84 return success;
84} 85}
85 86
87bool LLXmlTree::parseBufferStart(bool keep_contents)
88{
89 if (mRoot) delete mRoot;
90 mRoot = NULL;
91
92 if (mParser) delete mParser;
93 mParser = new LLXmlTreeParser(this);
94 mParser->parseBufferStart(keep_contents);
95 return (mParser != 0);
96}
97
98bool LLXmlTree::parseBuffer(const char *buf, int len)
99{
100 bool success = mParser->parseBuffer(buf, len);
101 if (!success) {
102 S32 line_number = mParser->getCurrentLineNumber();
103 const char* error = mParser->getErrorString();
104 llwarns << "LLXmlTree parse failed in line " << line_number << ": " << error << llendl;
105 delete mParser;
106 mParser = 0;
107 }
108 return success;
109}
110
111bool LLXmlTree::parseBufferFinalize()
112{
113 bool success = mParser->parseBufferFinalize(&mRoot);
114 delete mParser;
115 mParser = 0;
116 return success;
117}
118
119
86void LLXmlTree::dump() 120void LLXmlTree::dump()
87{ 121{
88 if( mRoot ) 122 if( mRoot )
@@ -102,6 +136,25 @@ void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix )
102 } 136 }
103} 137}
104 138
139void LLXmlTree::write(std::string &buffer) const
140{
141 if (mRoot) writeNode(mRoot, buffer, "");
142}
143
144void LLXmlTree::writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const
145{
146 if (!node->getFirstChild()) {
147 node->writeNoChild(buffer, indent);
148 } else {
149 node->writeStart(buffer, indent);
150 std::string newIndent = indent + " ";
151 for (LLXmlTreeNode *child=node->getFirstChild(); child; child=node->getNextChild())
152 writeNode(child, buffer, newIndent);
153 node->writeEnd(buffer, indent);
154 }
155}
156
157
105////////////////////////////////////////////////////////////// 158//////////////////////////////////////////////////////////////
106// LLXmlTreeNode 159// LLXmlTreeNode
107 160
@@ -139,6 +192,43 @@ void LLXmlTreeNode::dump( const std::string& prefix )
139 llcont << llendl; 192 llcont << llendl;
140} 193}
141 194
195void LLXmlTreeNode::writeNoChild(std::string &buffer, const std::string &indent) const
196{
197 if (!mContents.empty()) {
198 writeStart(buffer, indent);
199 writeEnd(buffer, indent);
200 } else {
201 buffer += indent + '<' + mName;
202 writeAttributes(buffer);
203 buffer += "/>\n";
204 }
205}
206
207void LLXmlTreeNode::writeStart(std::string &buffer, const std::string &indent) const
208{
209 buffer += indent + '<' + mName;
210 writeAttributes(buffer);
211 buffer += ">\n";
212}
213
214void LLXmlTreeNode::writeEnd(std::string &buffer, const std::string &indent) const
215{
216 if (!mContents.empty()) {
217 buffer += indent + " " + mContents + '\n';
218 }
219 buffer += indent + "</" + mName + ">\n";
220}
221
222void LLXmlTreeNode::writeAttributes(std::string &buffer) const
223{
224 attribute_map_t::const_iterator it, end = mAttributes.end();
225 for (it=mAttributes.begin(); it!=end; ++it) {
226 LLStdStringHandle key = it->first;
227 const std::string *value = it->second;
228 buffer += ' ' + *key + "=\"" + *value + '"';
229 }
230}
231
142BOOL LLXmlTreeNode::hasAttribute(const std::string& name) 232BOOL LLXmlTreeNode::hasAttribute(const std::string& name)
143{ 233{
144 LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); 234 LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
@@ -527,7 +617,7 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B
527 617
528 BOOL success = LLXmlParser::parseFile(path); 618 BOOL success = LLXmlParser::parseFile(path);
529 619
530 *root = mRoot; 620 if (root) *root = mRoot;
531 mRoot = NULL; 621 mRoot = NULL;
532 622
533 if( success ) 623 if( success )
@@ -539,6 +629,31 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B
539 return success; 629 return success;
540} 630}
541 631
632void LLXmlTreeParser::parseBufferStart(BOOL keep_contents)
633{
634 llassert(!mRoot);
635 llassert(!mCurrent);
636 mKeepContents = keep_contents;
637}
638
639bool LLXmlTreeParser::parseBuffer(const char *buf, int len)
640{
641 return (LLXmlParser::parse(buf, len, false) != 0);
642}
643
644bool LLXmlTreeParser::parseBufferFinalize(LLXmlTreeNode** root)
645{
646 bool success = (LLXmlParser::parse(0, 0, true) != 0);
647
648 if (root) *root = mRoot;
649 mRoot = NULL;
650
651 llassert(!success || !mCurrent);
652 mCurrent = NULL;
653
654 return success;
655}
656
542 657
543const std::string& LLXmlTreeParser::tabs() 658const std::string& LLXmlTreeParser::tabs()
544{ 659{
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 @@
5 * 5 *
6 * $LicenseInfo:firstyear=2001&license=viewergpl$ 6 * $LicenseInfo:firstyear=2001&license=viewergpl$
7 * 7 *
8 * Copyright (c) 2001-2009, Linden Research, Inc. 8 * Copyright (c) 2001-2010, Linden Research, Inc.
9 * 9 *
10 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 11 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -63,11 +63,18 @@ public:
63 63
64 virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE); 64 virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE);
65 65
66 bool parseBufferStart(bool keep_contents = true);
67 bool parseBuffer(const char *buf, int len);
68 bool parseBufferFinalize();
69
66 LLXmlTreeNode* getRoot() { return mRoot; } 70 LLXmlTreeNode* getRoot() { return mRoot; }
67 71
68 void dump(); 72 void dump();
69 void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); 73 void dumpNode( LLXmlTreeNode* node, const std::string& prefix );
70 74
75 void write(std::string &buffer) const;
76 void writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const;
77
71 static LLStdStringHandle addAttributeString( const std::string& name) 78 static LLStdStringHandle addAttributeString( const std::string& name)
72 { 79 {
73 return sAttributeKeys.addString( name ); 80 return sAttributeKeys.addString( name );
@@ -79,6 +86,7 @@ public:
79 86
80protected: 87protected:
81 LLXmlTreeNode* mRoot; 88 LLXmlTreeNode* mRoot;
89 LLXmlTreeParser *mParser;
82 90
83 // local 91 // local
84 LLStdStringTable mNodeNames; 92 LLStdStringTable mNodeNames;
@@ -175,6 +183,11 @@ private:
175 183
176 void dump( const std::string& prefix ); 184 void dump( const std::string& prefix );
177 185
186 void writeNoChild(std::string &buffer, const std::string &indent) const;
187 void writeStart(std::string &buffer, const std::string &indent) const;
188 void writeEnd(std::string &buffer, const std::string &indent) const;
189 void writeAttributes(std::string &buffer) const;
190
178protected: 191protected:
179 typedef std::map<LLStdStringHandle, const std::string*> attribute_map_t; 192 typedef std::map<LLStdStringHandle, const std::string*> attribute_map_t;
180 attribute_map_t mAttributes; 193 attribute_map_t mAttributes;
@@ -207,6 +220,10 @@ public:
207 220
208 BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents ); 221 BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents );
209 222
223 void parseBufferStart(BOOL keep_contents);
224 bool parseBuffer(const char *buf, int len);
225 bool parseBufferFinalize(LLXmlTreeNode** root);
226
210protected: 227protected:
211 const std::string& tabs(); 228 const std::string& tabs();
212 229
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
160void HippoGridInfo::setPlatform(Platform platform) 160void HippoGridInfo::setPlatform(Platform platform)
161{ 161{
162 mPlatform = platform; 162 mPlatform = platform;
163 mCurrencySymbol = (mPlatform == PLATFORM_SECONDLIFE)? "L$": "OS$"; 163 if (mPlatform == PLATFORM_SECONDLIFE)
164 {
165 mCurrencySymbol = "L$";
166 }
164} 167}
165 168
166 169
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 @@
10#include <curl/curl.h> 10#include <curl/curl.h>
11 11
12#include <stdtypes.h> 12#include <stdtypes.h>
13#include <llbufferstream.h>
13#include <llerror.h> 14#include <llerror.h>
15#include <llhttpclient.h>
16#include <llurlrequest.h>
17#include <llxmltree.h>
18
19
20// ********************************************************************
21
22
23class HippoRestComplete : public LLURLRequestComplete
24{
25 public:
26 HippoRestComplete(HippoRestHandler *handler) :
27 mHandler(handler),
28 mStatus(499),
29 mReason("Request completed w/o status")
30 {
31 }
32
33 ~HippoRestComplete()
34 {
35 delete mHandler;
36 }
37
38 // Called once for each header received, prior to httpStatus
39 void header(const std::string& header, const std::string& value)
40 {
41 mHandler->addHeader(header, value);
42 }
43
44 // Always called on request completion, prior to complete
45 void httpStatus(U32 status, const std::string& reason)
46 {
47 LLURLRequestComplete::httpStatus(status, reason);
48 mStatus = status;
49 mReason = reason;
50 }
51
52 void complete(const LLChannelDescriptors &channels, const buffer_ptr_t &buffer)
53 {
54 mHandler->handle(mStatus, mReason, channels, buffer);
55 }
56
57 private:
58 HippoRestHandler *mHandler;
59 int mStatus;
60 std::string mReason;
61};
62
63
64// ********************************************************************
65
66
67static std::string gEmptyString;
68
69void HippoRestHandler::addHeader(const std::string &header, const std::string &content)
70{
71 mHeaders[header] = content;
72}
73
74bool HippoRestHandler::hasHeader(const std::string &header) const
75{
76 return (mHeaders.find(header) != mHeaders.end());
77}
78
79const std::string &HippoRestHandler::getHeader(const std::string &header) const
80{
81 std::map<std::string, std::string>::const_iterator it;
82 it = mHeaders.find(header);
83 if (it != mHeaders.end()) {
84 return it->second;
85 } else {
86 return gEmptyString;
87 }
88}
89
90
91// ********************************************************************
92
93
94void HippoRestHandlerRaw::handle(int status, const std::string &reason,
95 const LLChannelDescriptors &channels,
96 const boost::shared_ptr<LLBufferArray> &body)
97{
98 if (status == 200) {
99 std::string data;
100 LLBufferArray *buffer = body.get();
101 LLBufferArray::segment_iterator_t it, end = buffer->endSegment();
102 for (it=buffer->beginSegment(); it!=end; ++it)
103 if (it->isOnChannel(channels.in()))
104 data.append((char*)it->data(), it->size());
105 result(data);
106 } else {
107 llwarns << "Rest request error " << status << ": " << reason << llendl;
108 }
109}
110
111void HippoRestHandlerXml::handle(int status, const std::string &reason,
112 const LLChannelDescriptors &channels,
113 const boost::shared_ptr<LLBufferArray> &body)
114{
115 if (status == 200) {
116 LLXmlTree *tree = new LLXmlTree();
117 bool success = tree->parseBufferStart();
118 LLBufferArray *buffer = body.get();
119 LLBufferArray::segment_iterator_t it, end = buffer->endSegment();
120 for (it=buffer->beginSegment(); success && (it!=end); ++it)
121 if (it->isOnChannel(channels.in()))
122 success = success && tree->parseBuffer((char*)it->data(), it->size());
123 success = success && tree->parseBufferFinalize();
124 if (success) result(tree);
125 delete tree;
126 } else {
127 llwarns << "Rest request error " << status << ": " << reason << llendl;
128 }
129}
130
131
132// ********************************************************************
133
134
135class BodyData : public LLIOPipe
136{
137 public:
138 virtual ~BodyData() { }
139 virtual const char *getContentMimeType() const = 0;
140};
141
142class BodyDataRaw : public BodyData
143{
144 public:
145 explicit BodyDataRaw(const std::string &data) :
146 mData(data)
147 {
148 }
149 virtual ~BodyDataRaw() { }
150
151 const char *getContentMimeType() const { return "application/octet-stream"; }
152
153 EStatus process_impl(const LLChannelDescriptors &channels,
154 buffer_ptr_t &buffer, bool &eos,
155 LLSD &context, LLPumpIO *pump)
156 {
157 LLBufferStream ostream(channels, buffer.get());
158 ostream.write(mData.data(), mData.size());
159 eos = true;
160 return STATUS_DONE;
161 }
162
163 private:
164 std::string mData;
165};
166
167class BodyDataXml : public BodyData
168{
169 public:
170 explicit BodyDataXml(const LLXmlTree *tree) :
171 mTree(tree)
172 {
173 }
174
175 virtual ~BodyDataXml()
176 {
177 if (mTree) delete mTree;
178 }
179
180 const char *getContentMimeType() const { return "application/xml"; }
181
182 EStatus process_impl(const LLChannelDescriptors &channels,
183 buffer_ptr_t &buffer, bool &eos,
184 LLSD &context, LLPumpIO *pump)
185 {
186 std::string data;
187 mTree->write(data);
188 LLBufferStream ostream(channels, buffer.get());
189 ostream.write(data.data(), data.size());
190 eos = true;
191 return STATUS_DONE;
192 }
193
194 private:
195 const LLXmlTree *mTree;
196};
197
198
199// ********************************************************************
200
201
202static void request(const std::string &url,
203 LLURLRequest::ERequestAction method,
204 BodyData *body,
205 HippoRestHandler *handler, float timeout);
206
207
208// static
209void HippoRestRequest::get(const std::string &url,
210 HippoRestHandler *handler, float timeout)
211{
212 request(url, LLURLRequest::HTTP_GET, 0, handler, timeout);
213}
214
215// static
216void HippoRestRequest::put(const std::string &url, const std::string &body,
217 HippoRestHandler *handler, float timeout)
218{
219 request(url, LLURLRequest::HTTP_PUT, new BodyDataRaw(body), handler, timeout);
220}
221
222// static
223void HippoRestRequest::put(const std::string &url, const LLXmlTree *body,
224 HippoRestHandler *handler, float timeout)
225{
226 request(url, LLURLRequest::HTTP_PUT, new BodyDataXml(body), handler, timeout);
227}
228
229// static
230void HippoRestRequest::post(const std::string &url, const std::string &body,
231 HippoRestHandler *handler, float timeout)
232{
233 request(url, LLURLRequest::HTTP_POST, new BodyDataRaw(body), handler, timeout);
234}
235
236// static
237void HippoRestRequest::post(const std::string &url, const LLXmlTree *body,
238 HippoRestHandler *handler, float timeout)
239{
240 request(url, LLURLRequest::HTTP_POST, new BodyDataXml(body), handler, timeout);
241}
242
243
244// ********************************************************************
245
246
247static void request(const std::string &url,
248 LLURLRequest::ERequestAction method,
249 BodyData *body,
250 HippoRestHandler *handler, float timeout)
251{
252 if (!LLHTTPClient::hasPump())
253 {
254 // !!! responder->completed(U32_MAX, "No pump", LLSD());
255 return;
256 }
257 LLPumpIO::chain_t chain;
258
259 LLURLRequest *req = new LLURLRequest(method, url);
260 req->checkRootCertificate(true);
261
262 /*
263 // Insert custom headers if the caller sent any
264 if (headers.isMap())
265 {
266 LLSD::map_const_iterator iter = headers.beginMap();
267 LLSD::map_const_iterator end = headers.endMap();
268
269 for (; iter != end; ++iter)
270 {
271 std::ostringstream header;
272 //if the header is "Pragma" with no value
273 //the caller intends to force libcurl to drop
274 //the Pragma header it so gratuitously inserts
275 //Before inserting the header, force libcurl
276 //to not use the proxy (read: llurlrequest.cpp)
277 static const std::string PRAGMA("Pragma");
278 if ((iter->first == PRAGMA) && (iter->second.asString().empty()))
279 {
280 req->useProxy(false);
281 }
282 header << iter->first << ": " << iter->second.asString() ;
283 lldebugs << "header = " << header.str() << llendl;
284 req->addHeader(header.str().c_str());
285 }
286 }
287 */
288
289 if ((method != LLURLRequest::HTTP_PUT) && (method != LLURLRequest::HTTP_POST)) {
290 std::string accept = "Accept: ";
291 accept += handler->getAcceptMimeType();
292 req->addHeader(accept.c_str());
293 }
294
295 req->setCallback(new HippoRestComplete(handler));
296
297 if ((method == LLURLRequest::HTTP_PUT) || (method == LLURLRequest::HTTP_POST)) {
298 std::string content = "Content-Type: ";
299 content += body->getContentMimeType();
300 req->addHeader(content.c_str());
301 chain.push_back(LLIOPipe::ptr_t(body));
302 }
303
304 chain.push_back(LLIOPipe::ptr_t(req));
305 LLHTTPClient::getPump().addChain(chain, timeout);
306}
307
308
309// ********************************************************************
14 310
15 311
16static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) 312static 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)
22} 318}
23 319
24 320
25//static 321// static
26int HippoRestRequest::getBlocking(const std::string &url, std::string *result) 322int HippoRestRequest::getBlocking(const std::string &url, std::string *result)
27{ 323{
28 llinfos << "Requesting: " << url << llendl; 324 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 @@
1#ifndef __HIPPO_REST_REQTUEST_H__ 1#ifndef __HIPPO_REST_REQUEST_H__
2#define __HIPPO_REST_REQTUEST_H__ 2#define __HIPPO_REST_REQUEST_H__
3 3
4 4
5#include <map>
5#include <string> 6#include <string>
6 7
8#include <boost/shared_ptr.hpp>
9
10class LLBufferArray;
11class LLChannelDescriptors;
12class LLXmlTree;
13
14
15#define HIPPO_REST_TIMEOUT 60.f
16
17
18// ********************************************************************
19
20
21class HippoRestHandler
22{
23 public:
24 virtual ~HippoRestHandler() { }
25
26 virtual const char *getAcceptMimeType() const = 0;
27
28 bool hasHeader(const std::string &header) const;
29 const std::string &getHeader(const std::string &header) const;
30
31 private:
32 // These functions are called by the request engine
33 void addHeader(const std::string &header, const std::string &content);
34 virtual void handle(int status, const std::string &reason,
35 const LLChannelDescriptors &channels,
36 const boost::shared_ptr<LLBufferArray> &body) = 0;
37
38 std::map<std::string, std::string> mHeaders;
39
40 friend class HippoRestComplete;
41};
42
43
44class HippoRestHandlerRaw : public HippoRestHandler
45{
46 public:
47 virtual ~HippoRestHandlerRaw() { }
48
49 const char *getAcceptMimeType() const { return "application/octet-stream"; }
50
51 private:
52 // This function must be implemented to receive the content
53 // it is executed on (status == 200) only
54 virtual void result(const std::string &content) = 0;
55
56 // This function is called by the request engine
57 void handle(int status, const std::string &reason,
58 const LLChannelDescriptors &channels,
59 const boost::shared_ptr<LLBufferArray> &body);
60};
61
62
63class HippoRestHandlerXml : public HippoRestHandler
64{
65 public:
66 virtual ~HippoRestHandlerXml() { }
67
68 const char *getAcceptMimeType() const { return "application/xml"; }
69
70 private:
71 // This function must be implemented to receive the content
72 virtual void result(LLXmlTree *content) = 0;
73
74 // This function is called by the request engine
75 void handle(int status, const std::string &reason,
76 const LLChannelDescriptors &channels,
77 const boost::shared_ptr<LLBufferArray> &body);
78};
79
80
81// ********************************************************************
82
7 83
8class HippoRestRequest 84class HippoRestRequest
9{ 85{
10 public: 86 public:
11 static int getBlocking(const std::string &url, std::string *result); 87 // asynchronous interface
12 88 static void get(const std::string &url,
89 HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
90 static void put(const std::string &url, const std::string &body,
91 HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
92 static void put(const std::string &url, const LLXmlTree *body,
93 HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
94 static void post(const std::string &url, const std::string &body,
95 HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
96 static void post(const std::string &url, const LLXmlTree *body,
97 HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
98
99 // synchronous interface
100 static int getBlocking(const std::string &url, std::string *result);
13}; 101};
14 102
15 103