Mercurial > hg > orthanc
annotate Core/HttpServer/MongooseServer.cpp @ 25:dd1489098265
basic http authentication
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 28 Aug 2012 11:20:49 +0200 |
parents | 166664f0f860 |
children | 96e57b863dd9 |
rev | line source |
---|---|
0 | 1 /** |
2 * Palantir - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege, | |
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 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 **/ | |
19 | |
20 | |
21 // http://en.highscore.de/cpp/boost/stringhandling.html | |
22 | |
23 #include "MongooseServer.h" | |
24 | |
25 #include <algorithm> | |
26 #include <string.h> | |
27 #include <boost/lexical_cast.hpp> | |
28 #include <boost/algorithm/string.hpp> | |
29 #include <iostream> | |
30 #include <string.h> | |
31 #include <stdio.h> | |
32 #include <boost/thread.hpp> | |
33 | |
34 #include "../PalantirException.h" | |
35 #include "../ChunkedBuffer.h" | |
36 #include "mongoose.h" | |
37 | |
38 | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
39 #define PALANTIR_REALM "Palantir Secure Area" |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
40 |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
41 |
0 | 42 namespace Palantir |
43 { | |
44 static const char multipart[] = "multipart/form-data; boundary="; | |
45 static unsigned int multipartLength = sizeof(multipart) / sizeof(char) - 1; | |
46 | |
47 | |
48 namespace | |
49 { | |
50 // Anonymous namespace to avoid clashes between compilation modules | |
51 class MongooseOutput : public HttpOutput | |
52 { | |
53 private: | |
54 struct mg_connection* connection_; | |
55 | |
56 public: | |
57 MongooseOutput(struct mg_connection* connection) : connection_(connection) | |
58 { | |
59 } | |
60 | |
61 virtual void Send(const void* buffer, size_t length) | |
62 { | |
63 mg_write(connection_, buffer, length); | |
64 } | |
65 }; | |
66 | |
67 | |
68 enum PostDataStatus | |
69 { | |
70 PostDataStatus_Success, | |
71 PostDataStatus_NoLength, | |
72 PostDataStatus_Pending, | |
73 PostDataStatus_Failure | |
74 }; | |
75 } | |
76 | |
77 | |
78 // TODO Move this to external file | |
79 | |
80 | |
81 class ChunkedFile : public ChunkedBuffer | |
82 { | |
83 private: | |
84 std::string filename_; | |
85 | |
86 public: | |
87 ChunkedFile(const std::string& filename) : | |
88 filename_(filename) | |
89 { | |
90 } | |
91 | |
92 const std::string& GetFilename() const | |
93 { | |
94 return filename_; | |
95 } | |
96 }; | |
97 | |
98 | |
99 | |
100 class ChunkStore | |
101 { | |
102 private: | |
103 typedef std::list<ChunkedFile*> Content; | |
104 Content content_; | |
105 unsigned int numPlaces_; | |
106 | |
107 boost::mutex mutex_; | |
108 std::set<std::string> discardedFiles_; | |
109 | |
110 void Clear() | |
111 { | |
112 for (Content::iterator it = content_.begin(); | |
113 it != content_.end(); it++) | |
114 { | |
115 delete *it; | |
116 } | |
117 } | |
118 | |
119 Content::iterator Find(const std::string& filename) | |
120 { | |
121 for (Content::iterator it = content_.begin(); | |
122 it != content_.end(); it++) | |
123 { | |
124 if ((*it)->GetFilename() == filename) | |
125 { | |
126 return it; | |
127 } | |
128 } | |
129 | |
130 return content_.end(); | |
131 } | |
132 | |
133 void Remove(const std::string& filename) | |
134 { | |
135 Content::iterator it = Find(filename); | |
136 if (it != content_.end()) | |
137 { | |
138 delete *it; | |
139 content_.erase(it); | |
140 } | |
141 } | |
142 | |
143 public: | |
144 ChunkStore() | |
145 { | |
146 numPlaces_ = 10; | |
147 } | |
148 | |
149 ~ChunkStore() | |
150 { | |
151 Clear(); | |
152 } | |
153 | |
154 PostDataStatus Store(std::string& completed, | |
155 const char* chunkData, | |
156 size_t chunkSize, | |
157 const std::string& filename, | |
158 size_t filesize) | |
159 { | |
160 boost::mutex::scoped_lock lock(mutex_); | |
161 | |
162 std::set<std::string>::iterator wasDiscarded = discardedFiles_.find(filename); | |
163 if (wasDiscarded != discardedFiles_.end()) | |
164 { | |
165 discardedFiles_.erase(wasDiscarded); | |
166 return PostDataStatus_Failure; | |
167 } | |
168 | |
169 ChunkedFile* f; | |
170 Content::iterator it = Find(filename); | |
171 if (it == content_.end()) | |
172 { | |
173 f = new ChunkedFile(filename); | |
174 | |
175 // Make some room | |
176 if (content_.size() >= numPlaces_) | |
177 { | |
178 discardedFiles_.insert(content_.front()->GetFilename()); | |
179 delete content_.front(); | |
180 content_.pop_front(); | |
181 } | |
182 | |
183 content_.push_back(f); | |
184 } | |
185 else | |
186 { | |
187 f = *it; | |
188 } | |
189 | |
190 f->AddChunk(chunkData, chunkSize); | |
191 | |
192 if (f->GetNumBytes() > filesize) | |
193 { | |
194 Remove(filename); | |
195 } | |
196 else if (f->GetNumBytes() == filesize) | |
197 { | |
198 f->Flatten(completed); | |
199 Remove(filename); | |
200 return PostDataStatus_Success; | |
201 } | |
202 | |
203 return PostDataStatus_Pending; | |
204 } | |
205 | |
206 /*void Print() | |
207 { | |
208 boost::mutex::scoped_lock lock(mutex_); | |
209 | |
210 printf("ChunkStore status:\n"); | |
211 for (Content::const_iterator i = content_.begin(); | |
212 i != content_.end(); i++) | |
213 { | |
214 printf(" [%s]: %d\n", (*i)->GetFilename().c_str(), (*i)->GetNumBytes()); | |
215 } | |
216 printf("-----\n"); | |
217 }*/ | |
218 }; | |
219 | |
220 | |
221 struct MongooseServer::PImpl | |
222 { | |
223 struct mg_context *context_; | |
224 ChunkStore chunkStore_; | |
225 }; | |
226 | |
227 | |
228 ChunkStore& MongooseServer::GetChunkStore() | |
229 { | |
230 return pimpl_->chunkStore_; | |
231 } | |
232 | |
233 | |
234 | |
235 HttpHandler* MongooseServer::FindHandler(const UriComponents& forUri) const | |
236 { | |
237 for (Handlers::const_iterator it = | |
238 handlers_.begin(); it != handlers_.end(); it++) | |
239 { | |
240 if ((*it)->IsServedUri(forUri)) | |
241 { | |
242 return *it; | |
243 } | |
244 } | |
245 | |
246 return NULL; | |
247 } | |
248 | |
249 | |
250 | |
251 | |
252 static PostDataStatus ReadPostData(std::string& postData, | |
253 struct mg_connection *connection, | |
254 const HttpHandler::Arguments& headers) | |
255 { | |
256 HttpHandler::Arguments::const_iterator cs = headers.find("content-length"); | |
257 if (cs == headers.end()) | |
258 { | |
259 return PostDataStatus_NoLength; | |
260 } | |
261 | |
262 int length; | |
263 try | |
264 { | |
265 length = boost::lexical_cast<int>(cs->second); | |
266 } | |
267 catch (boost::bad_lexical_cast) | |
268 { | |
269 return PostDataStatus_NoLength; | |
270 } | |
271 | |
272 if (length < 0) | |
273 { | |
274 length = 0; | |
275 } | |
276 | |
277 postData.resize(length); | |
278 | |
279 size_t pos = 0; | |
280 while (length > 0) | |
281 { | |
282 int r = mg_read(connection, &postData[pos], length); | |
283 if (r <= 0) | |
284 { | |
285 return PostDataStatus_Failure; | |
286 } | |
8 | 287 assert(r <= length); |
0 | 288 length -= r; |
289 pos += r; | |
290 } | |
291 | |
292 return PostDataStatus_Success; | |
293 } | |
294 | |
295 | |
296 | |
297 static PostDataStatus ParseMultipartPost(std::string &completedFile, | |
298 struct mg_connection *connection, | |
299 const HttpHandler::Arguments& headers, | |
300 const std::string& contentType, | |
301 ChunkStore& chunkStore) | |
302 { | |
303 std::string boundary = "--" + contentType.substr(multipartLength); | |
304 | |
305 std::string postData; | |
306 PostDataStatus status = ReadPostData(postData, connection, headers); | |
307 | |
308 if (status != PostDataStatus_Success) | |
309 { | |
310 return status; | |
311 } | |
312 | |
313 /*for (HttpHandler::Arguments::const_iterator i = headers.begin(); i != headers.end(); i++) | |
314 { | |
315 std::cout << "Header [" << i->first << "] = " << i->second << "\n"; | |
316 } | |
317 printf("CHUNK\n");*/ | |
318 | |
319 typedef HttpHandler::Arguments::const_iterator ArgumentIterator; | |
320 | |
321 ArgumentIterator requestedWith = headers.find("x-requested-with"); | |
322 ArgumentIterator fileName = headers.find("x-file-name"); | |
323 ArgumentIterator fileSizeStr = headers.find("x-file-size"); | |
324 | |
325 if (requestedWith == headers.end() || | |
326 requestedWith->second != "XMLHttpRequest") | |
327 { | |
328 return PostDataStatus_Failure; | |
329 } | |
330 | |
331 size_t fileSize = 0; | |
332 if (fileSizeStr != headers.end()) | |
333 { | |
334 try | |
335 { | |
336 fileSize = boost::lexical_cast<size_t>(fileSizeStr->second); | |
337 } | |
338 catch (boost::bad_lexical_cast) | |
339 { | |
340 return PostDataStatus_Failure; | |
341 } | |
342 } | |
343 | |
344 typedef boost::find_iterator<std::string::iterator> FindIterator; | |
10 | 345 typedef boost::iterator_range<char*> Range; |
0 | 346 |
347 //chunkStore.Print(); | |
348 | |
349 try | |
350 { | |
351 FindIterator last; | |
352 for (FindIterator it = | |
353 make_find_iterator(postData, boost::first_finder(boundary)); | |
354 it!=FindIterator(); | |
355 ++it) | |
356 { | |
357 if (last != FindIterator()) | |
358 { | |
10 | 359 Range part(&last->back(), &it->front()); |
0 | 360 Range content = boost::find_first(part, "\r\n\r\n"); |
361 if (content != Range()) | |
362 { | |
363 Range c(&content.back() + 1, &it->front() - 2); | |
364 size_t chunkSize = c.size(); | |
365 | |
366 if (chunkSize > 0) | |
367 { | |
368 const char* chunkData = &c.front(); | |
369 | |
370 if (fileName == headers.end()) | |
371 { | |
372 // This file is stored in a single chunk | |
373 completedFile.resize(chunkSize); | |
374 if (chunkSize > 0) | |
375 { | |
376 memcpy(&completedFile[0], chunkData, chunkSize); | |
377 } | |
378 return PostDataStatus_Success; | |
379 } | |
380 else | |
381 { | |
382 return chunkStore.Store(completedFile, chunkData, chunkSize, fileName->second, fileSize); | |
383 } | |
384 } | |
10 | 385 } |
0 | 386 } |
387 | |
388 last = it; | |
389 } | |
390 } | |
391 catch (std::length_error) | |
392 { | |
393 return PostDataStatus_Failure; | |
394 } | |
395 | |
396 return PostDataStatus_Pending; | |
397 } | |
398 | |
399 | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
400 static bool Authorize(const MongooseServer& that, |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
401 const HttpHandler::Arguments& headers, |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
402 HttpOutput& output) |
23 | 403 { |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
404 bool granted = false; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
405 |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
406 HttpHandler::Arguments::const_iterator auth = headers.find("authorization"); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
407 if (auth != headers.end()) |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
408 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
409 std::string s = auth->second; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
410 if (s.substr(0, 6) == "Basic ") |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
411 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
412 std::string b64 = s.substr(6); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
413 granted = that.IsValidBasicHttpAuthentication(b64); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
414 } |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
415 } |
23 | 416 |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
417 if (!granted) |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
418 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
419 std::string s = "HTTP/1.1 401 Unauthorized\r\n" |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
420 "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\"" |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
421 "\r\n\r\n"; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
422 output.Send(&s[0], s.size()); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
423 return false; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
424 } |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
425 else |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
426 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
427 return true; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
428 } |
23 | 429 } |
430 | |
431 | |
0 | 432 |
433 static void* Callback(enum mg_event event, | |
434 struct mg_connection *connection, | |
435 const struct mg_request_info *request) | |
436 { | |
437 if (event == MG_NEW_REQUEST) | |
438 { | |
439 MongooseServer* that = (MongooseServer*) (request->user_data); | |
440 | |
441 HttpHandler::Arguments arguments, headers; | |
442 MongooseOutput c(connection); | |
443 | |
444 for (int i = 0; i < request->num_headers; i++) | |
445 { | |
446 std::string name = request->http_headers[i].name; | |
447 std::transform(name.begin(), name.end(), name.begin(), ::tolower); | |
448 headers.insert(std::make_pair(name, request->http_headers[i].value)); | |
449 } | |
450 | |
23 | 451 // Authenticate this connection |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
452 if (that->IsAuthenticationEnabled() && |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
453 !Authorize(*that, headers, c)) |
23 | 454 { |
455 return (void*) ""; | |
456 } | |
457 | |
0 | 458 std::string postData; |
459 | |
460 if (!strcmp(request->request_method, "GET")) | |
461 { | |
462 HttpHandler::ParseGetQuery(arguments, request->query_string); | |
463 } | |
464 else if (!strcmp(request->request_method, "POST")) | |
465 { | |
466 HttpHandler::Arguments::const_iterator ct = headers.find("content-type"); | |
467 if (ct == headers.end()) | |
468 { | |
469 c.SendHeader(HttpStatus_400_BadRequest); | |
470 return (void*) ""; | |
471 } | |
472 | |
473 PostDataStatus status; | |
474 | |
475 std::string contentType = ct->second; | |
476 if (contentType.size() >= multipartLength && | |
477 !memcmp(contentType.c_str(), multipart, multipartLength)) | |
478 { | |
479 status = ParseMultipartPost(postData, connection, headers, contentType, that->GetChunkStore()); | |
480 } | |
481 else | |
482 { | |
483 status = ReadPostData(postData, connection, headers); | |
484 } | |
485 | |
486 switch (status) | |
487 { | |
488 case PostDataStatus_NoLength: | |
489 c.SendHeader(HttpStatus_411_LengthRequired); | |
490 return (void*) ""; | |
491 | |
492 case PostDataStatus_Failure: | |
493 c.SendHeader(HttpStatus_400_BadRequest); | |
494 return (void*) ""; | |
495 | |
496 case PostDataStatus_Pending: | |
497 c.AnswerBuffer(""); | |
498 return (void*) ""; | |
499 | |
500 default: | |
501 break; | |
502 } | |
503 } | |
504 | |
505 UriComponents uri; | |
506 Toolbox::SplitUriComponents(uri, request->uri); | |
507 | |
508 HttpHandler* handler = that->FindHandler(uri); | |
509 if (handler) | |
510 { | |
511 try | |
512 { | |
513 handler->Handle(c, std::string(request->request_method), | |
514 uri, headers, arguments, postData); | |
515 } | |
516 catch (PalantirException& e) | |
517 { | |
518 std::cerr << "MongooseServer Exception [" << e.What() << "]" << std::endl; | |
519 c.SendHeader(HttpStatus_500_InternalServerError); | |
520 } | |
521 } | |
522 else | |
523 { | |
524 c.SendHeader(HttpStatus_404_NotFound); | |
525 } | |
526 | |
527 // Mark as processed | |
528 return (void*) ""; | |
529 } | |
530 else | |
531 { | |
532 return NULL; | |
533 } | |
534 } | |
535 | |
536 | |
537 bool MongooseServer::IsRunning() const | |
538 { | |
539 return (pimpl_->context_ != NULL); | |
540 } | |
541 | |
542 | |
543 MongooseServer::MongooseServer() : pimpl_(new PImpl) | |
544 { | |
545 pimpl_->context_ = NULL; | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
546 authentication_ = false; |
23 | 547 ssl_ = false; |
0 | 548 port_ = 8000; |
549 } | |
550 | |
551 | |
552 MongooseServer::~MongooseServer() | |
553 { | |
554 Stop(); | |
555 ClearHandlers(); | |
556 } | |
557 | |
558 | |
559 void MongooseServer::SetPort(uint16_t port) | |
560 { | |
561 Stop(); | |
562 port_ = port; | |
563 } | |
564 | |
565 void MongooseServer::Start() | |
566 { | |
567 if (!IsRunning()) | |
568 { | |
569 std::string port = boost::lexical_cast<std::string>(port_); | |
570 | |
23 | 571 if (ssl_) |
572 { | |
573 port += "s"; | |
574 } | |
575 | |
0 | 576 const char *options[] = { |
577 "listening_ports", port.c_str(), | |
23 | 578 ssl_ ? "ssl_certificate" : NULL, |
579 certificate_.c_str(), | |
0 | 580 NULL |
581 }; | |
582 | |
583 pimpl_->context_ = mg_start(&Callback, this, options); | |
584 if (!pimpl_->context_) | |
585 { | |
586 throw PalantirException("Unable to launch the Mongoose server"); | |
587 } | |
588 } | |
589 } | |
590 | |
591 void MongooseServer::Stop() | |
592 { | |
593 if (IsRunning()) | |
594 { | |
595 mg_stop(pimpl_->context_); | |
596 pimpl_->context_ = NULL; | |
597 } | |
598 } | |
599 | |
600 | |
601 void MongooseServer::RegisterHandler(HttpHandler* handler) | |
602 { | |
603 Stop(); | |
604 | |
605 handlers_.push_back(handler); | |
606 } | |
607 | |
608 | |
609 void MongooseServer::ClearHandlers() | |
610 { | |
611 Stop(); | |
612 | |
613 for (Handlers::iterator it = | |
614 handlers_.begin(); it != handlers_.end(); it++) | |
615 { | |
616 delete *it; | |
617 } | |
618 } | |
619 | |
23 | 620 |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
621 void MongooseServer::ClearUsers() |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
622 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
623 Stop(); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
624 registeredUsers_.clear(); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
625 } |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
626 |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
627 |
23 | 628 void MongooseServer::RegisterUser(const char* username, |
629 const char* password) | |
630 { | |
631 Stop(); | |
24 | 632 |
633 std::string tag = std::string(username) + ":" + std::string(password); | |
634 registeredUsers_.insert(Toolbox::EncodeBase64(tag)); | |
23 | 635 } |
636 | |
637 void MongooseServer::SetSslEnabled(bool enabled) | |
638 { | |
639 Stop(); | |
640 | |
641 #if PALANTIR_SSL_ENABLED == 0 | |
642 if (enabled) | |
643 { | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
644 throw PalantirException("Palantir has been built without SSL support"); |
23 | 645 } |
646 else | |
647 { | |
648 ssl_ = false; | |
649 } | |
650 #else | |
651 ssl_ = enabled; | |
652 #endif | |
653 } | |
654 | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
655 void MongooseServer::SetAuthenticationEnabled(bool enabled) |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
656 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
657 Stop(); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
658 authentication_ = enabled; |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
659 } |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
660 |
23 | 661 void MongooseServer::SetSslCertificate(const char* path) |
662 { | |
663 Stop(); | |
664 certificate_ = path; | |
665 } | |
25
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
666 |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
667 bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
668 { |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
669 return registeredUsers_.find(basic) != registeredUsers_.end(); |
dd1489098265
basic http authentication
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
24
diff
changeset
|
670 } |
0 | 671 } |