651 // HttpCacheUtil::VSSCacheContent |
651 // HttpCacheUtil::VSSCacheContent |
652 // |
652 // |
653 // ----------------------------------------------------------------------------- |
653 // ----------------------------------------------------------------------------- |
654 // |
654 // |
655 TBool HttpCacheUtil::VSSCacheContent( const TDesC8& aUrl, const HBufC8* aWhiteList ) |
655 TBool HttpCacheUtil::VSSCacheContent( const TDesC8& aUrl, const HBufC8* aWhiteList ) |
656 { |
656 { |
657 TBool found( EFalse ); |
657 TBool found( EFalse ); |
658 if( aWhiteList ) |
658 |
659 { |
659 if ( aWhiteList ) |
660 TUint8* bufPtr = (TUint8* ) aWhiteList->Ptr(); |
660 { |
661 TUint8* startBufPtr = bufPtr; |
661 TUint8* bufPtr = (TUint8* ) aWhiteList->Ptr(); |
662 TUint len = aWhiteList->Length(); |
662 TUint8* startBufPtr = bufPtr; |
663 TInt i, startUri, uriLen; |
663 TUint len = aWhiteList->Length(); |
664 TPtrC8 uri ( aUrl ); |
664 TInt i, startUri, uriLen; |
665 for(i=0; i < len; i++) |
665 TPtrC8 uri ( aUrl ); |
666 { |
666 for ( i=0; i < len; i++ ) |
667 startUri = i; |
667 { |
668 for( ;( ( *bufPtr != ';' ) && ( i<len ) ) ; i++, bufPtr++ ) ; |
668 startUri = i; |
669 uriLen = i - startUri; |
669 |
670 if( i == len ) |
670 for ( ;( ( *bufPtr != ';' ) && ( i<len ) ) ; i++, bufPtr++ ) ; |
671 { |
671 |
672 uriLen += 2; //For getting total length |
672 uriLen = i - startUri; |
673 } |
673 |
674 TPtrC8 uriDomain( startBufPtr, uriLen); |
674 if ( i == len ) |
675 if ( OperatorCacheContent( uriDomain, uri ) ) |
675 { |
676 { |
676 //For getting total length |
677 found = ETrue; |
677 uriLen += 2; |
678 break; |
678 } |
679 } |
679 |
680 startBufPtr = ++bufPtr; |
680 TPtrC8 uriDomain( startBufPtr, uriLen); |
681 i++; |
681 if ( OperatorCacheContent( uriDomain, uri ) ) |
682 } //end for() |
682 { |
683 } //end for() |
683 found = ETrue; |
684 return found; |
684 break; |
|
685 } |
|
686 |
|
687 startBufPtr = ++bufPtr; |
|
688 i++; |
|
689 } //end for() |
|
690 } //end if ( aWhiteList ) |
|
691 |
|
692 return found; |
685 } |
693 } |
686 |
694 |
687 // ----------------------------------------------------------------------------- |
695 // ----------------------------------------------------------------------------- |
688 // HttpCacheUtil::PragmaNoCache |
696 // HttpCacheUtil::PragmaNoCache |
689 // |
697 // |
705 TInt noStoreField( requestHeaders.GetField( fieldName, 0, headerVal ) ); |
713 TInt noStoreField( requestHeaders.GetField( fieldName, 0, headerVal ) ); |
706 // |
714 // |
707 return( noCacheField == KErrNone || noStoreField == KErrNone ); |
715 return( noCacheField == KErrNone || noStoreField == KErrNone ); |
708 } |
716 } |
709 |
717 |
710 |
|
711 // ----------------------------------------------------------------------------- |
718 // ----------------------------------------------------------------------------- |
712 // HttpCacheUtil::GetHeaderFileName |
719 // HttpCacheUtil::GetHeaderFileName |
713 // |
720 // |
714 // ----------------------------------------------------------------------------- |
721 // ----------------------------------------------------------------------------- |
715 // |
722 // |
721 // header file name = foo.h |
728 // header file name = foo.h |
722 aHeaderFileName.Copy( aBodyFileName ); |
729 aHeaderFileName.Copy( aBodyFileName ); |
723 // take the filename and append the new extension |
730 // take the filename and append the new extension |
724 aHeaderFileName.Append( KHttpCacheHeaderExt() ); |
731 aHeaderFileName.Append( KHttpCacheHeaderExt() ); |
725 } |
732 } |
726 |
|
727 |
733 |
728 // ----------------------------------------------------------------------------- |
734 // ----------------------------------------------------------------------------- |
729 // HttpCacheUtil::AdjustExpirationTime |
735 // HttpCacheUtil::AdjustExpirationTime |
730 // |
736 // |
731 // ----------------------------------------------------------------------------- |
737 // ----------------------------------------------------------------------------- |
846 cachedDate = TTime( value.DateTime() ); |
852 cachedDate = TTime( value.DateTime() ); |
847 CleanupStack::PopAndDestroy(); // valueStr |
853 CleanupStack::PopAndDestroy(); // valueStr |
848 } |
854 } |
849 } |
855 } |
850 |
856 |
851 |
|
852 // last modified |
857 // last modified |
853 fieldName = aStrP.StringF( HTTP::ELastModified, RHTTPSession::GetTable() ); |
858 fieldName = aStrP.StringF( HTTP::ELastModified, RHTTPSession::GetTable() ); |
854 // new |
859 // new |
855 status = aResponseHeaders.GetField( fieldName, 0, hdrValue ); |
860 status = aResponseHeaders.GetField( fieldName, 0, hdrValue ); |
856 if( status == KErrNone ) |
861 if( status == KErrNone ) |
1023 } |
1028 } |
1024 else |
1029 else |
1025 { |
1030 { |
1026 expires = now; |
1031 expires = now; |
1027 } |
1032 } |
1028 |
1033 |
1029 // if past-expire date do not cache. According to RFC2616, section 13.2.4/14.9.3, |
1034 // if past-expire date do not cache. According to RFC2616, section 13.2.4/14.9.3, |
1030 // if maxage is present, then ignore expires |
1035 // if maxage is present, then ignore expires |
1031 if (!maxAge && now > expires) |
1036 if (!maxAge && now > expires) |
1032 { |
1037 { |
1033 return EFalse; |
1038 return EFalse; |
1034 } |
1039 } |
1035 |
1040 |
1036 if( err == KErrNone || maxAge > 0 ) |
1041 if( err == KErrNone || maxAge > 0 ) |
1037 { |
1042 { |
1038 hasExplicitCache = ETrue; |
1043 hasExplicitCache = ETrue; |
1039 } |
1044 } |
1040 // Reject if the http status code doesn't equal 200, 304, 301, 410. |
1045 // Reject if the http status code doesn't equal 200, 304, 301, 410. |
1148 (void)aAny; |
1153 (void)aAny; |
1149 #endif // __CACHELOG__ |
1154 #endif // __CACHELOG__ |
1150 } |
1155 } |
1151 |
1156 |
1152 // ----------------------------------------------------------------------------- |
1157 // ----------------------------------------------------------------------------- |
|
1158 // HttpCacheUtil::WriteFormatLog |
|
1159 // |
|
1160 // ----------------------------------------------------------------------------- |
|
1161 // |
|
1162 void HttpCacheUtil::WriteFormatLog( |
|
1163 TInt aLogLevel, |
|
1164 TRefByValue<const TDesC> aBuf, ... ) |
|
1165 { |
|
1166 #ifdef __CACHELOG__ |
|
1167 TBool log( aLogLevel <= KCurrentLogLevel ); |
|
1168 TPtrC fileName( KHttpCacheGeneralFileName ); |
|
1169 |
|
1170 if ( aLogLevel == 1 ) |
|
1171 { |
|
1172 // write logging to hash.txt |
|
1173 fileName.Set( KHttpCacheHashFileName ); |
|
1174 log = ETrue; |
|
1175 } |
|
1176 |
|
1177 if ( log ) |
|
1178 { |
|
1179 VA_LIST args; |
|
1180 VA_START(args, aBuf); |
|
1181 // Be careful of string length when debugging |
|
1182 TBuf16<1024> string; |
|
1183 // TDes16OverflowIgnore, not supported in 3.2.3 |
|
1184 // TDes16OverflowIgnore overflow; |
|
1185 // string.AppendFormatList(aBuf, args, &overflow); |
|
1186 string.AppendFormatList(aBuf, args); |
|
1187 RFileLogger::WriteFormat(_L("Browser"), fileName, EFileLoggingModeAppend, string); |
|
1188 VA_END(args); |
|
1189 } |
|
1190 #else // __CACHELOG__ |
|
1191 (void)aLogLevel; |
|
1192 (void)aBuf; |
|
1193 #endif // __CACHELOG__ |
|
1194 } |
|
1195 |
|
1196 // ----------------------------------------------------------------------------- |
1153 // HttpCacheUtil::WriteLogFilenameAndUrl |
1197 // HttpCacheUtil::WriteLogFilenameAndUrl |
1154 // |
1198 // |
1155 // ----------------------------------------------------------------------------- |
1199 // ----------------------------------------------------------------------------- |
1156 // |
1200 // |
1157 void HttpCacheUtil::WriteLogFilenameAndUrl( |
1201 void HttpCacheUtil::WriteLogFilenameAndUrl( |
1168 _LIT(KSpace, " "); |
1212 _LIT(KSpace, " "); |
1169 TInt itemTypeStringLen( 30 ); |
1213 TInt itemTypeStringLen( 30 ); |
1170 TInt tmpLen( aMethodName.Length() + aFilename.Length() + |
1214 TInt tmpLen( aMethodName.Length() + aFilename.Length() + |
1171 3*KColonSpace().Length() + aUrl.Length() + itemTypeStringLen ); |
1215 3*KColonSpace().Length() + aUrl.Length() + itemTypeStringLen ); |
1172 HBufC* tmp = HBufC::New( tmpLen ); |
1216 HBufC* tmp = HBufC::New( tmpLen ); |
1173 |
1217 |
1174 if ( tmp ) { |
1218 if ( tmp ) { |
1175 TPtr tmpPtr( tmp->Des() ); |
1219 TPtr tmpPtr( tmp->Des() ); |
1176 tmpPtr.Copy( aMethodName ); |
1220 tmpPtr.Copy( aMethodName ); |
1177 tmpPtr.Append( KColonSpace ); |
1221 tmpPtr.Append( KColonSpace ); |
1178 |
1222 |
1196 else { |
1240 else { |
1197 tmpPtr.Append( tmpUrlPtr ); |
1241 tmpPtr.Append( tmpUrlPtr ); |
1198 tmpPtr.Append( KColonSpace ); |
1242 tmpPtr.Append( KColonSpace ); |
1199 } |
1243 } |
1200 } |
1244 } |
1201 |
1245 |
1202 // Append the bucketIndex, lookup table pos, etc... |
1246 // Append the bucketIndex, lookup table pos, etc... |
1203 switch ( aItemType ) |
1247 switch ( aItemType ) |
1204 { |
1248 { |
1205 case ELogItemTypeNone: |
1249 case ELogItemTypeNone: |
1206 break; |
1250 break; |
1207 |
1251 |
1208 case ELogBucketIndex: |
1252 case ELogBucketIndex: |
1209 tmpPtr.Append( _L("bucketIndex =") ); |
1253 tmpPtr.Append( _L("bucketIndex =") ); |
1210 break; |
1254 break; |
1211 |
1255 |
1212 case ELogEntrySize: |
1256 case ELogEntrySize: |
1213 tmpPtr.Append( _L("entrySize =") ); |
1257 tmpPtr.Append( _L("entrySize =") ); |
1214 break; |
1258 break; |
1215 |
1259 |
1216 case ELogLookupTablePos: |
1260 case ELogLookupTablePos: |
1319 #endif // __CACHELOG__ |
1363 #endif // __CACHELOG__ |
1320 } |
1364 } |
1321 |
1365 |
1322 // ----------------------------------------------------------------------------- |
1366 // ----------------------------------------------------------------------------- |
1323 // HttpCacheUtil::GenerateNameLC |
1367 // HttpCacheUtil::GenerateNameLC |
1324 // Given a URL, generates fully qualified Symbian path for storing HTTP response. |
1368 // Given a URL, generates fully qualified Symbian path for storing HTTP response. |
1325 // The format is <cache base dir> + <subdirectory> + <file name>. |
1369 // The format is <cache base dir> + <subdirectory> + <file name>. |
1326 // Caller must free the returned HBufC* when done. |
1370 // Caller must free the returned HBufC* when done. |
1327 // ----------------------------------------------------------------------------- |
1371 // ----------------------------------------------------------------------------- |
1328 HBufC* HttpCacheUtil::GenerateNameLC( |
1372 HBufC* HttpCacheUtil::GenerateNameLC( const TDesC8& aUrl, const TDesC& aBaseDir ) |
1329 const TDesC8& aUrl, const TDesC& aBaseDir) |
1373 { |
1330 { |
|
1331 |
|
1332 TUint32 crc (0); |
1374 TUint32 crc (0); |
1333 |
1375 |
1334 //use the entire URL for CRC calculation: maximizes source entropy/avoids collisions |
1376 // Use the entire URL for CRC calculation: maximizes source |
1335 Mem::Crc32(crc, aUrl.Ptr(), aUrl.Size()); |
1377 // entropy/avoids collisions. Returns 8 char hex filename, use |
1336 TUint32 nibble (crc & (KCacheSubdirCount-1)); // extract least significant 4 bits (nibble) for subdirectory |
1378 // KMaxFilenameLength to internalize/externalize. |
1337 |
1379 Mem::Crc32(crc, aUrl.Ptr(), aUrl.Size()); |
1338 HBufC* fileName = HBufC::NewLC( KMaxPath ); // e.g E\078AFEFE |
1380 |
1339 _LIT(KFormat,"%S%x%c%08x"); // Note the %08x : a 32-bit value can represented as 0xFFFFFFFF |
1381 // extract least significant 4 bits (nibble) for subdirectory |
|
1382 TUint32 nibble( crc & (KCacheSubdirCount-1) ); |
|
1383 |
|
1384 // filename has full path, drive:\directory\sub-directory\8-char filename |
|
1385 // e.g. c:\system\cache\E\078AFEFE, where E is calculated by nibble() |
|
1386 // and 078AFEFE is calculated by crc32() |
|
1387 HBufC* fileName = HBufC::NewLC( KMaxPath ); |
|
1388 // Note in KFormat, the %08x : a 32-bit value can represented as 0xFFFFFFFF |
|
1389 _LIT(KFormat,"%S%x%c%08x"); |
1340 fileName->Des().Format(KFormat, &aBaseDir, nibble, KPathDelimiter, crc); |
1390 fileName->Des().Format(KFormat, &aBaseDir, nibble, KPathDelimiter, crc); |
|
1391 |
1341 return fileName; |
1392 return fileName; |
1342 |
1393 } |
1343 } |
|
1344 |
|
1345 |
1394 |
1346 // ----------------------------------------------------------------------------- |
1395 // ----------------------------------------------------------------------------- |
1347 // HttpCacheUtil::Freshness |
1396 // HttpCacheUtil::Freshness |
1348 // |
1397 // |
1349 // Get the freshness of the "entry". |
1398 // Get the freshness of the "entry". |
1366 TInt64 freshness( 0 ); |
1415 TInt64 freshness( 0 ); |
1367 |
1416 |
1368 // Get the date from the headers |
1417 // Get the date from the headers |
1369 fieldName = aStrP.StringF( HTTP::EDate, RHTTPSession::GetTable() ); |
1418 fieldName = aStrP.StringF( HTTP::EDate, RHTTPSession::GetTable() ); |
1370 err = aHeaders.GetField( fieldName, 0, hdrValue ); |
1419 err = aHeaders.GetField( fieldName, 0, hdrValue ); |
1371 if( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) |
1420 if ( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) |
1372 { |
1421 { |
1373 date = aResponseTime; |
1422 date = aResponseTime; |
1374 } |
1423 } |
1375 else |
1424 else |
1376 { |
1425 { |
1377 date = TTime( hdrValue.DateTime() ); |
1426 date = TTime( hdrValue.DateTime() ); |
1378 } |
1427 } |
1379 |
1428 |
1380 // Get useful cache-control directives |
1429 // Get useful cache-control directives |
1381 status = GetCacheControls( aHeaders, &maxAge, NULL, NULL, NULL, NULL, NULL, aStrP ); |
1430 status = GetCacheControls( aHeaders, &maxAge, NULL, NULL, NULL, NULL, NULL, aStrP ); |
1382 if( status == KErrNone ) |
1431 if ( status == KErrNone ) |
1383 { |
1432 { |
1384 // max-age is in delta-seconds. Convert it to micro seconds. |
1433 // max-age is in delta-seconds. Convert it to micro seconds. |
1385 // All our calculations are in micro-seconds |
1434 // All our calculations are in micro-seconds |
1386 // If maxAge is present, use it |
1435 // If maxAge is present, use it |
1387 if( maxAge != -1 ) |
1436 if ( maxAge != -1 ) |
1388 { |
1437 { |
1389 freshness = maxAge * 1000 * 1000; |
1438 freshness = maxAge * 1000 * 1000; |
1390 |
1439 |
1391 return freshness; |
1440 return freshness; |
1392 } |
1441 } |
1393 |
1442 |
1394 // Get the expires from the headers |
1443 // Get the expires from the headers |
1395 fieldName = aStrP.StringF( HTTP::EExpires, RHTTPSession::GetTable() ); |
1444 fieldName = aStrP.StringF( HTTP::EExpires, RHTTPSession::GetTable() ); |
1396 err = aHeaders.GetField( fieldName, 0, hdrValue ); |
1445 err = aHeaders.GetField( fieldName, 0, hdrValue ); |
1397 if( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) |
1446 if ( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) |
1398 { |
1447 { |
1399 expires = 0; |
1448 expires = 0; |
1400 } |
1449 } |
1401 else |
1450 else |
1402 { |
1451 { |
1403 expires = TTime( hdrValue.DateTime() ); |
1452 expires = TTime( hdrValue.DateTime() ); |
1404 } |
1453 } |
1405 |
1454 |
1406 // Otherwise, if the expires is present use it |
1455 // Otherwise, if the expires is present use it |
1407 if( err != KErrNotFound ) |
1456 if ( err != KErrNotFound ) |
1408 { |
1457 { |
1409 freshness = expires.Int64() - date.Int64(); |
1458 freshness = expires.Int64() - date.Int64(); |
1410 return freshness; |
1459 return freshness; |
1411 } |
1460 } |
1412 |
1461 |
1421 { |
1470 { |
1422 lastModified = TTime( hdrValue.DateTime() ); |
1471 lastModified = TTime( hdrValue.DateTime() ); |
1423 } |
1472 } |
1424 |
1473 |
1425 // Otherwise, if last-modified is present use it |
1474 // Otherwise, if last-modified is present use it |
1426 if( err != KErrNotFound ) |
1475 if ( err != KErrNotFound ) |
1427 { |
1476 { |
1428 if( aResponseTime > lastModified ) |
1477 if( aResponseTime > lastModified ) |
1429 { |
1478 { |
1430 freshness = aResponseTime.Int64() - lastModified.Int64(); |
1479 freshness = aResponseTime.Int64() - lastModified.Int64(); |
1431 freshness += ((TInt64)( freshness * 0.10 ) ); |
1480 freshness += ((TInt64)( freshness * 0.10 ) ); |