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 {