diff options
| author | Rider Linden <none@none> | 2015-04-16 17:01:10 -0700 | 
|---|---|---|
| committer | Rider Linden <none@none> | 2015-04-16 17:01:10 -0700 | 
| commit | c4bcc83336c623b97e982443ce2f91d82d1a187d (patch) | |
| tree | 64a19ba7680f643dff4f61f12d0e7621546fcac8 /indra | |
| parent | 0d302e692fd25e5dd7a37b5ac4c9d14f3e5d470d (diff) | |
Facebook conversion.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 91 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.h | 39 | ||||
| -rwxr-xr-x | indra/llxml/llcontrol.h | 2 | ||||
| -rw-r--r-- | indra/newview/llavatarrenderinfoaccountant.cpp | 4 | ||||
| -rwxr-xr-x | indra/newview/llfacebookconnect.cpp | 396 | ||||
| -rw-r--r-- | indra/newview/llfacebookconnect.h | 11 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 40 | 
7 files changed, 522 insertions, 61 deletions
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 2d6cca214c..a3226ee2c3 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -291,7 +291,7 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons              // this method can return a map to the caller.              // *TODO: Should it always do this?              LLSD newResult = LLSD::emptyMap(); -            newResult["content"] = result; +            newResult[HttpCoroutineAdapter::HTTP_RESULTS_CONTENT] = result;              result = newResult;          }      } @@ -305,11 +305,6 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H      LLSD httpresults = LLSD::emptyMap();      writeStatusCodes(status, response->getRequestURL(), httpresults); -    //     httpresults["success"] = static_cast<LLSD::Boolean>(status); -    //     httpresults["type"] = static_cast<LLSD::Integer>(status.getType()); -    //     httpresults["status"] = static_cast<LLSD::Integer>(status.getStatus()); -    //     httpresults["message"] = static_cast<LLSD::String>(status.getMessage()); -    //     httpresults["url"] = static_cast<LLSD::String>(response->getRequestURL());      LLSD httpHeaders = LLSD::emptyMap();      LLCore::HttpHeaders * hdrs = response->getHeaders(); @@ -329,24 +324,24 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H          }      } -    httpresults["headers"] = httpHeaders; -    result["http_result"] = httpresults; +    httpresults[HttpCoroutineAdapter::HTTP_RESULTS_HEADERS] = httpHeaders; +    result[HttpCoroutineAdapter::HTTP_RESULTS] = httpresults;  }  void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result)  { -    result["success"] = static_cast<LLSD::Boolean>(status); -    result["type"] = static_cast<LLSD::Integer>(status.getType()); -    result["status"] = static_cast<LLSD::Integer>(status.getStatus()); -    result["message"] = static_cast<LLSD::String>(status.getMessage()); -    result["url"] = static_cast<LLSD::String>(url); +    result[HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS] = static_cast<LLSD::Boolean>(status); +    result[HttpCoroutineAdapter::HTTP_RESULTS_TYPE] = static_cast<LLSD::Integer>(status.getType()); +    result[HttpCoroutineAdapter::HTTP_RESULTS_STATUS] = static_cast<LLSD::Integer>(status.getStatus()); +    result[HttpCoroutineAdapter::HTTP_RESULTS_MESSAGE] = static_cast<LLSD::String>(status.getMessage()); +    result[HttpCoroutineAdapter::HTTP_RESULTS_URL] = static_cast<LLSD::String>(url);  }  LLCore::HttpStatus HttpCoroHandler::getStatusFromLLSD(const LLSD &httpResults)  { -    LLCore::HttpStatus::type_enum_t type = static_cast<LLCore::HttpStatus::type_enum_t>(httpResults["type"].asInteger()); -    short code = static_cast<short>(httpResults["status"].asInteger()); +    LLCore::HttpStatus::type_enum_t type = static_cast<LLCore::HttpStatus::type_enum_t>(httpResults[HttpCoroutineAdapter::HTTP_RESULTS_TYPE].asInteger()); +    short code = static_cast<short>(httpResults[HttpCoroutineAdapter::HTTP_RESULTS_STATUS].asInteger());      return LLCore::HttpStatus(type, code);  } @@ -377,6 +372,16 @@ bool HttpRequestPumper::pollRequest(const LLSD&)  }  //======================================================================== +const std::string HttpCoroutineAdapter::HTTP_RESULTS("http_result"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS("success"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_TYPE("type"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_STATUS("status"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_MESSAGE("message"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_URL("url"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_HEADERS("headers"); +const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content"); + +  HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,      LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) :      mAdapterName(name), @@ -422,6 +427,34 @@ LLSD HttpCoroutineAdapter::postAndYield(LLCoros::self & self, LLCore::HttpReques      return results;  } +LLSD HttpCoroutineAdapter::postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, +    const std::string & url, LLCore::BufferArray::ptr_t rawbody, +    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ +    LLEventStream  replyPump(mAdapterName, true); +    LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler = +        LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump)); + +    //LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL; +    LLCoreHttpUtil::HttpRequestPumper pumper(request); +    // The HTTPCoroHandler does not self delete, so retrieval of a the contained  +    // pointer from the smart pointer is safe in this case. +    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(),  +        options.get(), headers.get(), httpHandler.get()); + +    if (hhandle == LLCORE_HTTP_HANDLE_INVALID) +    { +        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url); +    } + +    saveState(hhandle, request, httpHandler); +    LLSD results = waitForEventOn(self, replyPump); +    cleanState(); + +    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; +    return results; +} +  LLSD HttpCoroutineAdapter::putAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,      const std::string & url, const LLSD & body,      LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) @@ -477,6 +510,34 @@ LLSD HttpCoroutineAdapter::getAndYield(LLCoros::self & self, LLCore::HttpRequest      return results;  } +LLSD HttpCoroutineAdapter::deleteAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, +    const std::string & url, +    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ +    LLEventStream  replyPump(mAdapterName + "Reply", true); +    LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler = +        LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump)); + +    //LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL; +    LLCoreHttpUtil::HttpRequestPumper pumper(request); +    // The HTTPCoroHandler does not self delete, so retrieval of a the contained  +    // pointer from the smart pointer is safe in this case. +    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority, +        url, options.get(), headers.get(), httpHandler.get()); + +    if (hhandle == LLCORE_HTTP_HANDLE_INVALID) +    { +        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url); +    } + +    saveState(hhandle, request, httpHandler); +    LLSD results = waitForEventOn(self, replyPump); +    cleanState(); +    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; +    return results; +} + +  void HttpCoroutineAdapter::cancelYieldingOperation()  {      LLCore::HttpRequest::ptr_t request = mWeakRequest.lock(); diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 6fcf03b95c..cd137dbbe1 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -205,6 +205,7 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,  class HttpCoroHandler : public LLCore::HttpHandler  {  public: +      typedef boost::shared_ptr<HttpCoroHandler>  ptr_t;      typedef boost::weak_ptr<HttpCoroHandler>    wptr_t; @@ -248,6 +249,15 @@ private:  class HttpCoroutineAdapter  {  public: +    static const std::string HTTP_RESULTS; +    static const std::string HTTP_RESULTS_SUCCESS; +    static const std::string HTTP_RESULTS_TYPE; +    static const std::string HTTP_RESULTS_STATUS; +    static const std::string HTTP_RESULTS_MESSAGE; +    static const std::string HTTP_RESULTS_URL; +    static const std::string HTTP_RESULTS_HEADERS; +    static const std::string HTTP_RESULTS_CONTENT; +      typedef boost::shared_ptr<HttpCoroutineAdapter> ptr_t;      typedef boost::weak_ptr<HttpCoroutineAdapter>   wptr_t; @@ -264,6 +274,25 @@ public:          const std::string & url, const LLSD & body,           LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),          LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false)); +    LLSD postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, +        const std::string & url, LLCore::BufferArray::ptr_t rawbody, +        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), +        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false)); +    LLSD postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request, +        const std::string & url, const LLSD & body, +        LLCore::HttpHeaders::ptr_t &headers) +    { +        return postAndYield(self, request, url, body, +            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), headers); +    } + +    LLSD postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request, +        const std::string & url, LLCore::BufferArray::ptr_t &rawbody, +        LLCore::HttpHeaders::ptr_t &headers) +    { +        return postAndYield(self, request, url, rawbody,  +            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), headers); +    }      /// Execute a Put transaction on the supplied URL and yield execution of       /// the coroutine until a result is available. @@ -285,6 +314,16 @@ public:          LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),          LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false)); +    /// Execute a DELETE transaction on the supplied URL and yield execution of  +    /// the coroutine until a result is available. +    ///  +    /// @Note: the request's smart pointer is passed by value so that it will +    /// not be deallocated during the yield. +    LLSD deleteAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, +        const std::string & url, +        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), +        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false)); +      ///      void cancelYieldingOperation(); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 04575d81e0..8116adeae2 100755 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -256,7 +256,7 @@ public:  		}  		else  		{ -			LL_WARNS() << "Control " << name << " not found." << LL_ENDL; +			LL_WARNS_ONCE() << "Control " << name << " not found." << LL_ENDL;  			return T();  		}  		return convert_from_llsd<T>(value, type, name); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index d532dbc6b1..4436fe74d6 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -65,7 +65,7 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(LLCoros::self& self,  {      LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);      LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t  -        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy)); +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));      LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);      LLSD result = httpAdapter->getAndYield(self, httpRequest, url); @@ -135,7 +135,7 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(LLCoros::self& sel  {      LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);      LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t -        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy)); +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));      LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);      LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle); diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp index 28319564e4..dc50ec81f1 100755 --- a/indra/newview/llfacebookconnect.cpp +++ b/indra/newview/llfacebookconnect.cpp @@ -45,6 +45,7 @@  #include "llfloaterwebcontent.h"  #include "llfloaterreg.h" +#include "llcorehttputil.h"  boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));  boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo")); @@ -125,6 +126,58 @@ LLFacebookConnectHandler gFacebookConnectHandler;  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 + +void LLFacebookConnect::facebookConnectCoro(LLCoros::self& self, std::string authCode, std::string authState) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + +    LLSD putData; +    if (!authCode.empty()) +    { +        putData["code"] = authCode; +    } +    if (!authState.empty()) +    { +        putData["state"] = authState; +    } + +    httpOpts->setWantHeaders(true); + +    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS); + +    LLSD result = httpAdapter->putAndYield(self, httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); +    if (!status) +    { +        if (status == LLCore::HttpStatus(HTTP_FOUND)) +        { +            std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; +            if (location.empty()) +            { +                LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; +            } +            else +            { +                openFacebookWeb(location); +            } +        } +    } +    else +    { +        LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_CONNECTED); +    } + +} + +#else  class LLFacebookConnectResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookConnectResponder); @@ -166,9 +219,129 @@ public:  		}  	}  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 +bool LLFacebookConnect::testShareStatus(LLSD &result) +{ +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); + +    if (status) +        return true; + +    if (status == LLCore::HttpStatus(HTTP_FOUND)) +    { +        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; +        if (location.empty()) +        { +            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; +        } +        else +        { +            openFacebookWeb(location); +        } +    } +    if (status == LLCore::HttpStatus(HTTP_NOT_FOUND)) +    { +        LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL; +        connectToFacebook(); +    } +    else +    { +        LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_POST_FAILED); +        log_facebook_connect_error("Share", status.getStatus(), status.toString(), +            result.get("error_code"), result.get("error_description")); +    } +    return false; +} + +void LLFacebookConnect::facebookShareCoro(LLCoros::self& self, std::string route, LLSD share) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    setConnectionState(LLFacebookConnect::FB_POSTING); + +    LLSD result = httpAdapter->postAndYield(self, httpRequest, getFacebookConnectURL(route, true), share); + +    if (testShareStatus(result)) +    { +        toast_user_for_facebook_success(); +        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_POSTED); +    } +} + +void LLFacebookConnect::facebookShareImageCoro(LLCoros::self& self, std::string route, LLPointer<LLImageFormatted> image, std::string caption) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + +    std::string imageFormat; +    if (dynamic_cast<LLImagePNG*>(image.get())) +    { +        imageFormat = "png"; +    } +    else if (dynamic_cast<LLImageJPEG*>(image.get())) +    { +        imageFormat = "jpg"; +    } +    else +    { +        LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL; +        return; +    } + +    // All this code is mostly copied from LLWebProfile::post() +    static const std::string boundary = "----------------------------0123abcdefab"; + +    std::string contentType = "multipart/form-data; boundary=" + boundary; +    httpHeaders->append("Content-Type", contentType.c_str()); + +    LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray(), false); //  +    LLCore::BufferArrayStream body(raw.get()); + +    // *NOTE: The order seems to matter. +    body << "--" << boundary << "\r\n" +        << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n" +        << caption << "\r\n"; + +    body << "--" << boundary << "\r\n" +        << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n" +        << "Content-Type: image/" << imageFormat << "\r\n\r\n"; + +    // Insert the image data. +    // *FIX: Treating this as a string will probably screw it up ... +    U8* image_data = image->getData(); +    for (S32 i = 0; i < image->getDataSize(); ++i) +    { +        body << image_data[i]; +    } + +    body << "\r\n--" << boundary << "--\r\n"; + +    setConnectionState(LLFacebookConnect::FB_POSTING); + +    LLSD result = httpAdapter->postAndYield(self, httpRequest, getFacebookConnectURL(route, true), raw, httpHeaders); + +    if (testShareStatus(result)) +    { +        toast_user_for_facebook_success(); +        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_POSTED); +    } +} + +#else  class LLFacebookShareResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookShareResponder); @@ -215,9 +388,43 @@ public:  		}  	}  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 +void LLFacebookConnect::facebookDisconnectCoro(LLCoros::self& self) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    setConnectionState(LLFacebookConnect::FB_DISCONNECTING); + +    LLSD result = httpAdapter->deleteAndYield(self, httpRequest, getFacebookConnectURL("/connection")); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); +    if (!status && (status != LLCore::HttpStatus(HTTP_FOUND))) +    { +        LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED); +        log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(), +            result.get("error_code"), result.get("error_description")); +    } +    else +    { +        LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL; +        clearInfo(); +        clearContent(); +        //Notify state change +        setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED); +    } + +} + +#else  class LLFacebookDisconnectResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookDisconnectResponder); @@ -261,9 +468,56 @@ public:  		}  	}  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 +void LLFacebookConnect::facebookConnectedCheckCoro(LLCoros::self& self, bool autoConnect) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS); + +    LLSD result = httpAdapter->getAndYield(self, httpRequest, getFacebookConnectURL("/connection", true)); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); + +    if (!status) +    { +        if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) ) +        { +            LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL; +            if (autoConnect) +            { +                connectToFacebook(); +            } +            else +            { +                setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED); +            } +        } +        else +        { +            LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL; + +            setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED); +            log_facebook_connect_error("Connected", status.getStatus(), status.toString(), +                result.get("error_code"), result.get("error_description")); +        } +    } +    else +    { +        LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL; +        setConnectionState(LLFacebookConnect::FB_CONNECTED); +    } +} + +#else  class LLFacebookConnectedResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookConnectedResponder); @@ -308,9 +562,50 @@ public:  private:  	bool mAutoConnect;  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 +void LLFacebookConnect::facebookConnectInfoCoro(LLCoros::self& self) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    LLSD result = httpAdapter->getAndYield(self, httpRequest, getFacebookConnectURL("/info", true)); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); + +    if (status == LLCore::HttpStatus(HTTP_FOUND)) +    { +        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; +        if (location.empty()) +        { +            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; +        } +        else +        { +            openFacebookWeb(location); +        } +    } +    else if (!status) +    { +        LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL; +        log_facebook_connect_error("Info", status.getStatus(), status.toString(), +            result.get("error_code"), result.get("error_description")); +    } +    else +    { +        LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL; +        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); +        storeInfo(result); +    } +} + +#else  class LLFacebookInfoResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookInfoResponder); @@ -347,9 +642,51 @@ public:  		}  	}  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // +#if 1 +void LLFacebookConnect::facebookConnectFriendsCoro(LLCoros::self& self) +{ +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    LLSD result = httpAdapter->getAndYield(self, httpRequest, getFacebookConnectURL("/friends", true)); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults); + +    if (status == LLCore::HttpStatus(HTTP_FOUND)) +    { +        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; +        if (location.empty()) +        { +            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; +        } +        else +        { +            openFacebookWeb(location); +        } +    } +    else if (!status) +    { +        LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL; +        log_facebook_connect_error("Info", status.getStatus(), status.toString(), +            result.get("error_code"), result.get("error_description")); +    } +    else +    { +        LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL; +        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); +        LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT]; +        storeContent(content); +    } +} + +#else  class LLFacebookFriendsResponder : public LLHTTPClient::Responder  {  	LOG_CLASS(LLFacebookFriendsResponder); @@ -385,6 +722,7 @@ public:  		}  	}  }; +#endif  ///////////////////////////////////////////////////////////////////////////////  // @@ -439,6 +777,11 @@ std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, b  void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)  { +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro", +        boost::bind(&LLFacebookConnect::facebookConnectCoro, this, _1, auth_code, auth_state)); + +#else  	LLSD body;  	if (!auth_code.empty())      { @@ -450,29 +793,48 @@ void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const st      }  	LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new LLFacebookConnectResponder()); +#endif  }  void LLFacebookConnect::disconnectFromFacebook()  { -	LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder()); +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro", +        boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this, _1)); + +#else +    LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder()); +#endif  }  void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)  { +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro", +        boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, _1, auto_connect)); + +#else  	const bool follow_redirects = false;  	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;  	LLHTTPClient::get(getFacebookConnectURL("/connection", true), new LLFacebookConnectedResponder(auto_connect),  						LLSD(), timeout, follow_redirects); +#endif  }  void LLFacebookConnect::loadFacebookInfo()  {  	if(mRefreshInfo)  	{ +#if 1 +        LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro", +            boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this, _1)); +         +#else  		const bool follow_redirects = false;  		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;  		LLHTTPClient::get(getFacebookConnectURL("/info", true), new LLFacebookInfoResponder(),  			LLSD(), timeout, follow_redirects); +#endif  	}  } @@ -480,14 +842,21 @@ void LLFacebookConnect::loadFacebookFriends()  {  	if(mRefreshContent)  	{ +#if 1 +        LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro", +            boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this, _1)); +#else +  		const bool follow_redirects = false;  		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;  		LLHTTPClient::get(getFacebookConnectURL("/friends", true), new LLFacebookFriendsResponder(),  			LLSD(), timeout, follow_redirects); +#endif  	}  } -void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& image, const std::string& message) +void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name,  +    const std::string& description, const std::string& image, const std::string& message)  {  	LLSD body;  	if (!location.empty()) @@ -511,22 +880,37 @@ void LLFacebookConnect::postCheckin(const std::string& location, const std::stri  		body["message"] = message;      } +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", +        boost::bind(&LLFacebookConnect::facebookShareCoro, this, _1, "/share/checkin", body)); +#else  	// Note: we can use that route for different publish action. We should be able to use the same responder.  	LLHTTPClient::post(getFacebookConnectURL("/share/checkin", true), body, new LLFacebookShareResponder()); +#endif  }  void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)  { +    // *TODO: I could not find an instace where this method is used.  Remove?  	LLSD body;  	body["image"] = image_url;  	body["caption"] = caption; +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", +        boost::bind(&LLFacebookConnect::facebookShareCoro, this, _1, "/share/photo", body)); +#else      // Note: we can use that route for different publish action. We should be able to use the same responder.  	LLHTTPClient::post(getFacebookConnectURL("/share/photo", true), body, new LLFacebookShareResponder()); +#endif  }  void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)  { +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro", +        boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, _1, "/share/photo", image, caption)); +#else  	std::string imageFormat;  	if (dynamic_cast<LLImagePNG*>(image.get()))  	{ @@ -576,15 +960,21 @@ void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std:      // Note: we can use that route for different publish action. We should be able to use the same responder.  	LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo", true), data, size, new LLFacebookShareResponder(), headers); +#endif  }  void LLFacebookConnect::updateStatus(const std::string& message)  {  	LLSD body;  	body["message"] = message; -	 + +#if 1 +    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", +        boost::bind(&LLFacebookConnect::facebookShareCoro, this, _1, "/share/wall", body)); +#else      // Note: we can use that route for different publish action. We should be able to use the same responder.  	LLHTTPClient::post(getFacebookConnectURL("/share/wall", true), body, new LLFacebookShareResponder()); +#endif  }  void LLFacebookConnect::storeInfo(const LLSD& info) diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h index c157db2178..f569c2f486 100644 --- a/indra/newview/llfacebookconnect.h +++ b/indra/newview/llfacebookconnect.h @@ -30,6 +30,8 @@  #include "llsingleton.h"  #include "llimage.h" +#include "llcoros.h" +#include "lleventcoro.h"  class LLEventPump; @@ -101,6 +103,15 @@ private:  	static boost::scoped_ptr<LLEventPump> sStateWatcher;  	static boost::scoped_ptr<LLEventPump> sInfoWatcher;  	static boost::scoped_ptr<LLEventPump> sContentWatcher; + +    bool testShareStatus(LLSD &results); +    void facebookConnectCoro(LLCoros::self& self, std::string authCode, std::string authState); +    void facebookConnectedCheckCoro(LLCoros::self& self, bool autoConnect); +    void facebookDisconnectCoro(LLCoros::self& self); +    void facebookShareCoro(LLCoros::self& self, std::string route, LLSD share); +    void facebookShareImageCoro(LLCoros::self& self, std::string route, LLPointer<LLImageFormatted> image, std::string caption); +    void facebookConnectInfoCoro(LLCoros::self& self); +    void facebookConnectFriendsCoro(LLCoros::self& self);  };  #endif // LL_LLFACEBOOKCONNECT_H diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index f78b08eb70..36dd778746 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -201,46 +201,6 @@ public:      void        requestSimulatorFeatureCoro(LLCoros::self& self, std::string url, U64 regionHandle);  }; -// support for secondlife:///app/region/{REGION} SLapps
 -// N.B. this is defined to work exactly like the classic secondlife://{REGION}
 -// However, the later syntax cannot support spaces in the region name because
 -// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
 -// browsers let you get away with this, but some do not (such as Qt's Webkit).
 -// Hence we introduced the newer secondlife:///app/region alternative.
 -class LLRegionHandler : public LLCommandHandler
 -{
 -public:
 -    // requests will be throttled from a non-trusted browser
 -    LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
 -        
 -    bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
 -    {
 -        // make sure that we at least have a region name
 -        int num_params = params.size();
 -        if (num_params < 1)
 -        {
 -            return false;
 -        }
 -            
 -        // build a secondlife://{PLACE} SLurl from this SLapp
 -        std::string url = "secondlife://";
 -        for (int i = 0; i < num_params; i++)
 -        {
 -            if (i > 0)
 -            {
 -                url += "/";
 -            }
 -            url += params[i].asString();
 -        }
 -            
 -        // Process the SLapp as if it was a secondlife://{PLACE} SLurl
 -        LLURLDispatcher::dispatch(url, "clicked", web, true);
 -        return true;
 -    }
 -        
 -};
 -LLRegionHandler gRegionHandler; -  void LLViewerRegionImpl::requestBaseCapabilitiesCoro(LLCoros::self& self, U64 regionHandle)  {      LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);  | 
