comparison Core/HttpServer/MongooseServer.cpp @ 2377:32bea64e070b

Experimental support of actively maintained Civetweb to replace Mongoose 3.8
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Aug 2017 14:09:24 +0200
parents ce5c13b95dac
children 878b59270859
comparison
equal deleted inserted replaced
2376:c33ff8a7ffa9 2377:32bea64e070b
37 #include "MongooseServer.h" 37 #include "MongooseServer.h"
38 38
39 #include "../Logging.h" 39 #include "../Logging.h"
40 #include "../ChunkedBuffer.h" 40 #include "../ChunkedBuffer.h"
41 #include "HttpToolbox.h" 41 #include "HttpToolbox.h"
42 #include "mongoose.h" 42
43 #if ORTHANC_ENABLE_MONGOOSE == 1
44 # include "mongoose.h"
45
46 #elif ORTHANC_ENABLE_CIVETWEB == 1
47 # include "civetweb.h"
48 # define MONGOOSE_USE_CALLBACKS 1
49
50 #else
51 # error "Either Mongoose or Civetweb must be enabled to compile this file"
52 #endif
43 53
44 #include <algorithm> 54 #include <algorithm>
45 #include <string.h> 55 #include <string.h>
46 #include <boost/lexical_cast.hpp> 56 #include <boost/lexical_cast.hpp>
47 #include <boost/algorithm/string.hpp> 57 #include <boost/algorithm/string.hpp>
57 #if ORTHANC_ENABLE_SSL == 1 67 #if ORTHANC_ENABLE_SSL == 1
58 #include <openssl/opensslv.h> 68 #include <openssl/opensslv.h>
59 #endif 69 #endif
60 70
61 #define ORTHANC_REALM "Orthanc Secure Area" 71 #define ORTHANC_REALM "Orthanc Secure Area"
62
63 static const long LOCALHOST = (127ll << 24) + 1ll;
64 72
65 73
66 namespace Orthanc 74 namespace Orthanc
67 { 75 {
68 static const char multipart[] = "multipart/form-data; boundary="; 76 static const char multipart[] = "multipart/form-data; boundary=";
584 HttpMethod& method /* out */, 592 HttpMethod& method /* out */,
585 MongooseServer& server, 593 MongooseServer& server,
586 struct mg_connection *connection, 594 struct mg_connection *connection,
587 const struct mg_request_info *request) 595 const struct mg_request_info *request)
588 { 596 {
597 bool localhost;
598
599 #if ORTHANC_ENABLE_MONGOOSE == 1
600 static const long LOCALHOST = (127ll << 24) + 1ll;
601 localhost = (request->remote_ip == LOCALHOST);
602 #elif ORTHANC_ENABLE_CIVETWEB == 1
603 // The "remote_ip" field of "struct mg_request_info" is tagged as
604 // deprecated in Civetweb, using "remote_addr" instead.
605 localhost = (std::string(request->remote_addr) == "127.0.0.1");
606 #else
607 #error
608 #endif
609
589 // Check remote calls 610 // Check remote calls
590 if (!server.IsRemoteAccessAllowed() && 611 if (!server.IsRemoteAccessAllowed() &&
591 request->remote_ip != LOCALHOST) 612 !localhost)
592 { 613 {
593 output.SendUnauthorized(ORTHANC_REALM); 614 output.SendUnauthorized(ORTHANC_REALM);
594 return; 615 return;
595 } 616 }
596 617
636 { 657 {
637 output.SendUnauthorized(ORTHANC_REALM); 658 output.SendUnauthorized(ORTHANC_REALM);
638 return; 659 return;
639 } 660 }
640 661
641 662
663 #if ORTHANC_ENABLE_MONGOOSE == 1
642 // Apply the filter, if it is installed 664 // Apply the filter, if it is installed
643 char remoteIp[24]; 665 char remoteIp[24];
644 sprintf(remoteIp, "%d.%d.%d.%d", 666 sprintf(remoteIp, "%d.%d.%d.%d",
645 reinterpret_cast<const uint8_t*>(&request->remote_ip) [3], 667 reinterpret_cast<const uint8_t*>(&request->remote_ip) [3],
646 reinterpret_cast<const uint8_t*>(&request->remote_ip) [2], 668 reinterpret_cast<const uint8_t*>(&request->remote_ip) [2],
647 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], 669 reinterpret_cast<const uint8_t*>(&request->remote_ip) [1],
648 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]); 670 reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]);
671 #elif ORTHANC_ENABLE_CIVETWEB == 1
672 const char* remoteIp = request->remote_addr;
673 #else
674 #error
675 #endif
649 676
650 std::string username = GetAuthenticatedUsername(headers); 677 std::string username = GetAuthenticatedUsername(headers);
651 678
652 const IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter(); 679 const IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter();
653 if (filter != NULL) 680 if (filter != NULL)
745 static void ProtectedCallback(struct mg_connection *connection, 772 static void ProtectedCallback(struct mg_connection *connection,
746 const struct mg_request_info *request) 773 const struct mg_request_info *request)
747 { 774 {
748 try 775 try
749 { 776 {
750 MongooseServer* server = reinterpret_cast<MongooseServer*>(request->user_data); 777 void* that = NULL;
778
779 #if ORTHANC_ENABLE_MONGOOSE == 1
780 that = request->user_data;
781 #elif ORTHANC_ENABLE_CIVETWEB == 1
782 // https://github.com/civetweb/civetweb/issues/409
783 that = mg_get_user_data(mg_get_context(connection));
784 #else
785 #error
786 #endif
751 787
788 MongooseServer* server = reinterpret_cast<MongooseServer*>(that);
789
752 if (server == NULL) 790 if (server == NULL)
753 { 791 {
754 MongooseOutputStream stream(connection); 792 MongooseOutputStream stream(connection);
755 HttpOutput output(stream, false /* assume no keep-alive */); 793 HttpOutput output(stream, false /* assume no keep-alive */);
756 output.SendStatus(HttpStatus_500_InternalServerError); 794 output.SendStatus(HttpStatus_500_InternalServerError);
757 return; 795 return;
758 } 796 }
759 797
760 MongooseOutputStream stream(connection); 798 MongooseOutputStream stream(connection);
761 HttpOutput output(stream, server->IsKeepAliveEnabled()); 799 HttpOutput output(stream, server->IsKeepAliveEnabled());
762 HttpMethod method = HttpMethod_Get; 800 HttpMethod method = HttpMethod_Get;
763 801
764 try 802 try
844 } 882 }
845 883
846 #elif MONGOOSE_USE_CALLBACKS == 1 884 #elif MONGOOSE_USE_CALLBACKS == 1
847 static int Callback(struct mg_connection *connection) 885 static int Callback(struct mg_connection *connection)
848 { 886 {
849 struct mg_request_info *request = mg_get_request_info(connection); 887 const struct mg_request_info *request = mg_get_request_info(connection);
850 888
851 ProtectedCallback(connection, request); 889 ProtectedCallback(connection, request);
852 890
853 return 1; // Do not let Mongoose handle the request by itself 891 return 1; // Do not let Mongoose handle the request by itself
854 } 892 }
904 port_ = port; 942 port_ = port;
905 } 943 }
906 944
907 void MongooseServer::Start() 945 void MongooseServer::Start()
908 { 946 {
947 #if ORTHANC_ENABLE_MONGOOSE == 1
948 LOG(INFO) << "Starting embedded Web server using Mongoose";
949 #elif ORTHANC_ENABLE_CIVETWEB == 1
950 LOG(INFO) << "Starting embedded Web server using Civetweb";
951 #else
952 #error
953 #endif
954
909 if (!IsRunning()) 955 if (!IsRunning())
910 { 956 {
911 std::string port = boost::lexical_cast<std::string>(port_); 957 std::string port = boost::lexical_cast<std::string>(port_);
912 958
913 if (ssl_) 959 if (ssl_)