Provide IFile consumers a rudimentary HTTP POST option via a CurlFile sub-class calle...
authorRed-F <tv@hoogduin.net>
Mon, 8 Oct 2012 20:09:11 +0000 (22:09 +0200)
committerFred Hoogduin <tv@hoogduin.net>
Tue, 23 Oct 2012 18:33:28 +0000 (20:33 +0200)
Implements IFile's OpenForWrite and Write methods to POST data with Content-Type set to "Application/Json"

project/VS2010Express/XBMC.vcxproj
project/VS2010Express/XBMC.vcxproj.filters
xbmc/filesystem/CurlFile.cpp
xbmc/filesystem/CurlFile.h
xbmc/filesystem/FileFactory.cpp
xbmc/filesystem/HTTPFile.cpp [new file with mode: 0644]
xbmc/filesystem/HTTPFile.h [new file with mode: 0644]
xbmc/filesystem/Makefile.in

index 4c7824d..c0a8a35 100644 (file)
     <ClCompile Include="..\..\xbmc\filesystem\HTSPDirectory.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\HTSPSession.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\HTTPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HTTPFile.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\IDirectory.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\IFile.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\ImageFile.cpp" />
     <ClInclude Include="..\..\xbmc\dialogs\GUIDialogKeyboardGeneric.h" />
     <ClInclude Include="..\..\xbmc\DbUrl.h" />
     <ClInclude Include="..\..\xbmc\dialogs\GUIDialogMediaFilter.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HTTPFile.h" />
     <ClInclude Include="..\..\xbmc\filesystem\ImageFile.h" />
     <ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeTags.h" />
     <ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" />
index b471ebf..cf1711e 100644 (file)
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\PVROperations.cpp">
       <Filter>interfaces\json-rpc</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HTTPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\xbmc\win32\pch.h">
     <ClInclude Include="..\..\xbmc\interfaces\json-rpc\PVROperations.h">
       <Filter>interfaces\json-rpc</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HTTPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
index 5878786..143716e 100644 (file)
@@ -322,11 +322,13 @@ CCurlFile::CCurlFile()
   m_bufferSize = 32768;
   m_binary = true;
   m_postdata = "";
+  m_postdataset = false;
   m_username = "";
   m_password = "";
   m_httpauth = "";
   m_state = new CReadState();
   m_skipshout = false;
+  m_httpresponse = -1;
 }
 
 //Has to be called before Open()
@@ -423,8 +425,8 @@ void CCurlFile::SetCommonOptions(CReadState* state)
   g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_URL, m_url.c_str());
   g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TRANSFERTEXT, FALSE);
 
-  // setup POST data if it exists
-  if (!m_postdata.IsEmpty())
+  // setup POST data if it is set (and it may be empty)
+  if (m_postdataset)
   {
     g_curlInterface.easy_setopt(h, CURLOPT_POST, 1 );
     g_curlInterface.easy_setopt(h, CURLOPT_POSTFIELDSIZE, m_postdata.length());
@@ -741,6 +743,7 @@ bool CCurlFile::Get(const CStdString& strURL, CStdString& strHTML)
 bool CCurlFile::Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML)
 {
   m_postdata = strPostData;
+  m_postdataset = true;
   if (Open(strURL))
   {
     if (ReadData(strHTML))
@@ -840,8 +843,8 @@ bool CCurlFile::Open(const CURL& url)
   SetCommonOptions(m_state);
   SetRequestHeaders(m_state);
 
-  long response = m_state->Connect(m_bufferSize);
-  if( response < 0 || response >= 400)
+  m_httpresponse = m_state->Connect(m_bufferSize);
+  if( m_httpresponse < 0 || m_httpresponse >= 400)
     return false;
 
   SetCorrectHeaders(m_state);
index cc16dde..3ad10b2 100644 (file)
@@ -70,7 +70,7 @@ namespace XFILE
       void SetPostData(CStdString postdata)                      { m_postdata = postdata; }
       void SetReferer(CStdString referer)                        { m_referer = referer; }
       void SetCookie(CStdString cookie)                          { m_cookie = cookie; }
-      void SetMimeType(CStdString mimetype)                      { SetRequestHeader("Content-Type", m_mimetype); }
+      void SetMimeType(CStdString mimetype)                      { SetRequestHeader("Content-Type", mimetype); }
       void SetRequestHeader(CStdString header, CStdString value);
       void SetRequestHeader(CStdString header, long value);
 
@@ -125,7 +125,7 @@ namespace XFILE
       void SetCorrectHeaders(CReadState* state);
       bool Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML);
 
-    private:
+    protected:
       CReadState*     m_state;
       unsigned int    m_bufferSize;
 
@@ -141,7 +141,6 @@ namespace XFILE
       CStdString      m_postdata;
       CStdString      m_referer;
       CStdString      m_cookie;
-      CStdString      m_mimetype;
       CStdString      m_username;
       CStdString      m_password;
       CStdString      m_httpauth;
@@ -153,6 +152,7 @@ namespace XFILE
       bool            m_seekable;
       bool            m_multisession;
       bool            m_skipshout;
+      bool            m_postdataset;
 
       CRingBuffer     m_buffer;           // our ringhold buffer
       char *          m_overflowBuffer;   // in the rare case we would overflow the above buffer
@@ -165,6 +165,8 @@ namespace XFILE
 
       typedef std::map<CStdString, CStdString> MAPHTTPHEADERS;
       MAPHTTPHEADERS m_requestheaders;
+
+      long            m_httpresponse;
   };
 }
 
index d67194a..09482c7 100644 (file)
@@ -26,6 +26,7 @@
 #include "FileFactory.h"
 #include "HDFile.h"
 #include "CurlFile.h"
+#include "HTTPFile.h"
 #include "ShoutcastFile.h"
 #include "LastFMFile.h"
 #include "FileReaderFile.h"
@@ -144,13 +145,12 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
 
   if( g_application.getNetwork().IsAvailable() )
   {
-    if (strProtocol == "http"
-    ||  strProtocol == "https"
-    ||  strProtocol == "dav"
+    if (strProtocol == "dav"
     ||  strProtocol == "davs"
     ||  strProtocol == "ftp"
     ||  strProtocol == "ftps"
     ||  strProtocol == "rss") return new CCurlFile();
+    else if (strProtocol == "http" ||  strProtocol == "https") return new CHTTPFile();
 #ifdef HAS_FILESYSTEM_SFTP
     else if (strProtocol == "sftp" || strProtocol == "ssh") return new CSFTPFile();
 #endif
diff --git a/xbmc/filesystem/HTTPFile.cpp b/xbmc/filesystem/HTTPFile.cpp
new file mode 100644 (file)
index 0000000..fb42482
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *      Copyright (C) 2005-2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "HTTPFile.h"
+
+using namespace XFILE;
+
+CHTTPFile::CHTTPFile(void)
+{
+  m_openedforwrite = false;
+}
+
+
+CHTTPFile::~CHTTPFile(void)
+{
+}
+
+bool CHTTPFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  // real Open is delayed until we receive the POST data
+  m_urlforwrite = url;
+  m_openedforwrite = true;
+  return true;
+}
+
+int CHTTPFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  // Although we can not verify much, try to catch errors where we can
+  if (!m_openedforwrite)
+    return -1;
+
+  CStdString myPostData((char*) lpBuf);
+  if (myPostData.length() != uiBufSize)
+    return -1;
+
+  // If we get here, we (most likely) satisfied the pre-conditions that we used OpenForWrite and passed a string as postdata
+  // we mimic 'post(..)' but do not read any data
+  m_postdata = myPostData;
+  m_postdataset = true;
+  m_openedforwrite = false;
+  SetMimeType("application/json");
+  if (!Open(m_urlforwrite))
+    return -1;
+
+  // Finally (and this is a clumsy hack) return the http response code
+  return (int) m_httpresponse;
+}
+
diff --git a/xbmc/filesystem/HTTPFile.h b/xbmc/filesystem/HTTPFile.h
new file mode 100644 (file)
index 0000000..06e9a27
--- /dev/null
@@ -0,0 +1,38 @@
+#pragma once
+/*
+*      Copyright (C) 2005-2012 Team XBMC
+*      http://www.xbmc.org
+*
+*  This Program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2, or (at your option)
+*  any later version.
+*
+*  This Program 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 General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with XBMC; see the file COPYING.  If not, see
+*  <http://www.gnu.org/licenses/>.
+*
+*/
+
+#include "CurlFile.h"
+#include "URL.h"
+
+namespace XFILE
+{
+  class CHTTPFile : public CCurlFile
+  {
+  public:
+    CHTTPFile(void);
+    virtual ~CHTTPFile(void);
+    virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+    virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  private:
+    bool            m_openedforwrite;
+    CURL            m_urlforwrite;
+  };
+}
index 0ac0cac..8c337eb 100644 (file)
@@ -29,6 +29,7 @@ SRCS += HDHomeRunFile.cpp
 SRCS += HTSPDirectory.cpp
 SRCS += HTSPSession.cpp
 SRCS += HTTPDirectory.cpp
+SRCS += HTTPFile.cpp
 SRCS += IDirectory.cpp
 SRCS += IFile.cpp
 SRCS += ImageFile.cpp