diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index b2bf549ab..1764a857a 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -231,7 +231,7 @@ void LLHTTPClient::getByteRange(std::string const& url, S32 offset, S32 bytes, R request(url, LLURLRequest::HTTP_GET, NULL, responder, headers); } -void LLHTTPClient::head(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers) { request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers); } @@ -241,7 +241,7 @@ void LLHTTPClient::get(std::string const& url, ResponderPtr responder, AIHTTPHea request(url, LLURLRequest::HTTP_GET, NULL, responder, headers); } -void LLHTTPClient::getHeaderOnly(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers) +void LLHTTPClient::getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers) { request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers); } diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index fa37e8b62..3e491de82 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -183,6 +183,39 @@ public: // This function must delete the ResponderBase object when the reference count reaches zero. }; + // Responders derived from this base class should use HTTPClient::head or HTTPClient::getHeaderOnly. + // That will set the curl option CURLOPT_NOBODY so that only headers are received. + class ResponderHeadersOnly : public ResponderBase { + private: + /*virtual*/ bool needsHeaders(void) const { return true; } + + protected: + // ResponderBase event + + // The responder finished. Do not override this function in derived classes; override completedRaw instead. + /*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) + { + mCode = code; + // Allow classes derived from ResponderHeadersOnly to override completedHeaders. + completedHeaders(http_status, reason, mReceivedHeaders); + mFinished = true; + } + + protected: +#ifdef SHOW_ASSERT + // Responders derived from this class must override completedHeaders. + // They may not attempt to override any of the virual functions defined by ResponderBase. + // Define those functions here with different parameters in order to cause a compile + // warning when a class accidently tries to override them. + enum YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS { }; + virtual void completedRaw(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void completed(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void result(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void errorWithContent(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } + virtual void error(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { } +#endif + }; + /** * @class ResponderWithCompleted * @brief Base class for Responders that implement completed, or completedRaw if the response is not LLSD. @@ -195,8 +228,8 @@ public: /*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { mCode = code; - // Allow classes derived from ResponderBase to override completedRaw - // (if not they should override completed or be derived from Responder instead). + // Allow classes derived from ResponderWithCompleted to override completedRaw + // (if not they should override completed or be derived from ResponderWithResult instead). completedRaw(http_status, reason, channels, buffer); mFinished = true; } @@ -324,8 +357,8 @@ public: /** @name non-blocking API */ //@{ - static void head(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers); - static void head(std::string const& url, ResponderPtr responder) + static void head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers); + static void head(std::string const& url, ResponderHeadersOnly* responder) { AIHTTPHeaders headers; head(url, responder, headers); } static void getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder, AIHTTPHeaders& headers); @@ -344,8 +377,8 @@ public: static void put(std::string const& url, LLSD const& body, ResponderPtr responder) { AIHTTPHeaders headers; put(url, body, responder, headers); } - static void getHeaderOnly(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers); - static void getHeaderOnly(std::string const& url, ResponderPtr responder) + static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers); + static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder) { AIHTTPHeaders headers; getHeaderOnly(url, responder, headers); } static void post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers); diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index e6b4ee4c3..927b64b7a 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -212,7 +212,6 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) switch(mAction) { case HTTP_HEAD: - curlEasyRequest_w->setopt(CURLOPT_HEADER, 1); curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1); curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index d8d4f5e84..60d6ad963 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -53,7 +53,7 @@ static LLFloaterURLEntry* sInstance = NULL; // Move this to its own file. // helper class that tries to download a URL from a web site and calls a method // on the Panel Land Media and to discover the MIME type -class LLMediaTypeResponder : public LLHTTPClient::ResponderIgnoreBody +class LLMediaTypeResponder : public LLHTTPClient::ResponderHeadersOnly { public: LLMediaTypeResponder( const LLHandle parent ) : @@ -62,20 +62,20 @@ public: LLHandle mParent; - virtual bool needsHeaders(void) const { return true; } - virtual void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - std::string media_type; - bool content_type_found = headers.getFirstValue("content-type", media_type); - llassert_always(content_type_found); - std::string::size_type idx1 = media_type.find_first_of(";"); - std::string mime_type = media_type.substr(0, idx1); - completeAny(status, mime_type); - } - - virtual void error( U32 status, const std::string& reason ) - { + if (200 <= status && status < 300) + { + std::string media_type; + if (headers.getFirstValue("content-type", media_type)) + { + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + return; + } + llwarns << "LLMediaTypeResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + } completeAny(status, "none/none"); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index cc20ab576..019ddd668 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -168,7 +168,7 @@ std::string gFullName; // helper class that trys to download a URL from a web site and calls a method // on parent class indicating if the web server is working or not -class LLIamHereLogin : public LLHTTPClient::ResponderWithCompleted +class LLIamHereLogin : public LLHTTPClient::ResponderHeadersOnly { private: LLIamHereLogin( LLPanelLogin* parent ) : @@ -188,10 +188,7 @@ class LLIamHereLogin : public LLHTTPClient::ResponderWithCompleted mParent = parentIn; }; - // We don't actually expect LLSD back, so need to override completedRaw - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { if (mParent) { @@ -887,7 +884,7 @@ void LLPanelLogin::refreshLoginPage() std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage(); if (!login_page.empty()) { - LLHTTPClient::head(login_page, gResponsePtr); + LLHTTPClient::head(login_page, gResponsePtr.get()); } else { sInstance->setSiteIsAlive(false); } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index bc7c88e2b..94b05c958 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -71,7 +71,7 @@ const int RIGHT_BUTTON = 1; /////////////////////////////////////////////////////////////////////////////// // Helper class that tries to download a URL from a web site and calls a method // on the Panel Land Media and to discover the MIME type -class LLMimeDiscoveryResponder : public LLHTTPClient::ResponderIgnoreBody +class LLMimeDiscoveryResponder : public LLHTTPClient::ResponderHeadersOnly { LOG_CLASS(LLMimeDiscoveryResponder); public: @@ -80,16 +80,21 @@ public: mInitialized(false) {} - /*virtual*/ bool needsHeaders(void) const { return true; } - /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - std::string media_type; - bool content_type_found = headers.getFirstValue("content-type", media_type); - llassert_always(content_type_found); - std::string::size_type idx1 = media_type.find_first_of(";"); - std::string mime_type = media_type.substr(0, idx1); - completeAny(status, mime_type); + if (200 <= status && status < 300) + { + std::string media_type; + if (headers.getFirstValue("content-type", media_type)) + { + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + return; + } + llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + } + completeAny(status, "none/none"); } void completeAny(U32 status, const std::string& mime_type)