00001
00002
00003
00004
00005
00006 #include "fsHttpFiles.h"
00007 #include "fsURL.h"
00008 #include "common.h"
00009 #include <limits.h>
00010 #include "fsHTMLParser.h"
00011
00012 fsHttpFiles::fsHttpFiles()
00013 {
00014 m_pszFileBuffer = NULL;
00015 m_bGetInfo = TRUE;
00016 m_pfnEvents = NULL;
00017 }
00018
00019 fsHttpFiles::~fsHttpFiles()
00020 {
00021 SAFE_DELETE_ARRAY (m_pszFileBuffer);
00022 }
00023
00024 fsInternetResult fsHttpFiles::GetList(LPCSTR pszPath)
00025 {
00026 fsInternetResult ir;
00027 BOOL bRedirected = FALSE;
00028
00029 m_bAbort = FALSE;
00030
00031 m_strPath = pszPath;
00032 LPSTR pszNewUrl;
00033
00034 m_httpFile.UseSecure (m_bUseSecure);
00035
00036 BOOL bRel;
00037
00038
00039 ir = fsHttpOpenPath (pszPath, m_pServer, &m_httpFile, &pszNewUrl, &bRel);
00040 if (ir != IR_SUCCESS)
00041 return ir;
00042
00043 Event (HFE_CONNECTED);
00044
00045 if (pszNewUrl)
00046 {
00047 if (bRel == FALSE)
00048 {
00049
00050
00051 fsURL url;
00052 ir = url.Crack (pszNewUrl);
00053 if (ir != IR_SUCCESS)
00054 return ir;
00055
00056 m_strPath = url.GetPath ();
00057
00058 bRedirected = TRUE;
00059 }
00060 else
00061 m_strPath = pszNewUrl;
00062
00063 delete [] pszNewUrl;
00064 }
00065
00066
00067
00068 ir = LoadFile ();
00069 if (ir != IR_SUCCESS)
00070 return ir;
00071
00072 Event (HFE_FILELISTREAD);
00073
00074 Event (HFE_STARTBUILDLIST);
00075
00076 ir = BuildFileList ();
00077 if (ir != IR_SUCCESS)
00078 return ir;
00079
00080 Event (HFE_FINISHBUILDLIST);
00081
00082 return bRedirected ? IR_S_REDIRECTED : IR_SUCCESS;
00083 }
00084
00085 fsInternetResult fsHttpFiles::LoadFile()
00086 {
00087 UINT uToRead = 1000;
00088 const FLOAT fInc = 1.2f;
00089
00090 fsInternetResult ir;
00091
00092 UINT64 uFileSize = m_httpFile.GetFileSize ();
00093 UINT64 uMax = uFileSize;
00094 UINT64 uPos = 0;
00095 DWORD dwRead;
00096
00097 if (uMax == _UI64_MAX)
00098 uMax = 100000;
00099
00100 SAFE_DELETE_ARRAY (m_pszFileBuffer);
00101
00102 fsnew (m_pszFileBuffer, char, int (uMax+1));
00103
00104 int cZeroReads = 0;
00105
00106 do
00107 {
00108 if (uToRead > uFileSize - uPos)
00109 uToRead = UINT (uFileSize - uPos);
00110
00111 if (uPos + uToRead > uMax)
00112 {
00113
00114
00115 uMax = UINT64 ((INT64)uMax * fInc);
00116
00117
00118 LPSTR psz = 0;
00119 fsnew (psz, char, int (uMax+1));
00120 CopyMemory (psz, m_pszFileBuffer, UINT (uPos));
00121 delete [] m_pszFileBuffer;
00122 m_pszFileBuffer = psz;
00123 }
00124
00125 ir = m_httpFile.Read (LPBYTE (m_pszFileBuffer+uPos), uToRead, &dwRead);
00126 if (ir != IR_SUCCESS)
00127 {
00128 delete m_pszFileBuffer;
00129 return ir;
00130 }
00131
00132 uPos += dwRead;
00133
00134 if (dwRead == 0)
00135 {
00136 cZeroReads ++;
00137 if (cZeroReads < 3 && uFileSize != _UI64_MAX)
00138 dwRead = 1;
00139 }
00140 else
00141 cZeroReads = 0;
00142
00143 }
00144 while (dwRead && m_bAbort == FALSE);
00145
00146 if (m_bAbort)
00147 return IR_S_FALSE;
00148
00149 if (uFileSize != _UI64_MAX && uFileSize != uPos)
00150 return IR_WININETUNKERROR;
00151
00152 m_pszFileBuffer [m_uFileLen = uPos] = 0;
00153
00154 m_httpFile.CloseHandle ();
00155
00156 return IR_SUCCESS;
00157 }
00158
00159 fsInternetResult fsHttpFiles::BuildFileList()
00160 {
00161 fsHTMLParser html;
00162
00163 html.ParseHTML (m_pszFileBuffer);
00164
00165 m_pszBaseURL = html.Get_BaseURL ();
00166
00167 UINT cUrls = html.GetUrlCount ();
00168
00169 m_vFiles.clear ();
00170
00171 fsURL url;
00172 CHAR szUrl [10000];
00173 DWORD dwLen = 10000;
00174 url.Create (INTERNET_SCHEME_HTTP, m_pServer->GetServerName (), m_pServer->GetServerPort (),
00175 NULL, NULL, m_strPath, szUrl, &dwLen);
00176 m_strFullPath = szUrl;
00177
00178 for (UINT i = 0; i < cUrls && m_bAbort == FALSE; i++)
00179 {
00180 fsFileInfo file;
00181 LPCSTR pszUrl = html.GetUrl (i);
00182 fsURL url;
00183 if (url.Crack (pszUrl, FALSE) == IR_SUCCESS)
00184 {
00185 INTERNET_SCHEME scheme = url.GetInternetScheme ();
00186
00187 if (scheme != INTERNET_SCHEME_HTTP && scheme != INTERNET_SCHEME_HTTPS && scheme != INTERNET_SCHEME_FTP)
00188 continue;
00189 }
00190
00191 file.bAvailable = TRUE;
00192 file.bFolder = FALSE;
00193
00194
00195 LPCSTR ppszBadUrls [] = {"/..", "../", "./", "/.", "\\..", "..\\", ".\\", "\\."};
00196 BOOL bBad = FALSE;
00197
00198 for (int s = 0; s < sizeof (ppszBadUrls) / sizeof (LPSTR); s++)
00199 {
00200 if (strcmp (pszUrl, ppszBadUrls [s]) == 0)
00201 {
00202 bBad = TRUE;
00203 break;
00204 }
00205 }
00206
00207 if (bBad)
00208 continue;
00209
00210 CalcUrl (&file, pszUrl);
00211 CheckFolder (&file);
00212
00213
00214 if (m_bGetInfo == FALSE || GetUrlInfo (pszUrl, &file) != IR_SUCCESS)
00215 {
00216 CalcUrl (&file, pszUrl);
00217 file.date.dwHighDateTime = file.date.dwLowDateTime = UINT_MAX;
00218 file.uSize = _UI64_MAX;
00219 }
00220
00221
00222 if (file.strName.Length () == 0)
00223 continue;
00224
00225 m_vFiles.add (file);
00226 }
00227
00228 m_strFullPath = NULL;
00229
00230 if (m_bAbort)
00231 m_vFiles.clear ();
00232
00233 return m_bAbort ? IR_S_FALSE : IR_SUCCESS;
00234 }
00235
00236 fsInternetResult fsHttpFiles::GetUrlInfo(LPCSTR pszUrl, fsFileInfo *pInfo)
00237 {
00238 fsInternetResult ir;
00239
00240 pInfo->strName = pszUrl;
00241
00242 if (pInfo->bFolder)
00243 return IR_SUCCESS;
00244
00245 m_hUI_server.Initialize (m_pServer->GetSession ());
00246
00247
00248 if (m_bAbort)
00249 return IR_S_FALSE;
00250
00251 m_hUI_file.UseSecure (m_bUseSecure);
00252
00253 fsURL url;
00254
00255 LPSTR pszNewUrl = NULL;
00256 BOOL bRedirInner;
00257
00258 if (url.Crack (pszUrl) == IR_SUCCESS)
00259 {
00260
00261 ir = fsHttpOpenUrl (pszUrl, url.GetUserName (), url.GetPassword (), &m_hUI_server, &m_hUI_file, &pszNewUrl, &bRedirInner);
00262 m_hUI_server.CloseHandle ();
00263 }
00264 else
00265 {
00266
00267 ir = fsHttpOpenPath (pszUrl, m_pServer, &m_hUI_file, &pszNewUrl, &bRedirInner);
00268 }
00269
00270
00271 m_hUI_file.CloseHandle ();
00272
00273 if (ir != IR_SUCCESS)
00274 {
00275 pInfo->bAvailable = FALSE;
00276 return ir;
00277 }
00278
00279 if (pszNewUrl)
00280 CalcUrl (pInfo, pszNewUrl);
00281 else
00282 CalcUrl (pInfo, pszUrl);
00283
00284 CheckFolder (pInfo);
00285
00286
00287 if (!m_hUI_file.GetLastModifiedDate (&pInfo->date))
00288 pInfo->date.dwHighDateTime = pInfo->date.dwLowDateTime = UINT_MAX;
00289
00290 pInfo->uSize = m_hUI_file.GetFileSize ();
00291
00292 SAFE_DELETE_ARRAY (pszNewUrl);
00293
00294 return IR_SUCCESS;
00295 }
00296
00297 void fsHttpFiles::RetreiveInfoWhileGettingList(BOOL b)
00298 {
00299 m_bGetInfo = b;
00300 }
00301
00302 void fsHttpFiles::CheckFolder(fsFileInfo *file)
00303 {
00304 UINT uLen = file->strName.Length ();
00305
00306
00307 if (file->strName [uLen-1] == '\\' || file->strName [uLen - 1] == '/')
00308 {
00309 file->strName [uLen - 1] = 0;
00310 file->bFolder = TRUE;
00311 }
00312
00313 LPCSTR pszSlash = strrchr (file->strName, '\\');
00314 pszSlash = max (pszSlash, strrchr (file->strName, '/'));
00315 LPCSTR pszExt = strrchr (file->strName, '.');
00316
00317
00318 file->bFolder = pszSlash >= pszExt;
00319
00320
00321
00322 }
00323
00324 void fsHttpFiles::Abort()
00325 {
00326 m_bAbort = TRUE;
00327 m_httpFile.CloseHandle ();
00328 }
00329
00330 void fsHttpFiles::SetServer(fsHttpConnection *pServer)
00331 {
00332 m_pServer = pServer;
00333 }
00334
00335 void fsHttpFiles::CalcUrl(fsFileInfo *pInfo, LPCSTR pszSomeUrl)
00336 {
00337 fsURL url1, url2;
00338
00339 char szResUrl [10000];
00340
00341 fsInternetResult ir = url2.Crack (pszSomeUrl);
00342
00343 if (ir != IR_SUCCESS && *m_pszBaseURL)
00344 {
00345
00346 fsURL urlBase;
00347 if (IR_SUCCESS != urlBase.Crack (m_pszBaseURL))
00348 {
00349 strcpy (szResUrl, "http://");
00350 strcat (szResUrl, m_pszBaseURL);
00351 }
00352 else
00353 strcpy (szResUrl, m_pszBaseURL);
00354
00355 if (szResUrl [strlen (szResUrl)-1] != '/' && szResUrl [strlen (szResUrl)-1] != '\\')
00356 strcat (szResUrl, "/");
00357
00358 ir = urlBase.Crack (szResUrl);
00359 if (ir == IR_SUCCESS)
00360 strcat (szResUrl, pszSomeUrl);
00361 else
00362 strcpy (szResUrl, pszSomeUrl);
00363 }
00364 else
00365 {
00366 strcpy (szResUrl, pszSomeUrl);
00367 }
00368
00369 if (ir == IR_SUCCESS)
00370 {
00371 if (fsIsServersEqual (url1.GetHostName (), url2.GetHostName (), FALSE) &&
00372 url1.GetInternetScheme () == url2.GetInternetScheme () &&
00373 url1.GetPort () == url2.GetPort ())
00374 {
00375 LPCSTR p1 = url1.GetPath ();
00376 LPCSTR p2 = url2.GetPath ();
00377
00378 while (*p1 && *p1++ == *p2)
00379 p2++;
00380
00381
00382 strcpy (szResUrl, p2);
00383 }
00384 }
00385
00386
00387
00388
00389 pInfo->strName = szResUrl;
00390
00391
00392 if (pInfo->strName [pInfo->strName.Length () - 1] == '\\' || pInfo->strName [pInfo->strName.Length () - 1] == '/')
00393 {
00394
00395 pInfo->strName [pInfo->strName.Length () - 1] = 0;
00396 pInfo->bFolder = TRUE;
00397 }
00398 }
00399
00400 LPCSTR fsHttpFiles::GetLastError()
00401 {
00402 return m_pServer->GetLastError ();
00403 }
00404
00405 void fsHttpFiles::UseSecure(BOOL bUse)
00406 {
00407 m_bUseSecure = bUse;
00408 }
00409
00410 void fsHttpFiles::SetEventFunc(fntHttpFilesEventFunc pfn, LPVOID lpParam)
00411 {
00412 m_pfnEvents = pfn;
00413 m_lpEventsParam = lpParam;
00414 }
00415
00416 void fsHttpFiles::Event(fsHttpFilesEvent enEvent)
00417 {
00418 if (m_pfnEvents)
00419 m_pfnEvents (this, enEvent, m_lpEventsParam);
00420 }