Mercurial > hg > orthanc
annotate Core/RestApi/RestApi.cpp @ 976:6968356679c0 plugins
integration mainline->plugins
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 30 Jun 2014 14:55:43 +0200 |
parents | 7d88f3f4a3b3 c550e99c452b |
children | 2a9e08136860 |
rev | line source |
---|---|
209 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
689 | 3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, |
209 | 4 * Belgium |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * In addition, as a special exception, the copyright holders of this | |
12 * program give permission to link the code of its release with the | |
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
14 * that use the same license as the "OpenSSL" library), and distribute | |
15 * the linked executables. You must obey the GNU General Public License | |
16 * in all respects for all of the code used other than "OpenSSL". If you | |
17 * modify file(s) with this exception, you may extend this exception to | |
18 * your version of the file(s), but you are not obligated to do so. If | |
19 * you do not wish to do so, delete this exception statement from your | |
20 * version. If you delete this exception statement from all source files | |
21 * in the program, then also delete it here. | |
22 * | |
23 * This program is distributed in the hope that it will be useful, but | |
24 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
26 * General Public License for more details. | |
27 * | |
28 * You should have received a copy of the GNU General Public License | |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30 **/ | |
31 | |
32 | |
824
a811bdf8b8eb
precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
33 #include "../PrecompiledHeaders.h" |
209 | 34 #include "RestApi.h" |
35 | |
249 | 36 #include <stdlib.h> // To define "_exit()" under Windows |
210
96b7918a6a18
start of the refactoring of the Orthanc REST API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
209
diff
changeset
|
37 #include <glog/logging.h> |
96b7918a6a18
start of the refactoring of the Orthanc REST API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
209
diff
changeset
|
38 |
209 | 39 namespace Orthanc |
40 { | |
41 bool RestApi::IsGetAccepted(const UriComponents& uri) | |
42 { | |
43 for (GetHandlers::const_iterator it = getHandlers_.begin(); | |
656 | 44 it != getHandlers_.end(); ++it) |
209 | 45 { |
46 if (it->first->Match(uri)) | |
47 { | |
48 return true; | |
49 } | |
50 } | |
51 | |
52 return false; | |
53 } | |
54 | |
55 bool RestApi::IsPutAccepted(const UriComponents& uri) | |
56 { | |
57 for (PutHandlers::const_iterator it = putHandlers_.begin(); | |
656 | 58 it != putHandlers_.end(); ++it) |
209 | 59 { |
60 if (it->first->Match(uri)) | |
61 { | |
62 return true; | |
63 } | |
64 } | |
65 | |
66 return false; | |
67 } | |
68 | |
69 bool RestApi::IsPostAccepted(const UriComponents& uri) | |
70 { | |
71 for (PostHandlers::const_iterator it = postHandlers_.begin(); | |
656 | 72 it != postHandlers_.end(); ++it) |
209 | 73 { |
74 if (it->first->Match(uri)) | |
75 { | |
76 return true; | |
77 } | |
78 } | |
79 | |
80 return false; | |
81 } | |
82 | |
83 bool RestApi::IsDeleteAccepted(const UriComponents& uri) | |
84 { | |
85 for (DeleteHandlers::const_iterator it = deleteHandlers_.begin(); | |
656 | 86 it != deleteHandlers_.end(); ++it) |
209 | 87 { |
88 if (it->first->Match(uri)) | |
89 { | |
90 return true; | |
91 } | |
92 } | |
93 | |
94 return false; | |
95 } | |
96 | |
97 static void AddMethod(std::string& target, | |
98 const std::string& method) | |
99 { | |
100 if (target.size() > 0) | |
101 target += "," + method; | |
102 else | |
103 target = method; | |
104 } | |
105 | |
106 std::string RestApi::GetAcceptedMethods(const UriComponents& uri) | |
107 { | |
108 std::string s; | |
109 | |
110 if (IsGetAccepted(uri)) | |
111 AddMethod(s, "GET"); | |
112 | |
113 if (IsPutAccepted(uri)) | |
114 AddMethod(s, "PUT"); | |
115 | |
116 if (IsPostAccepted(uri)) | |
117 AddMethod(s, "POST"); | |
118 | |
119 if (IsDeleteAccepted(uri)) | |
120 AddMethod(s, "DELETE"); | |
121 | |
122 return s; | |
123 } | |
124 | |
125 RestApi::~RestApi() | |
126 { | |
127 for (GetHandlers::iterator it = getHandlers_.begin(); | |
656 | 128 it != getHandlers_.end(); ++it) |
209 | 129 { |
130 delete it->first; | |
131 } | |
132 | |
133 for (PutHandlers::iterator it = putHandlers_.begin(); | |
656 | 134 it != putHandlers_.end(); ++it) |
209 | 135 { |
136 delete it->first; | |
137 } | |
138 | |
139 for (PostHandlers::iterator it = postHandlers_.begin(); | |
656 | 140 it != postHandlers_.end(); ++it) |
209 | 141 { |
142 delete it->first; | |
143 } | |
144 | |
145 for (DeleteHandlers::iterator it = deleteHandlers_.begin(); | |
656 | 146 it != deleteHandlers_.end(); ++it) |
209 | 147 { |
148 delete it->first; | |
149 } | |
150 } | |
151 | |
152 | |
895
7e8cde5905fd
allow superposition of REST handlers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
824
diff
changeset
|
153 bool RestApi::Handle(HttpOutput& output, |
473
c9a5d72f8481
changing the namespace of HTTP enumerations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
416
diff
changeset
|
154 HttpMethod method, |
209 | 155 const UriComponents& uri, |
156 const Arguments& headers, | |
157 const Arguments& getArguments, | |
158 const std::string& postData) | |
159 { | |
901
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
160 if (!IsGetAccepted(uri) && |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
161 !IsPutAccepted(uri) && |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
162 !IsPostAccepted(uri) && |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
163 !IsDeleteAccepted(uri)) |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
164 { |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
165 // This URI is not served by this handler |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
166 return false; |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
167 } |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
168 |
7d88f3f4a3b3
refactoring IsServedUri, answer PNG images, regular expression groups
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
895
diff
changeset
|
169 |
209 | 170 bool ok = false; |
171 RestApiOutput restOutput(output); | |
975 | 172 HttpHandler::Arguments components; |
209 | 173 UriComponents trailing; |
210
96b7918a6a18
start of the refactoring of the Orthanc REST API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
209
diff
changeset
|
174 |
473
c9a5d72f8481
changing the namespace of HTTP enumerations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
416
diff
changeset
|
175 if (method == HttpMethod_Get) |
209 | 176 { |
177 for (GetHandlers::const_iterator it = getHandlers_.begin(); | |
656 | 178 it != getHandlers_.end(); ++it) |
209 | 179 { |
180 if (it->first->Match(components, trailing, uri)) | |
181 { | |
416 | 182 //LOG(INFO) << "REST GET call on: " << Toolbox::FlattenUri(uri); |
209 | 183 ok = true; |
974 | 184 RestApiGetCall call(restOutput, *this, headers, components, trailing, uri, getArguments); |
209 | 185 it->second(call); |
186 } | |
187 } | |
188 } | |
473
c9a5d72f8481
changing the namespace of HTTP enumerations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
416
diff
changeset
|
189 else if (method == HttpMethod_Put) |
209 | 190 { |
191 for (PutHandlers::const_iterator it = putHandlers_.begin(); | |
656 | 192 it != putHandlers_.end(); ++it) |
209 | 193 { |
194 if (it->first->Match(components, trailing, uri)) | |
195 { | |
416 | 196 //LOG(INFO) << "REST PUT call on: " << Toolbox::FlattenUri(uri); |
209 | 197 ok = true; |
974 | 198 RestApiPutCall call(restOutput, *this, headers, components, trailing, uri, postData); |
209 | 199 it->second(call); |
200 } | |
201 } | |
202 } | |
473
c9a5d72f8481
changing the namespace of HTTP enumerations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
416
diff
changeset
|
203 else if (method == HttpMethod_Post) |
209 | 204 { |
205 for (PostHandlers::const_iterator it = postHandlers_.begin(); | |
656 | 206 it != postHandlers_.end(); ++it) |
209 | 207 { |
208 if (it->first->Match(components, trailing, uri)) | |
209 { | |
416 | 210 //LOG(INFO) << "REST POST call on: " << Toolbox::FlattenUri(uri); |
209 | 211 ok = true; |
974 | 212 RestApiPostCall call(restOutput, *this, headers, components, trailing, uri, postData); |
209 | 213 it->second(call); |
214 } | |
215 } | |
216 } | |
473
c9a5d72f8481
changing the namespace of HTTP enumerations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
416
diff
changeset
|
217 else if (method == HttpMethod_Delete) |
209 | 218 { |
219 for (DeleteHandlers::const_iterator it = deleteHandlers_.begin(); | |
656 | 220 it != deleteHandlers_.end(); ++it) |
209 | 221 { |
222 if (it->first->Match(components, trailing, uri)) | |
223 { | |
416 | 224 //LOG(INFO) << "REST DELETE call on: " << Toolbox::FlattenUri(uri); |
209 | 225 ok = true; |
974 | 226 RestApiDeleteCall call(restOutput, *this, headers, components, trailing, uri); |
209 | 227 it->second(call); |
228 } | |
229 } | |
230 } | |
231 | |
232 if (!ok) | |
233 { | |
477 | 234 LOG(INFO) << "REST method " << EnumerationToString(method) |
416 | 235 << " not allowed on: " << Toolbox::FlattenUri(uri); |
209 | 236 output.SendMethodNotAllowedError(GetAcceptedMethods(uri)); |
237 } | |
895
7e8cde5905fd
allow superposition of REST handlers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
824
diff
changeset
|
238 |
7e8cde5905fd
allow superposition of REST handlers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
824
diff
changeset
|
239 return true; |
209 | 240 } |
241 | |
242 void RestApi::Register(const std::string& path, | |
974 | 243 RestApiGetCall::Handler handler) |
209 | 244 { |
245 getHandlers_.push_back(std::make_pair(new RestApiPath(path), handler)); | |
246 } | |
247 | |
248 void RestApi::Register(const std::string& path, | |
974 | 249 RestApiPutCall::Handler handler) |
209 | 250 { |
251 putHandlers_.push_back(std::make_pair(new RestApiPath(path), handler)); | |
252 } | |
253 | |
254 void RestApi::Register(const std::string& path, | |
974 | 255 RestApiPostCall::Handler handler) |
209 | 256 { |
257 postHandlers_.push_back(std::make_pair(new RestApiPath(path), handler)); | |
258 } | |
259 | |
260 void RestApi::Register(const std::string& path, | |
974 | 261 RestApiDeleteCall::Handler handler) |
209 | 262 { |
263 deleteHandlers_.push_back(std::make_pair(new RestApiPath(path), handler)); | |
264 } | |
265 } |