[mapguide-commits] r9687 - sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Jul 28 03:39:20 PDT 2020


Author: jng
Date: 2020-07-28 03:39:16 -0700 (Tue, 28 Jul 2020)
New Revision: 9687

Modified:
   sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/DevHttpServer.vcxproj
   sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp
Log:
Use MapAgentCommon to handle auth header parsing. This gives us WFS/WMS requests without needing authentication challenges like a real Apache/IIS-backed web tier.

Modified: sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/DevHttpServer.vcxproj
===================================================================
--- sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/DevHttpServer.vcxproj	2020-07-24 13:11:35 UTC (rev 9686)
+++ sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/DevHttpServer.vcxproj	2020-07-28 10:39:16 UTC (rev 9687)
@@ -94,7 +94,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\MapAgentCommon;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_MAPAGENT_API_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -133,7 +133,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\MapAgentCommon;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_MAPAGENT_API_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -172,7 +172,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\MapAgentCommon;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_MAPAGENT_API_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -212,7 +212,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\Oem\cpp-httplib;..\HttpHandler;..\MapAgentCommon;..\WebSupport;..\WebApp;..\..\..\Common\MdfModel;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\jsoncpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_MAPAGENT_API_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -268,6 +268,9 @@
     <ProjectReference Include="..\HttpHandler\HttpHandler.vcxproj">
       <Project>{78619d0e-d3f9-4ddf-b90e-f99cb03dfc44}</Project>
     </ProjectReference>
+    <ProjectReference Include="..\MapAgentCommon\MapAgentCommon.vcxproj">
+      <Project>{2e11e332-cf38-4c8e-999a-29935a63aa89}</Project>
+    </ProjectReference>
     <ProjectReference Include="..\WebApp\WebApp.vcxproj">
       <Project>{b797917b-6842-467c-8b14-e00b76a91247}</Project>
     </ProjectReference>

Modified: sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp
===================================================================
--- sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp	2020-07-24 13:11:35 UTC (rev 9686)
+++ sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp	2020-07-28 10:39:16 UTC (rev 9687)
@@ -28,6 +28,7 @@
 #include <malloc.h>
 #endif
 
+#include "MapAgentCommon.h"
 #include "MapGuideCommon.h"
 #include "HttpHandler.h"
 #include "WebSupport.h"
@@ -68,6 +69,8 @@
 
 void OutputByteReader(httplib::Response& res, MgByteReader* outputReader)
 {
+    //Need to AddRef the reader to make sure it does not prematurely go
+    //out of scope before the chunk handler below is invoked
     MgByteReader* br = SAFE_ADDREF(outputReader);
     std::string sContentType = MgUtil::WideCharToMultiByte(br->GetMimeType());
     res.set_header("Content-Type", sContentType);
@@ -81,6 +84,7 @@
                 nBytes = br->Read(buf, 4096);
             }
             sink.done();
+            //Now we're done with the reader
             br->Release();
             return true;
         }
@@ -191,35 +195,19 @@
     }
 }
 
-bool ParseAuthenticationHeader(MgHttpRequestParam* param, const httplib::Request& req)
+bool ParseAuthenticationHeader(MgHttpRequestParam* params, const httplib::Request& req)
 {
-    //This method decodes and extracts the username and password from the http authentication
-    //header (if it exists) and packs the values into the MgHttpRequestParam object if they
-    //exist
-    auto authHeader = req.get_header_value("Authorization");
-    if (!authHeader.empty())
+    // Check for HTTP Basic Auth header
+    string auth = req.get_header_value("Authorization");
+    bool gotAuth = MapAgentCommon::ParseAuth((char*)auth.c_str(), params);
+
+    if (!gotAuth)
     {
-        //Skip past "Basic "
-        authHeader = authHeader.substr(6);
-        char buffer[256] = { 0 };
-        Base64::Decode((unsigned char*)buffer, authHeader.c_str(), (unsigned long)authHeader.length());
-
-        std::string decoded = buffer;
-        auto cPos = decoded.find(':');
-        if (cPos != std::string::npos)
-        {
-            std::string sUser = decoded.substr(0, cPos);
-            std::string sPass = decoded.substr(cPos + 1);
-
-            STRING username = MgUtil::MultiByteToWideChar(sUser);
-            STRING password = MgUtil::MultiByteToWideChar(sPass);
-
-            param->AddParameter(L"USERNAME", username);
-            param->AddParameter(L"PASSWORD", password);
-            return true;
-        }
+        // And check for a REMOTE_USER remapped header
+        auth = req.get_header_value("REMOTE_USER");
+        gotAuth = MapAgentCommon::ParseAuth((char*)auth.c_str(), params);
     }
-    return false;
+    return gotAuth;
 }
 
 int SendRequest(MgHttpRequest* request, httplib::Response& res)
@@ -270,6 +258,7 @@
             else //Shouldn't get here
             {
                 res.status = 400;
+                result->SetStatusCode(400);
                 std::string errMsg = "Not sure how to output: ";
                 errMsg += resultObj->GetMultiByteClassName();
                 res.set_content(errMsg, contentType.c_str());
@@ -285,6 +274,9 @@
 
 void MapAgentHandler(const httplib::Request& req, httplib::Response& res)
 {
+    std::string logStr;
+    bool bLoggedStatus = false;
+
     bool isGet = req.method == "GET";
     bool isPost = req.method == "POST";
     if (!isGet && !isPost)
@@ -300,7 +292,9 @@
     sUri += std::to_string(port);
     sUri += req.path;
 
-    printf("%s %s", req.method.c_str(), req.path.c_str());
+    logStr += req.method;
+    logStr += " ";
+    logStr += req.path;
 
     MG_TRY()
 
@@ -314,9 +308,6 @@
     //down
     Ptr<MgHttpRequestParam> param = request->GetRequestParam();
 
-    //Extract any parameters from the http authentication header if there is one
-    bool bGotAuth = ParseAuthenticationHeader(param, req);
-
     if (isGet)
     {
         PopulateGetRequest(param, req);
@@ -326,26 +317,40 @@
         PopulatePostRequest(param, req);
     }
 
-    //A request is valid if it contains any of the following:
-    //
-    // 1. A SESSION parameter
-    // 2. A USERNAME parameter (PASSWORD optional). If not specified the http authentication header is checked and extracted if found
-    //
-    //Whether these values are valid will be determined by MgSiteConnection in the MgHttpRequest handler when we come to execute it
-    bool bValid = param->ContainsParameter(L"SESSION");
-    if (!bValid)
-        bValid = param->ContainsParameter(L"USERNAME");
+    //Extract any parameters from the http authentication header if there is one
+    bool bGotAuth = ParseAuthenticationHeader(param, req);
 
-    if (!bValid)
+    bool bIsOgcRequest = false;
+    STRING opName;
+
+    auto ogcSvc = param->GetParameterValue(L"SERVICE");
+    auto ogcReq = param->GetParameterValue(L"REQUEST");
+    if (!ogcSvc.empty() && !ogcReq.empty())
     {
-        HandleUnauthorized(res);
-        printf(" - %d\n", 401);
-        return;
+        opName = ogcSvc;
+        opName += L".";
+        opName += ogcReq;
+        bIsOgcRequest = true;
     }
+    else
+    {
+        opName = param->GetParameterValue(L"OPERATION");
+    }
+    auto opv = param->GetParameterValue(L"VERSION");
 
+    logStr += " ";
+    logStr += MgUtil::WideCharToMultiByte(opName);
+    logStr += " (";
+    logStr += MgUtil::WideCharToMultiByte(opv);
+    logStr += ")";
+
     auto status = SendRequest(request, res);
 
-    printf(" - %d\n", status);
+    logStr += " - ";
+    std::string sStatus;
+    MgUtil::Int32ToString(status, sStatus);
+    logStr += sStatus;
+    bLoggedStatus = true;
 
     MG_CATCH(L"MapAgentHandler")
 
@@ -352,7 +357,16 @@
     if (mgException != nullptr)
     {
         HandleMgException(mgException, res);
+        if (!bLoggedStatus)
+        {
+            logStr += " - ";
+            std::string sStatus;
+            MgUtil::Int32ToString(res.status, sStatus);
+            logStr += sStatus;
+        }
     }
+
+    printf("%s\n", logStr.c_str());
 }
 
 int main(int argc, char** argv)



More information about the mapguide-commits mailing list