diff options
Diffstat (limited to 'indra/test/lliohttpserver_tut.cpp')
-rw-r--r-- | indra/test/lliohttpserver_tut.cpp | 608 |
1 files changed, 304 insertions, 304 deletions
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp index 1513446788..7034f4a063 100644 --- a/indra/test/lliohttpserver_tut.cpp +++ b/indra/test/lliohttpserver_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliohttpserver_tut.cpp * @date May 2006 * @brief HTTP server unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,313 +38,313 @@ namespace tut { - class HTTPServiceTestData - { - public: - class DelayedEcho : public LLHTTPNode - { - HTTPServiceTestData* mTester; - - public: - DelayedEcho(HTTPServiceTestData* tester) : mTester(tester) { } - - void post(ResponsePtr response, const LLSD& context, const LLSD& input) const - { - ensure("response already set", mTester->mResponse == ResponsePtr(NULL)); - mTester->mResponse = response; - mTester->mResult = input; - } - }; - - class WireHello : public LLIOPipe - { - protected: - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) - { - if(!eos) return STATUS_BREAK; - LLSD sd = "yo!"; - LLBufferStream ostr(channels, buffer.get()); - ostr << LLSDXMLStreamer(sd); - return STATUS_DONE; - } - }; - - HTTPServiceTestData() - : mResponse(NULL) - { - LLHTTPStandardServices::useServices(); - LLHTTPRegistrar::buildAllServices(mRoot); - mRoot.addNode("/delayed/echo", new DelayedEcho(this)); - mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>); - } - - ~HTTPServiceTestData() - { - } - - LLHTTPNode mRoot; - LLHTTPNode::ResponsePtr mResponse; - LLSD mResult; - - void pumpPipe(LLPumpIO* pump, S32 iterations) - { - while(iterations > 0) - { - pump->pump(); - pump->callback(); - --iterations; - } - } - - std::string makeRequest( - const std::string& name, - const std::string& httpRequest, - bool timeout = false) - { - LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest); - LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); - - apr_pool_t* pool; - apr_pool_create(&pool, NULL); - - LLPumpIO* pump; - pump = new LLPumpIO(pool); - - LLPumpIO::chain_t chain; - LLSD context; - - chain.push_back(LLIOPipe::ptr_t(injector)); - LLIOHTTPServer::createPipe(chain, mRoot, LLSD()); - chain.push_back(LLIOPipe::ptr_t(extractor)); - - pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); - - pumpPipe(pump, 10); - if(mResponse.notNull() && (! timeout)) - { - mResponse->result(mResult); - mResponse = NULL; - } - pumpPipe(pump, 10); - - std::string httpResult = extractor->string(); - - chain.clear(); - delete pump; - apr_pool_destroy(pool); - - if(mResponse.notNull() && timeout) - { - mResponse->result(mResult); - mResponse = NULL; - } - - return httpResult; - } - - std::string httpGET(const std::string& uri, - bool timeout = false) - { - std::string httpRequest = "GET " + uri + " HTTP/1.0\r\n\r\n"; - return makeRequest(uri, httpRequest, timeout); - } - - std::string httpPOST(const std::string& uri, - const std::string& body, - bool timeout, - const std::string& evilExtra = "") - { - std::ostringstream httpRequest; - httpRequest << "POST " + uri + " HTTP/1.0\r\n"; - httpRequest << "Content-Length: " << body.size() << "\r\n"; - httpRequest << "\r\n"; - httpRequest << body; - httpRequest << evilExtra; - - return makeRequest(uri, httpRequest.str(), timeout); - } - - std::string httpPOST(const std::string& uri, - const std::string& body, - const std::string& evilExtra = "") - { - bool timeout = false; - return httpPOST(uri, body, timeout, evilExtra); - } - }; - - typedef test_group<HTTPServiceTestData> HTTPServiceTestGroup; - typedef HTTPServiceTestGroup::object HTTPServiceTestObject; - HTTPServiceTestGroup httpServiceTestGroup("http service"); - - template<> template<> - void HTTPServiceTestObject::test<1>() - { - std::string result = httpGET("web/hello"); - - ensure_starts_with("web/hello status", result, - "HTTP/1.0 200 OK\r\n"); - - ensure_contains("web/hello content type", result, - "Content-Type: application/llsd+xml\r\n"); - - ensure_contains("web/hello content length", result, - "Content-Length: 36\r\n"); - - ensure_contains("web/hello content", result, - "\r\n" - "<llsd><string>hello</string></llsd>" - ); - } - - template<> template<> - void HTTPServiceTestObject::test<2>() - { - // test various HTTP errors - - std::string actual; - - actual = httpGET("web/missing"); - ensure_starts_with("web/missing 404", actual, - "HTTP/1.0 404 Not Found\r\n"); - - actual = httpGET("web/echo"); - ensure_starts_with("web/echo 405", actual, - "HTTP/1.0 405 Method Not Allowed\r\n"); - } - - template<> template<> - void HTTPServiceTestObject::test<3>() - { - // test POST & content-length handling - - std::string result; - - result = httpPOST("web/echo", - "<llsd><integer>42</integer></llsd>"); - - ensure_starts_with("web/echo status", result, - "HTTP/1.0 200 OK\r\n"); - - ensure_contains("web/echo content type", result, - "Content-Type: application/llsd+xml\r\n"); - - ensure_contains("web/echo content length", result, - "Content-Length: 35\r\n"); - - ensure_contains("web/hello content", result, - "\r\n" - "<llsd><integer>42</integer></llsd>" - ); + class HTTPServiceTestData + { + public: + class DelayedEcho : public LLHTTPNode + { + HTTPServiceTestData* mTester; + + public: + DelayedEcho(HTTPServiceTestData* tester) : mTester(tester) { } + + void post(ResponsePtr response, const LLSD& context, const LLSD& input) const + { + ensure("response already set", mTester->mResponse == ResponsePtr(NULL)); + mTester->mResponse = response; + mTester->mResult = input; + } + }; + + class WireHello : public LLIOPipe + { + protected: + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) + { + if(!eos) return STATUS_BREAK; + LLSD sd = "yo!"; + LLBufferStream ostr(channels, buffer.get()); + ostr << LLSDXMLStreamer(sd); + return STATUS_DONE; + } + }; + + HTTPServiceTestData() + : mResponse(NULL) + { + LLHTTPStandardServices::useServices(); + LLHTTPRegistrar::buildAllServices(mRoot); + mRoot.addNode("/delayed/echo", new DelayedEcho(this)); + mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>); + } + + ~HTTPServiceTestData() + { + } + + LLHTTPNode mRoot; + LLHTTPNode::ResponsePtr mResponse; + LLSD mResult; + + void pumpPipe(LLPumpIO* pump, S32 iterations) + { + while(iterations > 0) + { + pump->pump(); + pump->callback(); + --iterations; + } + } + + std::string makeRequest( + const std::string& name, + const std::string& httpRequest, + bool timeout = false) + { + LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest); + LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); + + apr_pool_t* pool; + apr_pool_create(&pool, NULL); + + LLPumpIO* pump; + pump = new LLPumpIO(pool); + + LLPumpIO::chain_t chain; + LLSD context; + + chain.push_back(LLIOPipe::ptr_t(injector)); + LLIOHTTPServer::createPipe(chain, mRoot, LLSD()); + chain.push_back(LLIOPipe::ptr_t(extractor)); + + pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); + + pumpPipe(pump, 10); + if(mResponse.notNull() && (! timeout)) + { + mResponse->result(mResult); + mResponse = NULL; + } + pumpPipe(pump, 10); + + std::string httpResult = extractor->string(); + + chain.clear(); + delete pump; + apr_pool_destroy(pool); + + if(mResponse.notNull() && timeout) + { + mResponse->result(mResult); + mResponse = NULL; + } + + return httpResult; + } + + std::string httpGET(const std::string& uri, + bool timeout = false) + { + std::string httpRequest = "GET " + uri + " HTTP/1.0\r\n\r\n"; + return makeRequest(uri, httpRequest, timeout); + } + + std::string httpPOST(const std::string& uri, + const std::string& body, + bool timeout, + const std::string& evilExtra = "") + { + std::ostringstream httpRequest; + httpRequest << "POST " + uri + " HTTP/1.0\r\n"; + httpRequest << "Content-Length: " << body.size() << "\r\n"; + httpRequest << "\r\n"; + httpRequest << body; + httpRequest << evilExtra; + + return makeRequest(uri, httpRequest.str(), timeout); + } + + std::string httpPOST(const std::string& uri, + const std::string& body, + const std::string& evilExtra = "") + { + bool timeout = false; + return httpPOST(uri, body, timeout, evilExtra); + } + }; + + typedef test_group<HTTPServiceTestData> HTTPServiceTestGroup; + typedef HTTPServiceTestGroup::object HTTPServiceTestObject; + HTTPServiceTestGroup httpServiceTestGroup("http service"); + + template<> template<> + void HTTPServiceTestObject::test<1>() + { + std::string result = httpGET("web/hello"); + + ensure_starts_with("web/hello status", result, + "HTTP/1.0 200 OK\r\n"); + + ensure_contains("web/hello content type", result, + "Content-Type: application/llsd+xml\r\n"); + + ensure_contains("web/hello content length", result, + "Content-Length: 36\r\n"); + + ensure_contains("web/hello content", result, + "\r\n" + "<llsd><string>hello</string></llsd>" + ); + } + + template<> template<> + void HTTPServiceTestObject::test<2>() + { + // test various HTTP errors + + std::string actual; + + actual = httpGET("web/missing"); + ensure_starts_with("web/missing 404", actual, + "HTTP/1.0 404 Not Found\r\n"); + + actual = httpGET("web/echo"); + ensure_starts_with("web/echo 405", actual, + "HTTP/1.0 405 Method Not Allowed\r\n"); + } + + template<> template<> + void HTTPServiceTestObject::test<3>() + { + // test POST & content-length handling + + std::string result; + + result = httpPOST("web/echo", + "<llsd><integer>42</integer></llsd>"); + + ensure_starts_with("web/echo status", result, + "HTTP/1.0 200 OK\r\n"); + + ensure_contains("web/echo content type", result, + "Content-Type: application/llsd+xml\r\n"); + + ensure_contains("web/echo content length", result, + "Content-Length: 35\r\n"); + + ensure_contains("web/hello content", result, + "\r\n" + "<llsd><integer>42</integer></llsd>" + ); /* TO DO: this test doesn't pass!! - - result = httpPOST("web/echo", - "<llsd><string>evil</string></llsd>", - "really! evil!!!"); - - ensure_equals("web/echo evil result", result, - "HTTP/1.0 200 OK\r\n" - "Content-Length: 34\r\n" - "\r\n" - "<llsd><string>evil</string></llsd>" - ); + + result = httpPOST("web/echo", + "<llsd><string>evil</string></llsd>", + "really! evil!!!"); + + ensure_equals("web/echo evil result", result, + "HTTP/1.0 200 OK\r\n" + "Content-Length: 34\r\n" + "\r\n" + "<llsd><string>evil</string></llsd>" + ); */ - } + } + + template<> template<> + void HTTPServiceTestObject::test<4>() + { + // test calling things based on pipes + + std::string result; + + result = httpGET("wire/hello"); - template<> template<> - void HTTPServiceTestObject::test<4>() - { - // test calling things based on pipes + ensure_contains("wire/hello", result, "yo!"); + } - std::string result; + template<> template<> + void HTTPServiceTestObject::test<5>() + { + // test timeout before async response + std::string result; + + bool timeout = true; + result = httpPOST("delayed/echo", + "<llsd><string>agent99</string></llsd>", timeout); - result = httpGET("wire/hello"); + ensure_equals("timeout delayed/echo status", result, std::string("")); + } + + template<> template<> + void HTTPServiceTestObject::test<6>() + { + // test delayed service + std::string result; - ensure_contains("wire/hello", result, "yo!"); - } + result = httpPOST("delayed/echo", + "<llsd><string>agent99</string></llsd>"); + + ensure_starts_with("delayed/echo status", result, + "HTTP/1.0 200 OK\r\n"); + + ensure_contains("delayed/echo content", result, + "\r\n" + "<llsd><string>agent99</string></llsd>" + ); + } + + template<> template<> + void HTTPServiceTestObject::test<7>() + { + // test large request + std::stringstream stream; + + //U32 size = 36 * 1024 * 1024; + //U32 size = 36 * 1024; + //std::vector<char> data(size); + //memset(&(data[0]), '1', size); + //data[size - 1] = '\0'; + + + //std::string result = httpPOST("web/echo", &(data[0])); + + stream << "<llsd><array>"; + for(U32 i = 0; i < 1000000; ++i) + { + stream << "<integer>42</integer>"; + } + stream << "</array></llsd>"; + LL_INFOS() << "HTTPServiceTestObject::test<7>" + << stream.str().length() << LL_ENDL; + std::string result = httpPOST("web/echo", stream.str()); + ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n"); + } template<> template<> - void HTTPServiceTestObject::test<5>() + void HTTPServiceTestObject::test<8>() { - // test timeout before async response - std::string result; - - bool timeout = true; - result = httpPOST("delayed/echo", - "<llsd><string>agent99</string></llsd>", timeout); - - ensure_equals("timeout delayed/echo status", result, std::string("")); - } - - template<> template<> - void HTTPServiceTestObject::test<6>() - { - // test delayed service - std::string result; - - result = httpPOST("delayed/echo", - "<llsd><string>agent99</string></llsd>"); - - ensure_starts_with("delayed/echo status", result, - "HTTP/1.0 200 OK\r\n"); - - ensure_contains("delayed/echo content", result, - "\r\n" - "<llsd><string>agent99</string></llsd>" - ); - } - - template<> template<> - void HTTPServiceTestObject::test<7>() - { - // test large request - std::stringstream stream; - - //U32 size = 36 * 1024 * 1024; - //U32 size = 36 * 1024; - //std::vector<char> data(size); - //memset(&(data[0]), '1', size); - //data[size - 1] = '\0'; - - - //std::string result = httpPOST("web/echo", &(data[0])); - - stream << "<llsd><array>"; - for(U32 i = 0; i < 1000000; ++i) - { - stream << "<integer>42</integer>"; - } - stream << "</array></llsd>"; - LL_INFOS() << "HTTPServiceTestObject::test<7>" - << stream.str().length() << LL_ENDL; - std::string result = httpPOST("web/echo", stream.str()); - ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n"); - } - - template<> template<> - void HTTPServiceTestObject::test<8>() - { - // test the OPTIONS http method -- the default implementation - // should return the X-Documentation-URL - std::ostringstream http_request; - http_request << "OPTIONS / HTTP/1.0\r\nHost: localhost\r\n\r\n"; - bool timeout = false; - std::string result = makeRequest("/", http_request.str(), timeout); - ensure_starts_with("OPTIONS verb ok", result, "HTTP/1.0 200 OK\r\n"); - ensure_contains( - "Doc url header exists", - result, - "X-Documentation-URL: http://localhost"); - } - - - /* TO DO: - test generation of not found and method not allowed errors - */ + // test the OPTIONS http method -- the default implementation + // should return the X-Documentation-URL + std::ostringstream http_request; + http_request << "OPTIONS / HTTP/1.0\r\nHost: localhost\r\n\r\n"; + bool timeout = false; + std::string result = makeRequest("/", http_request.str(), timeout); + ensure_starts_with("OPTIONS verb ok", result, "HTTP/1.0 200 OK\r\n"); + ensure_contains( + "Doc url header exists", + result, + "X-Documentation-URL: http://localhost"); + } + + + /* TO DO: + test generation of not found and method not allowed errors + */ } |