comparison Core/HttpServer/HttpToolbox.cpp @ 1441:f3672356c121

refactoring: IHttpHandler and HttpToolbox
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 01 Jul 2015 10:38:39 +0200
parents Core/HttpServer/HttpHandler.cpp@02f5a3f5c0a0
children b2b09a3dbd8e
comparison
equal deleted inserted replaced
1440:3567503c00a7 1441:f3672356c121
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, 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
33 #include "../PrecompiledHeaders.h"
34 #include "HttpToolbox.h"
35
36 #include <string.h>
37 #include <iostream>
38
39 #include "HttpOutput.h"
40 #include "StringHttpOutput.h"
41
42
43 namespace Orthanc
44 {
45 static void SplitGETNameValue(IHttpHandler::GetArguments& result,
46 const char* start,
47 const char* end)
48 {
49 std::string name, value;
50
51 const char* equal = strchr(start, '=');
52 if (equal == NULL || equal >= end)
53 {
54 name = std::string(start, end - start);
55 //value = "";
56 }
57 else
58 {
59 name = std::string(start, equal - start);
60 value = std::string(equal + 1, end);
61 }
62
63 Toolbox::UrlDecode(name);
64 Toolbox::UrlDecode(value);
65
66 result.push_back(std::make_pair(name, value));
67 }
68
69
70 void HttpToolbox::ParseGetArguments(IHttpHandler::GetArguments& result,
71 const char* query)
72 {
73 const char* pos = query;
74
75 while (pos != NULL)
76 {
77 const char* ampersand = strchr(pos, '&');
78 if (ampersand)
79 {
80 SplitGETNameValue(result, pos, ampersand);
81 pos = ampersand + 1;
82 }
83 else
84 {
85 // No more ampersand, this is the last argument
86 SplitGETNameValue(result, pos, pos + strlen(pos));
87 pos = NULL;
88 }
89 }
90 }
91
92
93 void HttpToolbox::ParseGetQuery(UriComponents& uri,
94 IHttpHandler::GetArguments& getArguments,
95 const char* query)
96 {
97 const char *questionMark = ::strchr(query, '?');
98 if (questionMark == NULL)
99 {
100 // No question mark in the string
101 Toolbox::SplitUriComponents(uri, query);
102 getArguments.clear();
103 }
104 else
105 {
106 Toolbox::SplitUriComponents(uri, std::string(query, questionMark));
107 HttpToolbox::ParseGetArguments(getArguments, questionMark + 1);
108 }
109 }
110
111
112 std::string HttpToolbox::GetArgument(const IHttpHandler::Arguments& getArguments,
113 const std::string& name,
114 const std::string& defaultValue)
115 {
116 IHttpHandler::Arguments::const_iterator it = getArguments.find(name);
117 if (it == getArguments.end())
118 {
119 return defaultValue;
120 }
121 else
122 {
123 return it->second;
124 }
125 }
126
127
128 std::string HttpToolbox::GetArgument(const IHttpHandler::GetArguments& getArguments,
129 const std::string& name,
130 const std::string& defaultValue)
131 {
132 for (size_t i = 0; i < getArguments.size(); i++)
133 {
134 if (getArguments[i].first == name)
135 {
136 return getArguments[i].second;
137 }
138 }
139
140 return defaultValue;
141 }
142
143
144
145 void HttpToolbox::ParseCookies(IHttpHandler::Arguments& result,
146 const IHttpHandler::Arguments& httpHeaders)
147 {
148 result.clear();
149
150 IHttpHandler::Arguments::const_iterator it = httpHeaders.find("cookie");
151 if (it != httpHeaders.end())
152 {
153 const std::string& cookies = it->second;
154
155 size_t pos = 0;
156 while (pos != std::string::npos)
157 {
158 size_t nextSemicolon = cookies.find(";", pos);
159 std::string cookie;
160
161 if (nextSemicolon == std::string::npos)
162 {
163 cookie = cookies.substr(pos);
164 pos = std::string::npos;
165 }
166 else
167 {
168 cookie = cookies.substr(pos, nextSemicolon - pos);
169 pos = nextSemicolon + 1;
170 }
171
172 size_t equal = cookie.find("=");
173 if (equal != std::string::npos)
174 {
175 std::string name = Toolbox::StripSpaces(cookie.substr(0, equal));
176 std::string value = Toolbox::StripSpaces(cookie.substr(equal + 1));
177 result[name] = value;
178 }
179 }
180 }
181 }
182
183
184 void HttpToolbox::CompileGetArguments(IHttpHandler::Arguments& compiled,
185 const IHttpHandler::GetArguments& source)
186 {
187 compiled.clear();
188
189 for (size_t i = 0; i < source.size(); i++)
190 {
191 compiled[source[i].first] = source[i].second;
192 }
193 }
194
195
196 bool HttpToolbox::SimpleGet(std::string& output,
197 IHttpHandler& handler,
198 const std::string& uri)
199 {
200 IHttpHandler::Arguments headers; // No HTTP header
201 std::string body; // No body for a GET request
202
203 UriComponents curi;
204 IHttpHandler::GetArguments getArguments;
205 ParseGetQuery(curi, getArguments, uri.c_str());
206
207 StringHttpOutput stream;
208 HttpOutput http(stream, false /* no keep alive */);
209
210 if (handler.Handle(http, HttpMethod_Get, curi, headers, getArguments, body))
211 {
212 stream.GetOutput(output);
213 return true;
214 }
215 else
216 {
217 return false;
218 }
219 }
220
221 }