1 /*
2  * UriHandler.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 CORE_HTTP_URI_HANDLER_HPP
17 #define CORE_HTTP_URI_HANDLER_HPP
18 
19 #include <string>
20 #include <vector>
21 
22 #include <boost/function.hpp>
23 #include <boost/variant.hpp>
24 
25 #include <core/http/AsyncConnection.hpp>
26 #include <core/http/Response.hpp>
27 
28 namespace rstudio {
29 namespace core {
30 namespace http {
31 
32 class Request;
33 
34 typedef boost::function<void(Response*)> UriHandlerFunctionContinuation;
35 
36 // UriHandlerFunction concept
37 typedef boost::function<void(const Request&,const UriHandlerFunctionContinuation&)>
38                                                 UriAsyncHandlerFunction;
39 
40 // UriHandlerFunction concept
41 typedef boost::function<void(const Request&,Response*)> UriHandlerFunction;
42 
43 // UriFilterFunction concept - return true if the filter handled the request
44 typedef boost::function<bool(const http::Request&, http::Response*)>
45                                                          UriFilterFunction;
46 
47 typedef boost::function<bool(const Request&,
48                              const std::string&,
49                              bool,
50                              const UriHandlerFunctionContinuation&)> UriAsyncUploadHandlerFunction;
51 
52 typedef boost::variant<UriAsyncHandlerFunction,
53             UriAsyncUploadHandlerFunction> UriAsyncHandlerFunctionVariant;
54 
55 class UriHandler
56 {
57 public:
58    UriHandler(const std::string& prefix, const UriAsyncHandlerFunction& function);
59    UriHandler(const std::string& prefix, const UriHandlerFunction& function);
60    UriHandler(const std::string& prefix, const UriAsyncUploadHandlerFunction& function);
61 
62    // COPYING: via compiler
63 
64    bool matches(const std::string& uri) const;
65 
66    UriAsyncHandlerFunctionVariant function() const;
67 
68    // implement UriHandlerFunction concept
69    void operator()(const Request& request,
70                    const UriHandlerFunctionContinuation& cont) const;
71 
72    void operator()(const Request& request,
73                    const std::string& formData,
74                    bool complete,
75                    const UriHandlerFunctionContinuation& cont) const;
76 
77 private:
78    std::string prefix_;
79    UriAsyncHandlerFunctionVariant function_;
80 };
81 
82 class UriHandlers
83 {
84 public:
UriHandlers()85    UriHandlers() {}
86 
87    // COPYING: via compiler
88 
89    void add(const UriHandler& handler);
90 
91    boost::optional<UriAsyncHandlerFunctionVariant> handlerFor(const std::string& uri) const;
92 
93 private:
94    std::vector<UriHandler> uriHandlers_;
95 };
96 
notFoundHandler(const Request & request,Response * pResponse)97 inline void notFoundHandler(const Request& request, Response* pResponse)
98 {
99    pResponse->setNotFoundError(request);
100 }
101 
102 void visitHandler(const UriAsyncHandlerFunctionVariant& variant,
103                   const Request& request,
104                   const UriHandlerFunctionContinuation& cont);
105 
106 } // namespace http
107 } // namespace core
108 } // namespace rstudio
109 
110 #endif // CORE_HTTP_URI_HANDLER_HPP
111 
112 
113