00001
00002
00003
00004
00005
00006 #include "fsinet.h"
00007 #include "fsURL.h"
00008 #include "fsHttpConnection.h"
00009 #include "fsHttpFile.h"
00010 #include "system.h"
00011 #include "fsInternetURLFile.h"
00012
00013 #include <stdio.h>
00014
00015 fsInternetResult fsWinErrorToIR (DWORD dwErr)
00016 {
00017 switch (dwErr)
00018 {
00019 case ERROR_BAD_NETPATH:
00020 case ERROR_NOT_FOUND:
00021 case ERROR_PATH_NOT_FOUND:
00022 case ERROR_FILE_NOT_FOUND:
00023 return IR_FILENOTFOUND;
00024
00025 default:
00026
00027 return IR_WININETUNKERROR;
00028 }
00029 }
00030
00031 fsInternetResult fsWinErrorToIR ()
00032 {
00033 return fsWinErrorToIR (GetLastError ());
00034 }
00035
00036 fsInternetResult fsWinInetErrorToIR (DWORD dwErr)
00037 {
00038 switch (dwErr)
00039 {
00040 case ERROR_SUCCESS:
00041 return IR_SUCCESS;
00042
00043 case ERROR_INTERNET_LOGIN_FAILURE:
00044 return IR_LOGINFAILURE;
00045
00046 case ERROR_INTERNET_INCORRECT_USER_NAME:
00047 return IR_INVALIDUSERNAME;
00048
00049 case ERROR_INTERNET_INCORRECT_PASSWORD:
00050 return IR_INVALIDPASSWORD;
00051
00052 case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
00053 return IR_LOGINFAILURE;
00054
00055 case ERROR_INTERNET_UNRECOGNIZED_SCHEME:
00056 case ERROR_INTERNET_INVALID_URL:
00057 return IR_BADURL;
00058
00059 case ERROR_INTERNET_CANNOT_CONNECT:
00060 return IR_CANTCONNECT;
00061
00062 case ERROR_INTERNET_CONNECTION_RESET:
00063 return IR_LOSTCONNECTION;
00064
00065 case ERROR_INTERNET_TIMEOUT:
00066 return IR_TIMEOUT;
00067
00068 case ERROR_INTERNET_NAME_NOT_RESOLVED:
00069 return IR_NAMENOTRESOLVED;
00070
00071 case ERROR_INTERNET_EXTENDED_ERROR:
00072 return IR_EXTERROR;
00073
00074 case ERROR_INTERNET_CONNECTION_ABORTED:
00075 case ERROR_INTERNET_OPERATION_CANCELLED:
00076 case ERROR_FTP_DROPPED:
00077 return IR_CONNECTIONABORTED;
00078
00079 case ERROR_INTERNET_NO_DIRECT_ACCESS:
00080 return IR_NODIRECTACCESS;
00081
00082 case ERROR_INTERNET_ITEM_NOT_FOUND:
00083 return IR_FILENOTFOUND;
00084
00085 case ERROR_INTERNET_DISCONNECTED:
00086 return IR_NOINTERNETCONNECTION;
00087
00088 case ERROR_INVALID_PARAMETER:
00089 return IR_INVALIDPARAM;
00090
00091 case ERROR_HTTP_INVALID_SERVER_RESPONSE:
00092 return IR_SERVERUNKERROR;
00093
00094 case ERROR_HTTP_INVALID_HEADER:
00095 return IR_E_WININET_UNSUPP_RESOURCE;
00096
00097 default:
00098
00099 return IR_WININETUNKERROR;
00100 }
00101 }
00102
00103 fsInternetResult fsWinInetErrorToIR ()
00104 {
00105 return fsWinInetErrorToIR (GetLastError ());
00106 }
00107
00108 fsInternetResult fsHttpStatusCodeToIR (DWORD dwStatusCode)
00109 {
00110 switch (dwStatusCode)
00111 {
00112 case HTTP_STATUS_BAD_REQUEST:
00113 return IR_SERVERBADREQUEST;
00114
00115 case HTTP_STATUS_GONE:
00116 case HTTP_STATUS_NOT_FOUND:
00117 return IR_FILENOTFOUND;
00118
00119 case HTTP_STATUS_PROXY_AUTH_REQ:
00120 return IR_PROXYAUTHREQ;
00121
00122 case HTTP_STATUS_OK:
00123 return IR_SUCCESS;
00124
00125 case HTTP_STATUS_DENIED:
00126 case HTTP_STATUS_FORBIDDEN:
00127 return IR_LOGINFAILURE;
00128
00129 case HTTP_STATUS_REDIRECT:
00130 case HTTP_STATUS_REDIRECT_METHOD:
00131 case HTTP_STATUS_MOVED:
00132 case HTTP_STATUS_REDIRECT_KEEP_VERB:
00133 return IR_NEEDREDIRECT;
00134
00135 case HTTP_STATUS_SERVICE_UNAVAIL:
00136 case HTTP_STATUS_SERVER_ERROR:
00137 return IR_SERVERUNKERROR;
00138
00139 case HTTP_STATUS_VERSION_NOT_SUP:
00140 return IR_HTTPVERNOTSUP;
00141
00142 default:
00143
00144 return IR_WININETUNKERROR;
00145 }
00146 }
00147
00148 fsInternetResult fsHttpOpenUrl (LPCSTR pszUrl, LPCSTR pszUser, LPCSTR pszPassword, fsHttpConnection *pServer, fsHttpFile *pFile, LPSTR* ppRedirectedUrl, BOOL *pbRedirInner)
00149 {
00150 fsURL url;
00151 fsInternetResult ir;
00152
00153 ir = url.Crack (pszUrl);
00154 if (ir != IR_SUCCESS)
00155 return ir;
00156
00157 ir = pServer->Connect (url.GetHostName (), pszUser ? pszUser : url.GetUserName (),
00158 pszPassword ? pszPassword : url.GetPassword (), url.GetPort ());
00159
00160 if (ir != IR_SUCCESS)
00161 return ir;
00162
00163 pFile->UseSecure (url.GetInternetScheme () == INTERNET_SCHEME_HTTPS);
00164
00165 return fsHttpOpenPath (url.GetPath (), pServer, pFile, ppRedirectedUrl, pbRedirInner);
00166 }
00167
00168 fsInternetResult fsHttpOpenPath (LPCSTR pszPath, fsHttpConnection *pServer, fsHttpFile *pFile, LPSTR* ppRedirectedUrl, BOOL *pbRedirInner)
00169 {
00170 fsInternetResult ir;
00171
00172 pFile->Initialize (pServer);
00173
00174 *ppRedirectedUrl = NULL;
00175
00176
00177 ir = pFile->Open (pszPath, 0);
00178
00179 if (ir != IR_SUCCESS)
00180 {
00181 if (ir == IR_NEEDREDIRECT)
00182 {
00183 CHAR szUrl [10000];
00184 fsURL u;
00185 BOOL bRelUrl = FALSE;
00186
00187 if (u.Crack (pFile->GetLastError ()) != IR_SUCCESS)
00188 bRelUrl = TRUE;
00189
00190 *pbRedirInner = TRUE;
00191
00192 if (bRelUrl)
00193 {
00194 if (*pFile->GetLastError () != '/' && *pFile->GetLastError () != '\\')
00195 {
00196
00197 strcpy (szUrl, pszPath);
00198 int len = strlen (szUrl);
00199 while (szUrl [len-1] != '/' && szUrl [len-1] != '\\')
00200 len--;
00201 szUrl [len] = 0;
00202 strcat (szUrl, pFile->GetLastError ());
00203
00204 }
00205 else
00206 {
00207 strcpy (szUrl, pFile->GetLastError ());
00208 }
00209
00210
00211
00212
00213 ir = fsHttpOpenPath (szUrl, pServer, pFile, ppRedirectedUrl, pbRedirInner);
00214 }
00215 else
00216 {
00217 strcpy (szUrl, pFile->GetLastError ());
00218 ir = fsHttpOpenUrl (szUrl, NULL, NULL, pServer, pFile, ppRedirectedUrl, pbRedirInner);
00219 }
00220
00221
00222 if (*ppRedirectedUrl == NULL)
00223 {
00224 fsnew (*ppRedirectedUrl, CHAR, strlen (szUrl) + 1);
00225 strcpy (*ppRedirectedUrl, szUrl);
00226 }
00227
00228
00229 *pbRedirInner = *pbRedirInner && bRelUrl;
00230 }
00231
00232 return ir;
00233 }
00234
00235 return IR_SUCCESS;
00236 }
00237
00238 BOOL fsUrlToFullUrl (LPCSTR pszUrlParent, LPCSTR pszUrlCurrent, LPSTR *ppszFullUrl)
00239 {
00240 fsURL url;
00241 *ppszFullUrl = NULL;
00242
00243 try {
00244
00245 if (IR_SUCCESS != url.Crack (pszUrlCurrent, FALSE))
00246 {
00247 UINT nLenParent = strlen (pszUrlParent);
00248 UINT nLenUrl = strlen (pszUrlCurrent);
00249
00250 fsnew (*ppszFullUrl, char, nLenParent + nLenUrl + 10);
00251
00252 if (*pszUrlCurrent == '\\' || *pszUrlCurrent == '/')
00253 {
00254
00255
00256 fsURL url2;
00257 if (IR_SUCCESS != url.Crack (pszUrlParent))
00258 return FALSE;
00259 DWORD dwLen = nLenParent + nLenUrl + 1;
00260 url2.Create (url.GetInternetScheme (), url.GetHostName (), url.GetPort (), url.GetUserName (), url.GetPassword (),
00261 pszUrlCurrent, *ppszFullUrl, &dwLen);
00262 }
00263 else
00264 {
00265
00266
00267
00268
00269
00270 lstrcpy (*ppszFullUrl, pszUrlParent);
00271
00272
00273 int pos = nLenParent;
00274
00275 int posmin = 0;
00276
00277 LPCSTR pszPath;
00278 pszPath = strstr (*ppszFullUrl, "://");
00279 if (pszPath == NULL)
00280 pszPath = strstr (*ppszFullUrl, ":\\\\");
00281 if (pszPath)
00282 {
00283 pszPath += 3;
00284
00285 while (*pszPath != 0 && *pszPath != '\\' && *pszPath != '/')
00286 pszPath++;
00287
00288 posmin = pszPath - *ppszFullUrl;
00289
00290 if (*pszPath == 0)
00291 {
00292
00293
00294 lstrcat (*ppszFullUrl, "/");
00295 posmin++;
00296 }
00297 else
00298 posmin++;
00299 }
00300
00301
00302 if (pos < posmin)
00303 pos = posmin;
00304 else while (pos > posmin && pszUrlParent [pos-1] != '\\' && pszUrlParent [pos-1] != '/')
00305 pos--;
00306
00307
00308
00309 for (UINT i = 0; i < nLenUrl; i++)
00310 {
00311
00312 if (pszUrlCurrent [i] == '.')
00313 {
00314
00315 if (pszUrlCurrent [i+1] == '.')
00316 {
00317 if (pszUrlCurrent [i+2] == '\\' || pszUrlCurrent [i+2] == '/')
00318 {
00319
00320
00321 if (pos > posmin)
00322 pos--;
00323
00324
00325
00326 while (pos > posmin && ((*ppszFullUrl) [pos-1] != '\\' && (*ppszFullUrl) [pos-1] != '/'))
00327 pos --;
00328
00329 i += 2;
00330 }
00331 }
00332
00333 else if (pszUrlCurrent [i+1] == '\\' || pszUrlCurrent [i+1] == '/')
00334 i += 1;
00335 else
00336
00337 (*ppszFullUrl) [pos++] = pszUrlCurrent [i];
00338 }
00339 else
00340
00341 (*ppszFullUrl) [pos++] = pszUrlCurrent [i];
00342 }
00343
00344
00345 (*ppszFullUrl) [pos] = 0;
00346 }
00347
00348 return TRUE;
00349 }
00350
00351
00352
00353 fsnew (*ppszFullUrl, char, strlen (pszUrlCurrent) + 1);
00354 strcpy (*ppszFullUrl, pszUrlCurrent);
00355 return FALSE;
00356
00357 }
00358 catch (...)
00359 {
00360 return FALSE;
00361 }
00362 }
00363
00364 fsInternetResult fsWSAErrorToIR ()
00365 {
00366 DWORD dwError = WSAGetLastError ();
00367
00368 switch (dwError)
00369 {
00370 case NOERROR:
00371 return IR_SUCCESS;
00372 }
00373
00374 return IR_ERROR;
00375 }
00376
00377 BOOL fsIsUrlRelative (LPCSTR pszUrl)
00378 {
00379 return strnicmp (pszUrl, "http://", 7) && strnicmp (pszUrl, "https://", 8) && strnicmp (pszUrl, "ftp://", 6);
00380 }
00381
00382 void fsRemoveWWW (LPCSTR pszUrl)
00383 {
00384 char* psz = max (strstr (pszUrl, "://"), strstr (pszUrl, ":\\\\"));
00385
00386 if (psz)
00387 if (strnicmp (psz+3, "www.", 4) == 0)
00388 strcpy (psz+3, psz+7);
00389 }
00390
00391 BOOL fsIsServersEqual (LPCSTR pszServ1, LPCSTR pszServ2, BOOL bExcludeSubDomainNameFrom2Site)
00392 {
00393 if (pszServ1 == NULL || pszServ2 == NULL)
00394 return FALSE;
00395
00396 UINT n1 = 0, n2 = 0;
00397
00398
00399
00400 if (strnicmp (pszServ1, "www.", 4) == 0)
00401 n1 = 4;
00402
00403 if (strnicmp (pszServ2, "www.", 4) == 0)
00404 n2 = 4;
00405
00406 if (bExcludeSubDomainNameFrom2Site)
00407 {
00408 int l1 = strlen (pszServ1);
00409 int l2 = strlen (pszServ2);
00410
00411
00412
00413 if (l1-n1 < l2-n2)
00414 {
00415
00416 if (pszServ2 [l2 - (l1 - n1) - 1] == '.')
00417 n2 = l2 - (l1 - n1);
00418 }
00419 }
00420
00421 return stricmp (pszServ1 + n1, pszServ2 + n2) == 0;
00422 }
00423
00424 fsInternetResult fsDownloadFile (fsInternetURLFile* file, LPBYTE* ppBuf, UINT* puSize, BOOL* pbAbort)
00425 {
00426 UINT uToRead = 1000;
00427 const FLOAT fInc = 1.2f;
00428
00429 fsInternetResult ir;
00430
00431
00432
00433 UINT64 uFileSize = file->GetFileSize ();
00434 UINT uMax = (UINT) uFileSize;
00435 UINT uPos = 0;
00436 DWORD dwRead;
00437
00438 if (uFileSize == _UI64_MAX)
00439 uMax = 100000;
00440
00441 *ppBuf = NULL;
00442
00443 LPBYTE pBuf = NULL;
00444 fsnew (pBuf, BYTE, uMax+1);
00445
00446 int cZeroReads = 0;
00447
00448 do
00449 {
00450 if (uToRead > uFileSize - uPos)
00451 uToRead = UINT (uFileSize - uPos);
00452 if (uToRead == 0)
00453 break;
00454
00455 if (uPos + uToRead > uMax)
00456 {
00457
00458 uMax = UINT (uMax * fInc);
00459
00460
00461 LPBYTE buf = 0;
00462 fsnew (buf, BYTE, uMax+1);
00463 CopyMemory (buf, pBuf, uPos);
00464 delete [] pBuf;
00465 pBuf = buf;
00466 }
00467
00468 ir = file->Read (LPBYTE (pBuf+uPos), uToRead, &dwRead);
00469 if (ir != IR_SUCCESS)
00470 {
00471 delete pBuf;
00472 return ir;
00473 }
00474
00475 uPos += dwRead;
00476
00477 if (dwRead == 0)
00478 {
00479 cZeroReads ++;
00480 if (cZeroReads < 3 && uFileSize != _UI64_MAX)
00481 dwRead = 1;
00482 }
00483 else
00484 cZeroReads = 0;
00485 }
00486 while (dwRead && *pbAbort == FALSE);
00487
00488 if (*pbAbort)
00489 return IR_S_FALSE;
00490
00491 if (uFileSize != _UI64_MAX && uFileSize != uPos)
00492 return IR_WININETUNKERROR;
00493
00494 pBuf [uPos] = 0;
00495
00496 *ppBuf = pBuf;
00497
00498 if (puSize)
00499 *puSize = uPos;
00500
00501 return IR_SUCCESS;
00502 }