Mercurial > hg > orthanc
comparison Core/HttpServer/MongooseServer.cpp @ 908:e078ea944089 plugins
refactoring HttpOutput
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 19 Jun 2014 17:47:39 +0200 |
parents | 7d88f3f4a3b3 |
children | ef71057d8b26 |
comparison
equal
deleted
inserted
replaced
907:9b8298234254 | 908:e078ea944089 |
---|---|
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 HttpOutputStream |
72 { | 72 { |
73 private: | 73 private: |
74 struct mg_connection* connection_; | 74 struct mg_connection* connection_; |
75 | 75 |
76 protected: | |
77 virtual void SendBody(const void* buffer, size_t length) | |
78 { | |
79 if (length > 0) | |
80 { | |
81 mg_write(connection_, buffer, length); | |
82 } | |
83 } | |
84 | |
85 virtual void SendHeader(const void* buffer, size_t length) | |
86 { | |
87 SendBody(buffer, length); | |
88 } | |
89 | |
76 public: | 90 public: |
77 MongooseOutput(struct mg_connection* connection) : connection_(connection) | 91 MongooseOutputStream(struct mg_connection* connection) : connection_(connection) |
78 { | 92 { |
79 } | |
80 | |
81 virtual void Send(const void* buffer, size_t length) | |
82 { | |
83 if (length > 0) | |
84 { | |
85 mg_write(connection_, buffer, length); | |
86 } | |
87 } | 93 } |
88 }; | 94 }; |
89 | 95 |
90 | 96 |
91 enum PostDataStatus | 97 enum PostDataStatus |
402 | 408 |
403 return PostDataStatus_Pending; | 409 return PostDataStatus_Pending; |
404 } | 410 } |
405 | 411 |
406 | 412 |
407 static void SendUnauthorized(HttpOutput& output) | |
408 { | |
409 std::string s = "HTTP/1.1 401 Unauthorized\r\n" | |
410 "WWW-Authenticate: Basic realm=\"" ORTHANC_REALM "\"" | |
411 "\r\n\r\n"; | |
412 output.Send(&s[0], s.size()); | |
413 } | |
414 | |
415 | |
416 static bool Authorize(const MongooseServer& that, | 413 static bool Authorize(const MongooseServer& that, |
417 const HttpHandler::Arguments& headers, | 414 const HttpHandler::Arguments& headers, |
418 HttpOutput& output) | 415 HttpOutput& output) |
419 { | 416 { |
420 bool granted = false; | 417 bool granted = false; |
430 } | 427 } |
431 } | 428 } |
432 | 429 |
433 if (!granted) | 430 if (!granted) |
434 { | 431 { |
435 SendUnauthorized(output); | 432 output.SendUnauthorized(ORTHANC_REALM); |
436 return false; | 433 return false; |
437 } | 434 } |
438 else | 435 else |
439 { | 436 { |
440 return true; | 437 return true; |
557 const struct mg_request_info *request) | 554 const struct mg_request_info *request) |
558 { | 555 { |
559 if (event == MG_NEW_REQUEST) | 556 if (event == MG_NEW_REQUEST) |
560 { | 557 { |
561 MongooseServer* that = reinterpret_cast<MongooseServer*>(request->user_data); | 558 MongooseServer* that = reinterpret_cast<MongooseServer*>(request->user_data); |
562 MongooseOutput output(connection); | 559 MongooseOutputStream stream(connection); |
560 HttpOutput output(stream); | |
563 | 561 |
564 // Check remote calls | 562 // Check remote calls |
565 if (!that->IsRemoteAccessAllowed() && | 563 if (!that->IsRemoteAccessAllowed() && |
566 request->remote_ip != LOCALHOST) | 564 request->remote_ip != LOCALHOST) |
567 { | 565 { |
568 SendUnauthorized(output); | 566 output.SendUnauthorized(ORTHANC_REALM); |
569 return (void*) ""; | 567 return (void*) ""; |
570 } | 568 } |
571 | 569 |
572 | 570 |
573 // Extract the HTTP headers | 571 // Extract the HTTP headers |
618 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], | 616 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], |
619 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]); | 617 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]); |
620 | 618 |
621 if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str())) | 619 if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str())) |
622 { | 620 { |
623 SendUnauthorized(output); | 621 output.SendUnauthorized(ORTHANC_REALM); |
624 return (void*) ""; | 622 return (void*) ""; |
625 } | 623 } |
626 } | 624 } |
627 | 625 |
628 | 626 |
687 | 685 |
688 | 686 |
689 // Loop over the candidate handlers for this URI | 687 // Loop over the candidate handlers for this URI |
690 LOG(INFO) << EnumerationToString(method) << " " << Toolbox::FlattenUri(uri); | 688 LOG(INFO) << EnumerationToString(method) << " " << Toolbox::FlattenUri(uri); |
691 bool found = false; | 689 bool found = false; |
692 bool isError = false; | |
693 HttpStatus errorStatus; | |
694 std::string errorDescription; | |
695 | 690 |
696 for (MongooseServer::Handlers::const_iterator it = | 691 for (MongooseServer::Handlers::const_iterator it = |
697 that->GetHandlers().begin(); it != that->GetHandlers().end(); ++it) | 692 that->GetHandlers().begin(); it != that->GetHandlers().end() && !found; ++it) |
698 { | 693 { |
699 try | 694 try |
700 { | 695 { |
701 found = (*it)->Handle(output, method, uri, headers, argumentsGET, body); | 696 found = (*it)->Handle(output, method, uri, headers, argumentsGET, body); |
702 } | 697 } |
703 catch (OrthancException& e) | 698 catch (OrthancException& e) |
704 { | 699 { |
705 // Using this candidate handler results in an exception, try | 700 // Using this candidate handler results in an exception |
706 // another handler before failing | 701 LOG(ERROR) << "Exception in the HTTP handler: " << e.What(); |
707 isError = true; | 702 return (void*) ""; |
708 errorStatus = HttpStatus_500_InternalServerError; | |
709 errorDescription = e.What(); | |
710 } | 703 } |
711 catch (boost::bad_lexical_cast&) | 704 catch (boost::bad_lexical_cast&) |
712 { | 705 { |
713 isError = true; | 706 LOG(ERROR) << "Exception in the HTTP handler: Bad lexical cast"; |
714 errorStatus = HttpStatus_400_BadRequest; | 707 return (void*) ""; |
715 errorDescription = "Bad lexical cast"; | |
716 } | 708 } |
717 catch (std::runtime_error&) | 709 catch (std::runtime_error&) |
718 { | 710 { |
719 isError = true; | 711 LOG(ERROR) << "Exception in the HTTP handler: Presumably a bad JSON request"; |
720 errorStatus = HttpStatus_400_BadRequest; | 712 return (void*) ""; |
721 errorDescription = "Presumably a bad JSON request"; | |
722 } | 713 } |
723 } | 714 } |
724 | 715 |
725 if (!found) | 716 if (!found) |
726 { | 717 { |
727 if (isError) | 718 output.SendHeader(HttpStatus_404_NotFound); |
728 { | 719 } |
729 LOG(ERROR) << "Exception in the HTTP handler: " << errorDescription; | |
730 output.SendHeader(errorStatus); | |
731 } | |
732 else | |
733 { | |
734 output.SendHeader(HttpStatus_404_NotFound); | |
735 } | |
736 } | |
737 | |
738 | 720 |
739 // Mark as processed | 721 // Mark as processed |
740 return (void*) ""; | 722 return (void*) ""; |
741 } | 723 } |
742 else | 724 else |