Merge pull request #5095 from koying/fixdroidappcrash
[vuplus_xbmc] / xbmc / filesystem / DAVFile.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "system.h"
22
23 #include "DAVFile.h"
24
25 #include "DAVCommon.h"
26 #include "URL.h"
27 #include "utils/log.h"
28 #include "DllLibCurl.h"
29 #include "utils/XBMCTinyXML.h"
30 #include "utils/RegExp.h"
31
32 using namespace XFILE;
33 using namespace XCURL;
34
35 CDAVFile::CDAVFile(void)
36   : CCurlFile()
37   , lastResponseCode(0)
38 {
39 }
40
41 CDAVFile::~CDAVFile(void)
42 {
43 }
44
45 bool CDAVFile::Execute(const CURL& url)
46 {
47   CURL url2(url);
48   ParseAndCorrectUrl(url2);
49
50   CLog::Log(LOGDEBUG, "CDAVFile::Execute(%p) %s", (void*)this, m_url.c_str());
51
52   ASSERT(!(!m_state->m_easyHandle ^ !m_state->m_multiHandle));
53   if( m_state->m_easyHandle == NULL )
54     g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle );
55
56   // setup common curl options
57   SetCommonOptions(m_state);
58   SetRequestHeaders(m_state);
59
60   lastResponseCode = m_state->Connect(m_bufferSize);
61   if( lastResponseCode < 0 || lastResponseCode >= 400)
62     return false;
63
64   char* efurl;
65   if (CURLE_OK == g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_EFFECTIVE_URL,&efurl) && efurl)
66     m_url = efurl;
67
68   if (lastResponseCode == 207)
69   {
70     CStdString strResponse;
71     ReadData(strResponse);
72
73     CXBMCTinyXML davResponse;
74     davResponse.Parse(strResponse);
75
76     if (!davResponse.Parse(strResponse))
77     {
78       CLog::Log(LOGERROR, "%s - Unable to process dav response (%s)", __FUNCTION__, m_url.c_str());
79       Close();
80       return false;
81     }
82
83     TiXmlNode *pChild;
84     // Iterate over all responses
85     for (pChild = davResponse.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
86     {
87       if (CDAVCommon::ValueWithoutNamespace(pChild, "response"))
88       {
89         CStdString sRetCode = CDAVCommon::GetStatusTag(pChild->ToElement());
90         CRegExp rxCode;
91         rxCode.RegComp("HTTP/1\\.1\\s(\\d+)\\s.*"); 
92         if (rxCode.RegFind(sRetCode) >= 0)
93         {
94           if (rxCode.GetSubCount())
95           {
96             lastResponseCode = atoi(rxCode.GetMatch(1).c_str());
97             if( lastResponseCode < 0 || lastResponseCode >= 400)
98               return false;
99           }
100         }
101
102       }
103     }
104   }
105
106   return true;
107 }
108
109 bool CDAVFile::Delete(const CURL& url)
110 {
111   if (m_opened)
112     return false;
113
114   CDAVFile dav;
115   CStdString strRequest = "DELETE";
116
117   dav.SetCustomRequest(strRequest);
118  
119   if (!dav.Execute(url))
120   {
121     CLog::Log(LOGERROR, "%s - Unable to delete dav resource (%s)", __FUNCTION__, url.Get().c_str());
122     return false;
123   }
124
125   dav.Close();
126
127   return true;
128 }
129
130 bool CDAVFile::Rename(const CURL& url, const CURL& urlnew)
131 {
132   if (m_opened)
133     return false;
134
135   CDAVFile dav;
136
137   CURL url2(urlnew);
138   CStdString strProtocol = url2.GetTranslatedProtocol();
139   url2.SetProtocol(strProtocol);
140
141   CStdString strRequest = "MOVE";
142   dav.SetCustomRequest(strRequest);
143   dav.SetRequestHeader("Destination", url2.GetWithoutUserDetails());
144
145   if (!dav.Execute(url))
146   {
147     CLog::Log(LOGERROR, "%s - Unable to rename dav resource (%s)", __FUNCTION__, url.Get().c_str());
148     return false;
149   }
150
151   dav.Close();
152
153   return true;
154 }