[mapguide-commits] r7274 - sandbox/jng/streaming/Web/src/CgiAgent

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Dec 17 00:04:46 PST 2012


Author: jng
Date: 2012-12-17 00:04:46 -0800 (Mon, 17 Dec 2012)
New Revision: 7274

Added:
   sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.cpp
   sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.h
Modified:
   sandbox/jng/streaming/Web/src/CgiAgent/CgiAgent.vcxproj
   sandbox/jng/streaming/Web/src/CgiAgent/CgiResponseHandler.cpp
Log:
#2194: Add CGI implementation of MgHttpReaderStreamer. As printf is the http output mechanism, we have to escape any '%' characters in the chunks we're writing out. All 3 implementations (Apache/ISAPI/CGI) have been verified to produce the same identical xml and json responses.

Modified: sandbox/jng/streaming/Web/src/CgiAgent/CgiAgent.vcxproj
===================================================================
--- sandbox/jng/streaming/Web/src/CgiAgent/CgiAgent.vcxproj	2012-12-17 05:40:35 UTC (rev 7273)
+++ sandbox/jng/streaming/Web/src/CgiAgent/CgiAgent.vcxproj	2012-12-17 08:04:46 UTC (rev 7274)
@@ -190,6 +190,7 @@
   <ItemGroup>
     <ClCompile Include="CgiAgent.cpp" />
     <ClCompile Include="CgiPostParser.cpp" />
+    <ClCompile Include="CgiReaderStreamer.cpp" />
     <ClCompile Include="CgiResponseHandler.cpp" />
     <ClCompile Include="EchoTest.cpp" />
   </ItemGroup>
@@ -198,6 +199,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="CgiPostParser.h" />
+    <ClInclude Include="CgiReaderStreamer.h" />
     <ClInclude Include="CgiResponseHandler.h" />
   </ItemGroup>
   <ItemGroup>

Added: sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.cpp
===================================================================
--- sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.cpp	                        (rev 0)
+++ sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.cpp	2012-12-17 08:04:46 UTC (rev 7274)
@@ -0,0 +1,66 @@
+#include "CgiReaderStreamer.h"
+#include "MapAgentStrings.h"
+
+extern void DumpMessage(const char* format, ...);
+extern void DumpMessage2(const char* msg);
+
+CgiReaderStreamer::CgiReaderStreamer(MgReader* reader, CREFSTRING format) :
+    MgHttpReaderStreamer(reader, format),
+    m_bEndOfStream(false)
+{
+}
+
+CgiReaderStreamer::~CgiReaderStreamer() 
+{ 
+    EndStream();
+}
+
+void CgiReaderStreamer::EndStream()
+{
+    if (!m_bEndOfStream)
+    {
+        //Write end of chunked response
+        printf("0\r\n\r\n");
+        m_bEndOfStream = true;
+    }
+}
+
+void CgiReaderStreamer::SetChunkedEncoding() 
+{
+    printf("Connection: Keep-Alive");
+    printf(MapAgentStrings::CrLf);
+    printf("Transfer-Encoding: chunked");
+    printf(MapAgentStrings::CrLf);
+    printf(MapAgentStrings::CrLf);
+}
+
+void CgiReaderStreamer::WriteChunk(const char* str, size_t length)
+{
+    /*
+    std::string logStr = "BEGIN - CgiReaderStreamer::WriteChunk";
+    logStr.append(" str='");
+    logStr.append(str);
+    logStr.append("', length=");
+    MgUtil::ReplaceString("%", "%%", logStr, -1);
+    std::string lengthStr;
+    MgUtil::Int32ToString(length, lengthStr);
+    logStr.append(lengthStr);
+    DumpMessage(logStr.c_str());
+    */
+    
+    m_hexLen.clear();
+    MgUtil::Int32ToHexString(length, m_hexLen);
+    m_hexLen.append(MapAgentStrings::CrLf);
+
+    printf(m_hexLen.c_str());
+    //---- BEGIN chunk body ----//
+    //Need to escape any characters that may trip up printf
+    //Currently it is: '%'
+    m_sCurrentChunk.clear();
+    m_sCurrentChunk = str;
+    MgUtil::ReplaceString("%", "%%", m_sCurrentChunk, -1);
+    printf(m_sCurrentChunk.c_str());
+    //---- END chunk body ----//
+    printf(MapAgentStrings::CrLf);
+    //DumpMessage("END - CgiReaderStreamer::WriteChunk");
+}
\ No newline at end of file

Added: sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.h
===================================================================
--- sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.h	                        (rev 0)
+++ sandbox/jng/streaming/Web/src/CgiAgent/CgiReaderStreamer.h	2012-12-17 08:04:46 UTC (rev 7274)
@@ -0,0 +1,41 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef CGI_READER_STREAMER_H
+#define CGI_READER_STREAMER_H
+
+#include "MapGuideCommon.h"
+#include "HttpHandler.h"
+
+class CgiReaderStreamer : public MgHttpReaderStreamer
+{
+public:
+    CgiReaderStreamer(MgReader* reader, CREFSTRING format);
+    virtual ~CgiReaderStreamer();
+
+protected:
+    virtual void SetChunkedEncoding();
+    virtual void WriteChunk(const char* str, size_t length);
+    virtual void EndStream();
+
+private:
+    bool m_bEndOfStream;
+    std::string m_hexLen;
+    std::string m_sCurrentChunk;
+};
+
+#endif
\ No newline at end of file

Modified: sandbox/jng/streaming/Web/src/CgiAgent/CgiResponseHandler.cpp
===================================================================
--- sandbox/jng/streaming/Web/src/CgiAgent/CgiResponseHandler.cpp	2012-12-17 05:40:35 UTC (rev 7273)
+++ sandbox/jng/streaming/Web/src/CgiAgent/CgiResponseHandler.cpp	2012-12-17 08:04:46 UTC (rev 7274)
@@ -19,6 +19,7 @@
 #include "HttpHandler.h"
 #include "HttpPrimitiveValue.h"
 #include "CgiResponseHandler.h"
+#include "CgiReaderStreamer.h"
 #include "MapAgentStrings.h"
 
 #include <stdlib.h>
@@ -101,6 +102,7 @@
             printf(MapAgentStrings::ContentTypeHeader, MapAgentStrings::TextPlain, MapAgentStrings::Utf8Text);
         }
 
+        Ptr<MgReader> outputDataReader;
         Ptr<MgByteReader> outputReader;
         Ptr<MgDisposable> resultObj = result->GetResultObject();
         MgDisposable* pResultObj = (MgDisposable*)resultObj;
@@ -111,7 +113,7 @@
         }
         else if (NULL != dynamic_cast<MgFeatureReader*>(pResultObj))
         {
-            outputReader = ((MgFeatureReader*)pResultObj)->ToXml();
+            outputDataReader = SAFE_ADDREF((MgFeatureReader*)pResultObj); //Need to AddRef because there's now 2 references on this pointer
         }
         else if (NULL != dynamic_cast<MgStringCollection*>(pResultObj))
         {
@@ -119,11 +121,11 @@
         }
         else if (NULL != dynamic_cast<MgSqlDataReader*>(pResultObj))
         {
-            outputReader = ((MgSqlDataReader*)pResultObj)->ToXml();
+            outputDataReader = SAFE_ADDREF((MgSqlDataReader*)pResultObj); //Need to AddRef because there's now 2 references on this pointer
         }
         else if (NULL != dynamic_cast<MgDataReader*>(pResultObj))
         {
-            outputReader = ((MgDataReader*)pResultObj)->ToXml();
+            outputDataReader = SAFE_ADDREF((MgDataReader*)pResultObj); //Need to AddRef because there's now 2 references on this pointer
         }
         else if (NULL != dynamic_cast<MgSpatialContextReader*>(pResultObj))
         {
@@ -144,6 +146,11 @@
             printf(MapAgentStrings::ContentLengthHeader, utf8.length());
             printf("\r\n%s",utf8.c_str());
         }
+        else if (outputDataReader != NULL)
+        {
+            CgiReaderStreamer crs(outputDataReader, result->GetResultContentType());
+            crs.StreamResult();
+        }
         else if (outputReader != NULL)
         {
             INT64 outLen = outputReader->GetLength();
@@ -172,6 +179,8 @@
     MG_TRY()
     STRING shortError = e->GetExceptionMessage();
     STRING longError = e->GetDetails();
+    longError += L"\n";
+    longError += e->GetStackTrace();
     STRING statusMessage = e->GetClassName();
 
     //TODO: Use a string resource for html error text format



More information about the mapguide-commits mailing list