[mapguide-commits] r9688 - sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Tue Jul 28 05:12:15 PDT 2020
Author: jng
Date: 2020-07-28 05:12:15 -0700 (Tue, 28 Jul 2020)
New Revision: 9688
Modified:
sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp
Log:
When using MgDevHttpServer with Maestro, it blows up running certain operations. Further analysis shows that our POST handler needed to be able to take and process a content reader if given one, otherwise the routing engine treats this as no handler being matched and returns HTTP 400 back to the client.
Modified: sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp
===================================================================
--- sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp 2020-07-28 10:39:16 UTC (rev 9687)
+++ sandbox/jng/ogc_viewer_representation/Web/src/DevHttpServer/main.cpp 2020-07-28 12:12:15 UTC (rev 9688)
@@ -28,10 +28,11 @@
#include <malloc.h>
#endif
-#include "MapAgentCommon.h"
#include "MapGuideCommon.h"
#include "HttpHandler.h"
#include "WebSupport.h"
+#include "MapAgentCommon.h"
+#include "MapAgentStrings.h"
#include "Base64.h"
int port = 8000;
@@ -162,35 +163,104 @@
}
}
-void PopulatePostRequest(MgHttpRequestParam* param, const httplib::Request& req)
+bool StrEndsWith(std::string const& fullString, std::string const& ending)
{
- for (const auto& p : req.params)
+ if (fullString.length() >= ending.length())
{
- STRING key = MgUtil::MultiByteToWideChar(p.first);
- STRING value = MgUtil::MultiByteToWideChar(p.second);
- param->AddParameter(key, value);
+ return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
}
+ else
+ {
+ return false;
+ }
+}
- for (const auto& f : req.files)
+void PopulatePostRequest(MgHttpRequestParam* param, const httplib::Request& req, const httplib::ContentReader* contentReader = nullptr)
+{
+ if (contentReader != nullptr)
{
- STRING key = MgUtil::MultiByteToWideChar(f.first);
- auto file = f.second;
- if (file.filename.empty())
+ if (req.is_multipart_form_data())
{
- STRING value = MgUtil::MultiByteToWideChar(file.content);
- param->AddParameter(key, value);
+ httplib::MultipartFormDataItems files;
+ (*contentReader)(
+ [&](const httplib::MultipartFormData& file) {
+ files.push_back(file);
+ return true;
+ },
+ [&](const char* data, size_t data_length) {
+ files.back().content.append(data, data_length);
+ return true;
+ });
+ for (const auto& f : files)
+ {
+ STRING key;
+ if (StrEndsWith(f.name, "\";"))
+ {
+ key = MgUtil::MultiByteToWideChar(f.name.substr(0, f.name.length() - 2));
+ }
+ else
+ {
+ key = MgUtil::MultiByteToWideChar(f.name);
+ }
+ if (f.filename.empty())
+ {
+ STRING value = MgUtil::MultiByteToWideChar(f.content);
+ param->AddParameter(key, value);
+ }
+ else
+ {
+ STRING fileName = MgFileUtil::GenerateTempFileName();
+ Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)f.content.c_str(), (INT32)f.content.length());
+ Ptr<MgByteReader> reader = byteSource->GetReader();
+ Ptr<MgByteSink> sink = new MgByteSink(reader);
+ sink->ToFile(fileName);
+
+ param->AddParameter(key, fileName);
+ //tempfile is a hint to the MgHttpRequest for it to create a MgByteSource from it
+ param->SetParameterType(key, MapAgentStrings::TempfileKey);
+ }
+ }
}
else
{
- STRING fileName = MgFileUtil::GenerateTempFileName();
- Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)file.content.c_str(), (INT32)file.content.length());
- Ptr<MgByteReader> reader = byteSource->GetReader();
- Ptr<MgByteSink> sink = new MgByteSink(reader);
- sink->ToFile(fileName);
+ std::string body;
+ (*contentReader)([&](const char* data, size_t data_length) {
+ body.append(data, data_length);
+ return true;
+ });
+ param->SetXmlPostData(body.c_str());
+ }
+ }
+ else
+ {
+ for (const auto& p : req.params)
+ {
+ STRING key = MgUtil::MultiByteToWideChar(p.first);
+ STRING value = MgUtil::MultiByteToWideChar(p.second);
+ param->AddParameter(key, value);
+ }
- param->AddParameter(key, fileName);
- //tempfile is a hint to the MgHttpRequest for it to create a MgByteSource from it
- param->SetParameterType(key, L"tempfile");
+ for (const auto& f : req.files)
+ {
+ STRING key = MgUtil::MultiByteToWideChar(f.first);
+ auto file = f.second;
+ if (file.filename.empty())
+ {
+ STRING value = MgUtil::MultiByteToWideChar(file.content);
+ param->AddParameter(key, value);
+ }
+ else
+ {
+ STRING fileName = MgFileUtil::GenerateTempFileName();
+ Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)file.content.c_str(), (INT32)file.content.length());
+ Ptr<MgByteReader> reader = byteSource->GetReader();
+ Ptr<MgByteSink> sink = new MgByteSink(reader);
+ sink->ToFile(fileName);
+
+ param->AddParameter(key, fileName);
+ //tempfile is a hint to the MgHttpRequest for it to create a MgByteSource from it
+ param->SetParameterType(key, MapAgentStrings::TempfileKey);
+ }
}
}
}
@@ -272,7 +342,7 @@
return result->GetStatusCode();
}
-void MapAgentHandler(const httplib::Request& req, httplib::Response& res)
+void MapAgentHandlerInternal(const httplib::Request& req, httplib::Response& res, const httplib::ContentReader* contentReader = nullptr)
{
std::string logStr;
bool bLoggedStatus = false;
@@ -314,7 +384,7 @@
}
else if (isPost)
{
- PopulatePostRequest(param, req);
+ PopulatePostRequest(param, req, contentReader);
}
//Extract any parameters from the http authentication header if there is one
@@ -369,6 +439,16 @@
printf("%s\n", logStr.c_str());
}
+void MapAgentHandlerWithContentReader(const httplib::Request& req, httplib::Response& res, const httplib::ContentReader& content_reader)
+{
+ MapAgentHandlerInternal(req, res, &content_reader);
+}
+
+void MapAgentHandlerWithoutContentReader(const httplib::Request& req, httplib::Response& res)
+{
+ MapAgentHandlerInternal(req, res);
+}
+
int main(int argc, char** argv)
{
#ifdef _WIN32
@@ -404,8 +484,9 @@
g_server->set_mount_point("/mapguide", "./wwwroot");
- g_server->Post("/mapguide/mapagent/mapagent.fcgi", MapAgentHandler);
- g_server->Get("/mapguide/mapagent/mapagent.fcgi", MapAgentHandler);
+ g_server->Post("/mapguide/mapagent/mapagent.fcgi", MapAgentHandlerWithContentReader);
+ g_server->Post("/mapguide/mapagent/mapagent.fcgi", MapAgentHandlerWithoutContentReader);
+ g_server->Get("/mapguide/mapagent/mapagent.fcgi", MapAgentHandlerWithoutContentReader);
printf("Listening on port %d\n", port);
More information about the mapguide-commits
mailing list