1 /* 2 * SessionAsyncRpcConnection.hpp 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16 #ifndef SESSION_ASYNC_RPC_CONNECTION_HPP 17 #define SESSION_ASYNC_RPC_CONNECTION_HPP 18 19 #include <shared_core/Error.hpp> 20 #include <shared_core/json/Json.hpp> 21 #include <core/json/JsonRpc.hpp> 22 #include <session/SessionHttpConnection.hpp> 23 24 #include "SessionHttpMethods.hpp" 25 #include "SessionRpc.hpp" 26 27 namespace rstudio { 28 namespace session { 29 namespace rpc { 30 31 /** 32 * Created from an HttpConnectionImpl, then put into mainConnectionQueue for RPC requests handed asynchronously 33 * by the rsession, where it first acks the http request, then later calls the rpc handler, then sends a kAsyncCompletion 34 * event in the response. 35 */ 36 class AsyncRpcConnection : 37 public HttpConnection, 38 public boost::enable_shared_from_this<AsyncRpcConnection>, 39 boost::noncopyable 40 { 41 public: AsyncRpcConnection(const boost::shared_ptr<HttpConnection> & ptrConnection,const core::json::JsonRpcRequest & jsonRequest,const std::string & asyncHandle)42 AsyncRpcConnection(const boost::shared_ptr<HttpConnection>& ptrConnection, 43 const core::json::JsonRpcRequest& jsonRequest, 44 const std::string& asyncHandle) 45 : ptrConnection_(ptrConnection), jsonRequest_(jsonRequest), asyncHandle_(asyncHandle) 46 { 47 } 48 ~AsyncRpcConnection()49 virtual ~AsyncRpcConnection() {} 50 request()51 virtual const core::http::Request& request() { return ptrConnection_->request(); } 52 53 // Not valid for async rpc since we already replied to http sendResponse(const core::http::Response & response)54 virtual void sendResponse(const core::http::Response& response) 55 { 56 BOOST_ASSERT(false); 57 } 58 59 // emit the kAsyncCompletion event with the response sendJsonRpcResponse(core::json::JsonRpcResponse & jsonRpcResponse)60 virtual void sendJsonRpcResponse(core::json::JsonRpcResponse& jsonRpcResponse) 61 { 62 rpc::endHandleRpcRequestIndirect(asyncHandle(), core::Success(), &jsonRpcResponse); 63 } 64 close()65 virtual void close() 66 { 67 // Not closing ptrConnection_ since it will already be closed 68 } 69 requestId() const70 virtual std::string requestId() const 71 { 72 return ptrConnection_->requestId(); 73 } 74 75 // This method only valid for uri handlers, not rpc requests setUploadHandler(const core::http::UriAsyncUploadHandlerFunction & uploadHandler)76 virtual void setUploadHandler(const core::http::UriAsyncUploadHandlerFunction& uploadHandler) 77 { 78 BOOST_ASSERT(false); 79 } 80 81 // Differentiate from HttpConnectionImpl isAsyncRpc() const82 virtual bool isAsyncRpc() const 83 { 84 return true; 85 } 86 receivedTime() const87 virtual std::chrono::steady_clock::time_point receivedTime() const 88 { 89 return ptrConnection_->receivedTime(); 90 } 91 jsonRpcRequest() const92 core::json::JsonRpcRequest jsonRpcRequest() const 93 { 94 return jsonRequest_; 95 } 96 97 // The uuid for the rpc ack and event response asyncHandle() const98 std::string asyncHandle() const 99 { 100 return asyncHandle_; 101 } 102 103 private: 104 // The (now closed) http connection including Request object 105 boost::shared_ptr<HttpConnection> ptrConnection_; 106 core::json::JsonRpcRequest jsonRequest_; 107 std::string asyncHandle_; 108 109 }; 110 111 } // namespace rpc 112 } // namespace session 113 } // namespace rstudio 114 115 #endif 116