Mercurial > hg > orthanc
comparison Core/HttpServer/MongooseServer.cpp @ 1014:40e5255e7dc5
integration plugins->mainline
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 10 Jul 2014 11:13:26 +0200 |
parents | dcb2469f00f4 |
children | 8d1845feb277 |
comparison
equal
deleted
inserted
replaced
991:2f76b92addd4 | 1014:40e5255e7dc5 |
---|---|
66 | 66 |
67 | 67 |
68 namespace | 68 namespace |
69 { | 69 { |
70 // Anonymous namespace to avoid clashes between compilation modules | 70 // Anonymous namespace to avoid clashes between compilation modules |
71 class MongooseOutput : public HttpOutput | 71 class MongooseOutputStream : public IHttpOutputStream |
72 { | 72 { |
73 private: | 73 private: |
74 struct mg_connection* connection_; | 74 struct mg_connection* connection_; |
75 | 75 |
76 public: | 76 public: |
77 MongooseOutput(struct mg_connection* connection) : connection_(connection) | 77 MongooseOutputStream(struct mg_connection* connection) : connection_(connection) |
78 { | 78 { |
79 } | 79 } |
80 | 80 |
81 virtual void Send(const void* buffer, size_t length) | 81 virtual void Send(bool isHeader, const void* buffer, size_t length) |
82 { | 82 { |
83 if (length > 0) | 83 if (length > 0) |
84 { | 84 { |
85 mg_write(connection_, buffer, length); | 85 mg_write(connection_, buffer, length); |
86 } | 86 } |
87 } | |
88 | |
89 virtual void OnHttpStatusReceived(HttpStatus status) | |
90 { | |
91 // Ignore this | |
87 } | 92 } |
88 }; | 93 }; |
89 | 94 |
90 | 95 |
91 enum PostDataStatus | 96 enum PostDataStatus |
250 | 255 |
251 ChunkStore& MongooseServer::GetChunkStore() | 256 ChunkStore& MongooseServer::GetChunkStore() |
252 { | 257 { |
253 return pimpl_->chunkStore_; | 258 return pimpl_->chunkStore_; |
254 } | 259 } |
255 | |
256 | |
257 | |
258 HttpHandler* MongooseServer::FindHandler(const UriComponents& forUri) const | |
259 { | |
260 for (Handlers::const_iterator it = | |
261 handlers_.begin(); it != handlers_.end(); ++it) | |
262 { | |
263 if ((*it)->IsServedUri(forUri)) | |
264 { | |
265 return *it; | |
266 } | |
267 } | |
268 | |
269 return NULL; | |
270 } | |
271 | |
272 | 260 |
273 | 261 |
274 | 262 |
275 static PostDataStatus ReadBody(std::string& postData, | 263 static PostDataStatus ReadBody(std::string& postData, |
276 struct mg_connection *connection, | 264 struct mg_connection *connection, |
419 | 407 |
420 return PostDataStatus_Pending; | 408 return PostDataStatus_Pending; |
421 } | 409 } |
422 | 410 |
423 | 411 |
424 static void SendUnauthorized(HttpOutput& output) | |
425 { | |
426 std::string s = "HTTP/1.1 401 Unauthorized\r\n" | |
427 "WWW-Authenticate: Basic realm=\"" ORTHANC_REALM "\"" | |
428 "\r\n\r\n"; | |
429 output.Send(&s[0], s.size()); | |
430 } | |
431 | |
432 | |
433 static bool Authorize(const MongooseServer& that, | 412 static bool Authorize(const MongooseServer& that, |
434 const HttpHandler::Arguments& headers, | 413 const HttpHandler::Arguments& headers, |
435 HttpOutput& output) | 414 HttpOutput& output) |
436 { | 415 { |
437 bool granted = false; | 416 bool granted = false; |
447 } | 426 } |
448 } | 427 } |
449 | 428 |
450 if (!granted) | 429 if (!granted) |
451 { | 430 { |
452 SendUnauthorized(output); | 431 output.SendUnauthorized(ORTHANC_REALM); |
453 return false; | 432 return false; |
454 } | 433 } |
455 else | 434 else |
456 { | 435 { |
457 return true; | 436 return true; |
574 const struct mg_request_info *request) | 553 const struct mg_request_info *request) |
575 { | 554 { |
576 if (event == MG_NEW_REQUEST) | 555 if (event == MG_NEW_REQUEST) |
577 { | 556 { |
578 MongooseServer* that = reinterpret_cast<MongooseServer*>(request->user_data); | 557 MongooseServer* that = reinterpret_cast<MongooseServer*>(request->user_data); |
579 MongooseOutput output(connection); | 558 MongooseOutputStream stream(connection); |
559 HttpOutput output(stream); | |
580 | 560 |
581 // Check remote calls | 561 // Check remote calls |
582 if (!that->IsRemoteAccessAllowed() && | 562 if (!that->IsRemoteAccessAllowed() && |
583 request->remote_ip != LOCALHOST) | 563 request->remote_ip != LOCALHOST) |
584 { | 564 { |
585 SendUnauthorized(output); | 565 output.SendUnauthorized(ORTHANC_REALM); |
586 return (void*) ""; | 566 return (void*) ""; |
587 } | 567 } |
588 | 568 |
589 | 569 |
590 // Extract the HTTP headers | 570 // Extract the HTTP headers |
599 | 579 |
600 // Extract the GET arguments | 580 // Extract the GET arguments |
601 HttpHandler::Arguments argumentsGET; | 581 HttpHandler::Arguments argumentsGET; |
602 if (!strcmp(request->request_method, "GET")) | 582 if (!strcmp(request->request_method, "GET")) |
603 { | 583 { |
604 HttpHandler::ParseGetQuery(argumentsGET, request->query_string); | 584 HttpHandler::ParseGetArguments(argumentsGET, request->query_string); |
605 } | 585 } |
606 | 586 |
607 | 587 |
608 // Compute the HTTP method, taking method faking into consideration | 588 // Compute the HTTP method, taking method faking into consideration |
609 HttpMethod method; | 589 HttpMethod method; |
635 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], | 615 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], |
636 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]); | 616 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]); |
637 | 617 |
638 if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str())) | 618 if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str())) |
639 { | 619 { |
640 SendUnauthorized(output); | 620 output.SendUnauthorized(ORTHANC_REALM); |
641 return (void*) ""; | 621 return (void*) ""; |
642 } | 622 } |
643 } | 623 } |
644 | 624 |
645 | 625 |
688 break; | 668 break; |
689 } | 669 } |
690 } | 670 } |
691 | 671 |
692 | 672 |
693 // Call the proper handler for this URI | 673 // Decompose the URI into its components |
694 UriComponents uri; | 674 UriComponents uri; |
695 try | 675 try |
696 { | 676 { |
697 Toolbox::SplitUriComponents(uri, request->uri); | 677 Toolbox::SplitUriComponents(uri, request->uri); |
698 } | 678 } |
701 output.SendHeader(HttpStatus_400_BadRequest); | 681 output.SendHeader(HttpStatus_400_BadRequest); |
702 return (void*) ""; | 682 return (void*) ""; |
703 } | 683 } |
704 | 684 |
705 | 685 |
706 HttpHandler* handler = that->FindHandler(uri); | 686 // Loop over the candidate handlers for this URI |
707 if (handler) | 687 LOG(INFO) << EnumerationToString(method) << " " << Toolbox::FlattenUri(uri); |
688 bool found = false; | |
689 | |
690 for (MongooseServer::Handlers::const_iterator it = | |
691 that->GetHandlers().begin(); it != that->GetHandlers().end() && !found; ++it) | |
708 { | 692 { |
709 try | 693 try |
710 { | 694 { |
711 LOG(INFO) << EnumerationToString(method) << " " << Toolbox::FlattenUri(uri); | 695 found = (*it)->Handle(output, method, uri, headers, argumentsGET, body); |
712 handler->Handle(output, method, uri, headers, argumentsGET, body); | |
713 } | 696 } |
714 catch (OrthancException& e) | 697 catch (OrthancException& e) |
715 { | 698 { |
716 LOG(ERROR) << "MongooseServer Exception [" << e.What() << "]"; | 699 // Using this candidate handler results in an exception |
717 output.SendHeader(HttpStatus_500_InternalServerError); | 700 LOG(ERROR) << "Exception in the HTTP handler: " << e.What(); |
701 return (void*) ""; | |
718 } | 702 } |
719 catch (boost::bad_lexical_cast&) | 703 catch (boost::bad_lexical_cast&) |
720 { | 704 { |
721 LOG(ERROR) << "MongooseServer Exception: Bad lexical cast"; | 705 LOG(ERROR) << "Exception in the HTTP handler: Bad lexical cast"; |
722 output.SendHeader(HttpStatus_400_BadRequest); | 706 return (void*) ""; |
723 } | 707 } |
724 catch (std::runtime_error&) | 708 catch (std::runtime_error&) |
725 { | 709 { |
726 LOG(ERROR) << "MongooseServer Exception: Presumably a bad JSON request"; | 710 LOG(ERROR) << "Exception in the HTTP handler: Presumably a bad JSON request"; |
727 output.SendHeader(HttpStatus_400_BadRequest); | 711 return (void*) ""; |
728 } | 712 } |
729 } | 713 } |
730 else | 714 |
715 if (!found) | |
731 { | 716 { |
732 output.SendHeader(HttpStatus_404_NotFound); | 717 output.SendHeader(HttpStatus_404_NotFound); |
733 } | 718 } |
734 | 719 |
735 // Mark as processed | 720 // Mark as processed |
816 pimpl_->context_ = NULL; | 801 pimpl_->context_ = NULL; |
817 } | 802 } |
818 } | 803 } |
819 | 804 |
820 | 805 |
821 void MongooseServer::RegisterHandler(HttpHandler* handler) | 806 void MongooseServer::RegisterHandler(HttpHandler& handler) |
822 { | 807 { |
823 Stop(); | 808 Stop(); |
824 | 809 |
825 handlers_.push_back(handler); | 810 handlers_.push_back(&handler); |
826 } | 811 } |
827 | 812 |
828 | 813 |
829 void MongooseServer::ClearHandlers() | 814 void MongooseServer::ClearHandlers() |
830 { | 815 { |
831 Stop(); | 816 Stop(); |
832 | |
833 for (Handlers::iterator it = | |
834 handlers_.begin(); it != handlers_.end(); ++it) | |
835 { | |
836 delete *it; | |
837 } | |
838 } | 817 } |
839 | 818 |
840 | 819 |
841 void MongooseServer::ClearUsers() | 820 void MongooseServer::ClearUsers() |
842 { | 821 { |