diff options
author | AndreyL ProductEngine <alihatskiy@productengine.com> | 2016-04-01 06:18:49 +0300 |
---|---|---|
committer | AndreyL ProductEngine <alihatskiy@productengine.com> | 2016-04-01 06:18:49 +0300 |
commit | 0ff6fa576a653597d0e9dda7f1de5f568e8d6829 (patch) | |
tree | 21e1b8f1253eedc1cc844553dcf46fef390d5a7d /indra/newview/llviewermedia.cpp | |
parent | a04341efaa63cd6bc47db25c1e4b4bf1e31d90a8 (diff) | |
parent | eb413ec41e6ee49055464a636a73a7243c172c67 (diff) |
Merged in lindenlab/viewer-bear
Diffstat (limited to 'indra/newview/llviewermedia.cpp')
-rwxr-xr-x | indra/newview/llviewermedia.cpp | 536 |
1 files changed, 253 insertions, 283 deletions
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 0b70af44bc..3e027e3d05 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -70,6 +70,7 @@ #include "llwebprofile.h" #include "llwindow.h" #include "llvieweraudio.h" +#include "llcorehttputil.h" #include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. @@ -153,189 +154,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver() } -// 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 LLMimeDiscoveryResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLMimeDiscoveryResponder); -public: - LLMimeDiscoveryResponder( viewer_media_t media_impl) - : mMediaImpl(media_impl), - mInitialized(false) - { - if(mMediaImpl->mMimeTypeProbe != NULL) - { - LL_ERRS() << "impl already has an outstanding responder" << LL_ENDL; - } - - mMediaImpl->mMimeTypeProbe = this; - } - - ~LLMimeDiscoveryResponder() - { - disconnectOwner(); - } - -private: - /* virtual */ void httpCompleted() - { - if (!isGoodStatus()) - { - LL_WARNS() << dumpResponse() - << " [headers:" << getResponseHeaders() << "]" << LL_ENDL; - } - const std::string& media_type = getResponseHeader(HTTP_IN_HEADER_CONTENT_TYPE); - std::string::size_type idx1 = media_type.find_first_of(";"); - std::string mime_type = media_type.substr(0, idx1); - - LL_DEBUGS() << "status is " << getStatus() << ", media type \"" << media_type << "\"" << LL_ENDL; - - // 2xx status codes indicate success. - // Most 4xx status codes are successful enough for our purposes. - // 499 is the error code for host not found, timeout, etc. - // 500 means "Internal Server error" but we decided it's okay to - // accept this and go past it in the MIME type probe - // 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com - // 499 is a code specifc to join.secondlife.com apparently safe to ignore -// if( ((status >= 200) && (status < 300)) || -// ((status >= 400) && (status < 499)) || -// (status == 500) || -// (status == 302) || -// (status == 499) -// ) - // We now no longer check the error code returned from the probe. - // If we have a mime type, use it. If not, default to the web plugin and let it handle error reporting. - //if(1) - { - // The probe was successful. - if(mime_type.empty()) - { - // Some sites don't return any content-type header at all. - // Treat an empty mime type as text/html. - mime_type = HTTP_CONTENT_TEXT_HTML; - } - } - //else - //{ - // LL_WARNS() << "responder failed with status " << dumpResponse() << LL_ENDL; - // - // if(mMediaImpl) - // { - // mMediaImpl->mMediaSourceFailed = true; - // } - // return; - //} - - // the call to initializeMedia may disconnect the responder, which will clear mMediaImpl. - // Make a local copy so we can call loadURI() afterwards. - LLViewerMediaImpl *impl = mMediaImpl; - - if(impl && !mInitialized && ! mime_type.empty()) - { - if(impl->initializeMedia(mime_type)) - { - mInitialized = true; - impl->loadURI(); - disconnectOwner(); - } - } - } - -public: - void cancelRequest() - { - disconnectOwner(); - } - -private: - void disconnectOwner() - { - if(mMediaImpl) - { - if(mMediaImpl->mMimeTypeProbe != this) - { - LL_ERRS() << "internal error: mMediaImpl->mMimeTypeProbe != this" << LL_ENDL; - } - - mMediaImpl->mMimeTypeProbe = NULL; - } - mMediaImpl = NULL; - } - - -public: - LLViewerMediaImpl *mMediaImpl; - bool mInitialized; -}; - -class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLViewerMediaOpenIDResponder); -public: - LLViewerMediaOpenIDResponder( ) - { - } - - ~LLViewerMediaOpenIDResponder() - { - } - - /* virtual */ void completedRaw( - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - const std::string url = getURL(); - - const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE); - - // *TODO: What about bad status codes? Does this destroy previous cookies? - LLViewerMedia::openIDCookieResponse(url, cookie); - } - -}; - -class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder -{ -LOG_CLASS(LLViewerMediaWebProfileResponder); -public: - LLViewerMediaWebProfileResponder(std::string host) - { - mHost = host; - } - - ~LLViewerMediaWebProfileResponder() - { - } - - void completedRaw( - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - // We don't care about the content of the response, only the set-cookie header. - LL_WARNS("MediaAuth") << dumpResponse() - << " [headers:" << getResponseHeaders() << "]" << LL_ENDL; - - LLSD stripped_content = getResponseHeaders(); - // *TODO: Check that this works. - stripped_content.erase(HTTP_IN_HEADER_SET_COOKIE); - LL_WARNS("MediaAuth") << stripped_content << LL_ENDL; - - const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE); - LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL; - - // *TODO: What about bad status codes? Does this destroy previous cookies? - LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost); - - // Set cookie for snapshot publishing. - std::string auth_cookie = cookie.substr(0, cookie.find(";")); // strip path - LLWebProfile::setAuthCookie(auth_cookie); - } - - std::string mHost; -}; - - LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL; LLURL LLViewerMedia::sOpenIDURL; std::string LLViewerMedia::sOpenIDCookie; @@ -1412,6 +1230,18 @@ bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& na return false; } +LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders() +{ + LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders); + + headers->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); + headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML); + headers->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie); + headers->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent()); + + return headers; +} + ///////////////////////////////////////////////////////////////////////////////////////// // static @@ -1419,104 +1249,180 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url) { if(!sOpenIDCookie.empty()) { - // The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port] - // We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that. - // We therefore do it here. - std::string authority = sOpenIDURL.mAuthority; - std::string::size_type host_start = authority.find('@'); - if(host_start == std::string::npos) - { - // no username/password - host_start = 0; - } - else - { - // Hostname starts after the @. - // (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.) - ++host_start; - } - std::string::size_type host_end = authority.rfind(':'); - if((host_end == std::string::npos) || (host_end < host_start)) - { - // no port - host_end = authority.size(); - } + std::string profileUrl = getProfileURL(""); + + LLCoros::instance().launch("LLViewerMedia::getOpenIDCookieCoro", + boost::bind(&LLViewerMedia::getOpenIDCookieCoro, profileUrl)); + } +} + +/*static*/ +void LLViewerMedia::getOpenIDCookieCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getOpenIDCookieCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + + httpOpts->setFollowRedirects(true); + httpOpts->setWantHeaders(true); + + LLURL hostUrl(url.c_str()); + std::string hostAuth = hostUrl.getAuthority(); + + // *TODO: Expand LLURL to split and extract this information better. + // The structure of a URL is well defined and needing to retrieve parts of it are common. + // original comment: + // The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port] + // We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that. + // We therefore do it here. + std::string authority = sOpenIDURL.mAuthority; + std::string::size_type hostStart = authority.find('@'); + if (hostStart == std::string::npos) + { // no username/password + hostStart = 0; + } + else + { // Hostname starts after the @. + // Hostname starts after the @. + // (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.) + ++hostStart; + } + std::string::size_type hostEnd = authority.rfind(':'); + if ((hostEnd == std::string::npos) || (hostEnd < hostStart)) + { // no port + hostEnd = authority.size(); + } - getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start)); + getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart)); - if (url.length()) + if (url.length()) + { + LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); + if (media_instance) { - LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); - if (media_instance) + std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart); + std::string cookie_name = ""; + std::string cookie_value = ""; + std::string cookie_path = ""; + bool httponly = true; + bool secure = true; + if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && + media_instance->getMediaPlugin()) { - std::string cookie_host = authority.substr(host_start, host_end - host_start); - std::string cookie_name = ""; - std::string cookie_value = ""; - std::string cookie_path = ""; - bool httponly = true; - bool secure = true; - if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && - media_instance->getMediaPlugin()) - { - media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure); - } + media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure); } } + } - // NOTE: this is the original OpenID cookie code, so of which is no longer needed now that we - // are using CEF - it's very intertwined with other code so, for the moment, I'm going to - // leave it alone and make a task to come back to it once we're sure the CEF cookie code is robust. + // NOTE: this is the original OpenID cookie code, so of which is no longer needed now that we + // are using CEF - it's very intertwined with other code so, for the moment, I'm going to + // leave it alone and make a task to come back to it once we're sure the CEF cookie code is robust. - // Do a web profile get so we can store the cookie - LLSD headers = LLSD::emptyMap(); - headers[HTTP_OUT_HEADER_ACCEPT] = "*/*"; - headers[HTTP_OUT_HEADER_COOKIE] = sOpenIDCookie; - headers[HTTP_OUT_HEADER_USER_AGENT] = getCurrentUserAgent(); + // Do a web profile get so we can store the cookie + httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); + httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie); + httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent()); - std::string profile_url = getProfileURL(""); - LLURL raw_profile_url( profile_url.c_str() ); - LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << LL_ENDL; - LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL; - LLHTTPClient::get(profile_url, - new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()), - headers); - } + LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL; + LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL; + + LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("MediaAuth") << "Error getting web profile." << LL_ENDL; + return; + } + + LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; + if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE)) + { + LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL; + return; + } + + const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef(); + LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL; + + // *TODO: What about bad status codes? Does this destroy previous cookies? + LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth); + + // Set cookie for snapshot publishing. + std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path + LLWebProfile::setAuthCookie(authCookie); + } ///////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token) +void LLViewerMedia::openIDSetup(const std::string &openidUrl, const std::string &openidToken) +{ + LL_DEBUGS("MediaAuth") << "url = \"" << openidUrl << "\", token = \"" << openidToken << "\"" << LL_ENDL; + + LLCoros::instance().launch("LLViewerMedia::openIDSetupCoro", + boost::bind(&LLViewerMedia::openIDSetupCoro, openidUrl, openidToken)); +} + +/*static*/ +void LLViewerMedia::openIDSetupCoro(std::string openidUrl, std::string openidToken) { - LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL; + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("openIDSetupCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); - // post the token to the url - // the responder will need to extract the cookie(s). + httpOpts->setWantHeaders(true); - // Save the OpenID URL for later -- we may need the host when adding the cookie. - sOpenIDURL.init(openid_url.c_str()); + // post the token to the url + // the responder will need to extract the cookie(s). + // Save the OpenID URL for later -- we may need the host when adding the cookie. + sOpenIDURL.init(openidUrl.c_str()); + + // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. + sOpenIDCookie.clear(); - // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. - sOpenIDCookie.clear(); + httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); + httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded"); - LLSD headers = LLSD::emptyMap(); - // Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header - headers[HTTP_OUT_HEADER_ACCEPT] = "*/*"; - // and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream" - headers[HTTP_OUT_HEADER_CONTENT_TYPE] = "application/x-www-form-urlencoded"; + LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray); + LLCore::BufferArrayStream bas(rawbody.get()); + + bas << std::noskipws << openidToken; + + LLSD result = httpAdapter->postRawAndSuspend(httpRequest, openidUrl, rawbody, httpOpts, httpHeaders); - // postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here. - size_t size = openid_token.size(); - U8 *data = new U8[size]; - memcpy(data, openid_token.data(), size); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - LLHTTPClient::postRaw( - openid_url, - data, - size, - new LLViewerMediaOpenIDResponder(), - headers); + if (!status) + { + LL_WARNS("MediaAuth") << "Error getting Open ID cookie" << LL_ENDL; + return; + } + LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; + if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE)) + { + LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL; + return; + } + + // We don't care about the content of the response, only the Set-Cookie header. + const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asString(); + + // *TODO: What about bad status codes? Does this destroy previous cookies? + LLViewerMedia::openIDCookieResponse(openidUrl, cookie); + LL_DEBUGS("MediaAuth") << "OpenID cookie set." << LL_ENDL; + } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1712,7 +1618,6 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mIsParcelMedia(false), mProximity(-1), mProximityDistance(0.0f), - mMimeTypeProbe(NULL), mMediaAutoPlay(false), mInNearbyMediaList(false), mClearCache(false), @@ -1722,7 +1627,9 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mIsUpdated(false), mTrustedBrowser(false), mZoomFactor(1.0), - mCleanBrowser(false) + mCleanBrowser(false), + mMimeProbe(), + mCanceling(false) { // Set up the mute list observer if it hasn't been set up already. @@ -2684,8 +2591,9 @@ void LLViewerMediaImpl::navigateInternal() mNavigateSuspendedDeferred = true; return; } - - if(mMimeTypeProbe != NULL) + + + if (!mMimeProbe.expired()) { LL_WARNS() << "MIME type probe already in progress -- bailing out." << LL_ENDL; return; @@ -2723,14 +2631,8 @@ void LLViewerMediaImpl::navigateInternal() if(scheme.empty() || "http" == scheme || "https" == scheme) { - // If we don't set an Accept header, LLHTTPClient will add one like this: - // Accept: application/llsd+xml - // which is really not what we want. - LLSD headers = LLSD::emptyMap(); - headers[HTTP_OUT_HEADER_ACCEPT] = "*/*"; - // Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com - headers[HTTP_OUT_HEADER_COOKIE] = ""; - LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f); + LLCoros::instance().launch("LLViewerMediaImpl::mimeDiscoveryCoro", + boost::bind(&LLViewerMediaImpl::mimeDiscoveryCoro, this, mMediaURL)); } else if("data" == scheme || "file" == scheme || "about" == scheme) { @@ -2760,6 +2662,81 @@ void LLViewerMediaImpl::navigateInternal() } } +void LLViewerMediaImpl::mimeDiscoveryCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("mimeDiscoveryCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + + // Increment our refcount so that we do not go away while the coroutine is active. + this->ref(); + + mMimeProbe = httpAdapter; + + httpOpts->setFollowRedirects(true); + httpOpts->setHeadersOnly(true); + + httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); + httpHeaders->append(HTTP_OUT_HEADER_COOKIE, ""); + + LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders); + + mMimeProbe.reset(); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Error retrieving media headers." << LL_ENDL; + } + + if (this->getNumRefs() > 1) + { // if there is only a single ref count outstanding it will be the one we took out above... + // we can skip the rest of this routine + + LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS]; + + const std::string& mediaType = resultHeaders[HTTP_IN_HEADER_CONTENT_TYPE].asStringRef(); + + std::string::size_type idx1 = mediaType.find_first_of(";"); + std::string mimeType = mediaType.substr(0, idx1); + + // We now no longer need to check the error code returned from the probe. + // If we have a mime type, use it. If not, default to the web plugin and let it handle error reporting. + // The probe was successful. + if (mimeType.empty()) + { + // Some sites don't return any content-type header at all. + // Treat an empty mime type as text/html. + mimeType = HTTP_CONTENT_TEXT_HTML; + } + + LL_DEBUGS() << "Media type \"" << mediaType << "\", mime type is \"" << mimeType << "\"" << LL_ENDL; + + // the call to initializeMedia may disconnect the responder, which will clear mMediaImpl. + // Make a local copy so we can call loadURI() afterwards. + + if (!mimeType.empty()) + { + if (initializeMedia(mimeType)) + { + loadURI(); + } + } + + } + else + { + LL_WARNS() << "LLViewerMediaImpl to be released." << LL_ENDL; + } + + this->unref(); +} + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::navigateStop() { @@ -2878,7 +2855,7 @@ void LLViewerMediaImpl::update() { // Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state. } - else if(mMimeTypeProbe != NULL) + else if (!mMimeProbe.expired()) { // this media source is doing a MIME type probe -- don't try loading it again. } @@ -3775,18 +3752,11 @@ void LLViewerMediaImpl::setNavigateSuspended(bool suspend) void LLViewerMediaImpl::cancelMimeTypeProbe() { - if(mMimeTypeProbe != NULL) - { - // There doesn't seem to be a way to actually cancel an outstanding request. - // Simulate it by telling the LLMimeDiscoveryResponder not to write back any results. - mMimeTypeProbe->cancelRequest(); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t probeAdapter = mMimeProbe.lock(); - // The above should already have set mMimeTypeProbe to NULL. - if(mMimeTypeProbe != NULL) - { - LL_ERRS() << "internal error: mMimeTypeProbe is not NULL after cancelling request." << LL_ENDL; - } - } + if (probeAdapter) + probeAdapter->cancelSuspendedOperation(); + } void LLViewerMediaImpl::addObject(LLVOVolume* obj) |