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