Page Speed Optimization Libraries  1.5.27.2
net/instaweb/rewriter/public/rewrite_options.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http:///www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00018 
00019 #ifndef NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_
00020 #define NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_
00021 
00022 #include <cstddef>                      
00023 #include <map>
00024 #include <set>
00025 #include <utility>                      
00026 #include <vector>
00027 
00028 #include "base/logging.h"
00029 #include "net/instaweb/http/public/meta_data.h"
00030 #include "net/instaweb/http/public/semantic_type.h"
00031 #include "net/instaweb/rewriter/public/domain_lawyer.h"
00032 #include "net/instaweb/rewriter/public/file_load_policy.h"
00033 #include "net/instaweb/rewriter/public/javascript_library_identification.h"
00034 #include "net/instaweb/util/public/basictypes.h"
00035 #include "net/instaweb/util/public/enum_set.h"
00036 #include "net/instaweb/util/public/gtest_prod.h"
00037 #include "net/instaweb/util/public/md5_hasher.h"
00038 #include "net/instaweb/util/public/scoped_ptr.h"
00039 #include "net/instaweb/util/public/string.h"
00040 #include "net/instaweb/util/public/string_util.h"
00041 #include "net/instaweb/util/public/thread_system.h"
00042 #include "pagespeed/kernel/util/dense_hash_map.h"
00043 #include "pagespeed/kernel/util/fast_wildcard_group.h"
00044 #include "pagespeed/kernel/util/wildcard.h"
00045 
00046 namespace net_instaweb {
00047 
00048 class GoogleUrl;
00049 class Hasher;
00050 class MessageHandler;
00051 class RequestHeaders;
00052 
00073 class RewriteOptions {
00074  public:
00081   enum Filter {
00082     kAddBaseTag,  
00083     kAddHead,
00084     kAddInstrumentation,
00085     kComputeStatistics,
00086     kCachePartialHtml,
00087     kCanonicalizeJavascriptLibraries,
00088     kCollapseWhitespace,
00089     kCollectFlushEarlyContentFilter,
00090     kCombineCss,
00091     kCombineHeads,
00092     kCombineJavascript,
00093     kComputeCriticalCss,
00094     kComputeVisibleText,
00095     kConvertGifToPng,
00096     kConvertJpegToProgressive,
00097     kConvertJpegToWebp,
00098     kConvertMetaTags,
00099     kConvertPngToJpeg,
00100     kConvertToWebpLossless,
00101     kDebug,
00102     kDecodeRewrittenUrls,
00103     kDeferIframe,
00104     kDeferJavascript,
00105     kDelayImages,
00106     kDetectReflowWithDeferJavascript,
00107     kDeterministicJs,
00108     kDisableJavascript,
00109     kDivStructure,
00110     kElideAttributes,
00111     kExplicitCloseTags,
00112     kExtendCacheCss,
00113     kExtendCacheImages,
00114     kExtendCachePdfs,
00115     kExtendCacheScripts,
00116     kFallbackRewriteCssUrls,
00117     kFlattenCssImports,
00118     kFlushSubresources,
00119     kHandleNoscriptRedirect,
00120     kHtmlWriterFilter,
00121     kInlineCss,
00122     kInlineImages,
00123     kInlineImportToLink,
00124     kInlineJavascript,
00125     kInPlaceOptimizeForBrowser,
00126     kInsertDnsPrefetch,
00127     kInsertGA,
00128     kInsertImageDimensions,
00129     kJpegSubsampling,
00130     kLazyloadImages,
00131     kLeftTrimUrls,
00132     kLocalStorageCache,
00133     kMakeGoogleAnalyticsAsync,
00134     kMoveCssAboveScripts,
00135     kMoveCssToHead,
00136     kOutlineCss,
00137     kOutlineJavascript,
00138     kPedantic,
00139     kPrioritizeCriticalCss,
00140     kPrioritizeVisibleContent,
00141     kProcessBlinkInBackground,
00142     kRecompressJpeg,
00143     kRecompressPng,
00144     kRecompressWebp,
00145     kRemoveComments,
00146     kRemoveQuotes,
00147     kResizeImages,
00148     kResizeMobileImages,
00149     kRewriteCss,
00150     kRewriteDomains,
00151     kRewriteJavascript,
00152     kRewriteStyleAttributes,
00153     kRewriteStyleAttributesWithUrl,
00154     kServeNonCacheableNonCritical,
00155     kSplitHtml,
00156     kSpriteImages,
00157     kSquashImagesForMobileScreen,
00158     kStripImageColorProfile,
00159     kStripImageMetaData,
00160     kStripNonCacheable,
00161     kStripScripts,
00162     kEndOfFilters
00163   };
00164 
00165   enum EnabledEnum {
00168     kEnabledOff,
00170     kEnabledOn,
00173     kEnabledUnplugged,
00174   };
00175 
00178   enum OptionEnum {
00179     kAddOptionsToUrls,
00180     kAllowLoggingUrlsInLogRecord,
00181     kAlwaysRewriteCss,
00182     kAnalyticsID,
00183     kAvoidRenamingIntrospectiveJavascript,
00184     kBeaconReinstrumentTimeSec,
00185     kBeaconUrl,
00186     kBlinkDesktopUserAgent,
00187     kBlinkMaxHtmlSizeRewritable,
00188     kBlinkNonCacheablesForAllFamilies,
00189     kCacheInvalidationTimestamp,
00190     kCacheSmallImagesUnrewritten,
00191     kClientDomainRewrite,
00192     kCombineAcrossPaths,
00193     kCompressMetadataCache,
00194     kCriticalImagesBeaconEnabled,
00195     kCriticalLineConfig,
00196     kCssFlattenMaxBytes,
00197     kCssImageInlineMaxBytes,
00198     kCssInlineMaxBytes,
00199     kCssOutlineMinBytes,
00200     kCssPreserveURLs,
00201     kDefaultCacheHtml,
00202     kDistributedRewriteServers,
00203     kDistributedRewriteTimeoutMs,
00204     kDomainRewriteHyperlinks,
00205     kDomainShardCount,
00206     kEnableAggressiveRewritersForMobile,
00207     kEnableBlinkCriticalLine,
00208     kEnableBlinkDashboard,
00209     kEnableBlinkForMobileDevices,
00210     kEnableBlinkHtmlChangeDetection,
00211     kEnableBlinkHtmlChangeDetectionLogging,
00212     kEnableDeferJsExperimental,
00213     kEnableCachePurge,
00214     kEnableFlushEarlyCriticalCss,
00215     kEnableFixReflow,
00216     kEnableExtendedInstrumentation,
00217     kEnableFlushSubresourcesExperimental,
00218     kEnableLazyLoadHighResImages,
00219     kEnableLazyloadInBlink,
00220     kEnablePrioritizingScripts,
00221     kEnabled,
00222     kFinderPropertiesCacheExpirationTimeMs,
00223     kFinderPropertiesCacheRefreshTimeMs,
00224     kFlushBufferLimitBytes,
00225     kFlushHtml,
00226     kFlushMoreResourcesEarlyIfTimePermits,
00227     kForbidAllDisabledFilters,
00228     kFuriousCookieDurationMs,
00229     kFuriousSlot,
00230     kIdleFlushTimeMs,
00231     kImageInlineMaxBytes,
00232     kImageJpegNumProgressiveScans,
00233     kImageJpegNumProgressiveScansForSmallScreens,
00234     kImageJpegRecompressionQuality,
00235     kImageJpegRecompressionQualityForSmallScreens,
00236     kImageLimitOptimizedPercent,
00237     kImageLimitResizeAreaPercent,
00238     kImageMaxRewritesAtOnce,
00239     kImagePreserveURLs,
00240     kImageRecompressionQuality,
00241     kImageResolutionLimitBytes,
00242     kImageWebpRecompressionQuality,
00243     kImageWebpRecompressionQualityForSmallScreens,
00244     kImageWebpTimeoutMs,
00245     kImplicitCacheTtlMs,
00246     kInPlaceResourceOptimization,
00247     kInPlaceWaitForOptimized,
00248     kInPlacePreemptiveRewriteCss,
00249     kInPlacePreemptiveRewriteCssImages,
00250     kInPlacePreemptiveRewriteImages,
00251     kInPlacePreemptiveRewriteJavascript,
00252     kInPlaceRewriteDeadlineMs,
00253     kIncreaseSpeedTracking,
00254     kInlineOnlyCriticalImages,
00255     kJsInlineMaxBytes,
00256     kJsOutlineMinBytes,
00257     kJsPreserveURLs,
00258     kLazyloadImagesAfterOnload,
00259     kLazyloadImagesBlankUrl,
00260     kLogBackgroundRewrite,
00261     kLogRewriteTiming,
00262     kLogUrlIndices,
00263     kLowercaseHtmlNames,
00264     kMaxCacheableResponseContentLength,
00265     kMaxCombinedJsBytes,
00266     kMaxHtmlCacheTimeMs,
00267     kMaxHtmlParseBytes,
00268     kMaxImageBytesForWebpInCss,
00269     kMaxImageSizeLowResolutionBytes,
00270     kMaxInlinedPreviewImagesIndex,
00271     kMaxRewriteInfoLogSize,
00272     kMaxUrlSegmentSize,
00273     kMaxUrlSize,
00274     kMetadataCacheStalenessThresholdMs,
00275     kMinImageSizeLowResolutionBytes,
00276     kMinResourceCacheTimeToRewriteMs,
00277     kModifyCachingHeaders,
00278     kNonCacheablesForCachePartialHtml,
00279     kObliviousPagespeedUrls,
00280     kOverrideBlinkCacheTimeMs,
00281     kOverrideCachingTtlMs,
00282     kOverrideIeDocumentMode,
00283     kPassthroughBlinkForInvalidResponseCode,
00284     kPersistBlinkBlacklist,
00285     kProgressiveJpegMinBytes,
00286     kPropagateBlinkCacheDeletes,
00287     kRejectBlacklisted,
00288     kRejectBlacklistedStatusCode,
00289     kReportUnloadTime,
00290     kRespectVary,
00291     kRespectXForwardedProto,
00292     kRewriteDeadlineMs,
00293     kRewriteLevel,
00294     kRewriteUncacheableResources,
00295     kRunningFurious,
00296     kServeStaleIfFetchError,
00297     kSupportNoScriptEnabled,
00298     kTestOnlyPrioritizeCriticalCssDontApplyOriginalCss,
00299     kUseFallbackPropertyCacheValues,
00300     kUseSmartDiffInBlink,
00301     kXModPagespeedHeaderValue,
00302     kXPsaBlockingRewrite,
00303 
00305     kAllow,
00306     kDisableFilters,
00307     kDisallow,
00308     kDistributableFilters,  
00309     kDomain,
00310     kEnableFilters,
00311     kExperimentVariable,
00312     kExperimentSpec,
00313     kForbidFilters,
00314     kRetainComment,
00315 
00317     kCustomFetchHeader,
00318     kLoadFromFile,
00319     kLoadFromFileMatch,
00320     kLoadFromFileRule,
00321     kLoadFromFileRuleMatch,
00322     kMapOriginDomain,
00323     kMapRewriteDomain,
00324     kMapProxyDomain,
00325     kShardDomain,
00326 
00328     kUrlValuedAttribute,
00329     kLibrary,
00330 
00332     kCacheFlushFilename,
00333     kCacheFlushPollIntervalSec,
00334     kExperimentalFetchFromModSpdy,
00335     kFetchHttps,
00336     kFetcherProxy,
00337     kFetcherTimeOutMs,
00338     kFileCacheCleanInodeLimit,
00339     kFileCacheCleanIntervalMs,
00340     kFileCacheCleanSizeKb,
00341     kFileCachePath,
00342     kLruCacheByteLimit,
00343     kLruCacheKbPerProcess,
00344     kMemcachedServers,
00345     kMemcachedThreads,
00346     kMemcachedTimeoutUs,
00347     kMessageBufferSize,
00348     kRateLimitBackgroundFetches,
00349     kSlurpDirectory,
00350     kSlurpFlushLimit,
00351     kSlurpReadOnly,
00352     kStatisticsEnabled,
00353     kStatisticsLoggingChartsCSS,
00354     kStatisticsLoggingChartsJS,
00355     kStatisticsLoggingEnabled,
00356     kStatisticsLoggingFile,
00357     kStatisticsLoggingIntervalMs,
00358     kStatisticsLoggingMaxFileSizeKb,
00359     kTestProxy,
00360     kTestProxySlurp,
00361     kUseSharedMemLocking,
00362 
00365     kEndOfOptions
00366   };
00367 
00368   struct BeaconUrl {
00369     GoogleString http;
00370     GoogleString https;
00371   };
00372 
00373   struct NameValue {
00374     NameValue(const StringPiece& name_in, const StringPiece& value_in) {
00375       name_in.CopyToString(&name);
00376       value_in.CopyToString(&value);
00377     }
00378     GoogleString name;
00379     GoogleString value;
00380   };
00381 
00397   static const int kOptionsVersion = 13;
00398 
00400   static const int kHashBytes = 20;
00401 
00406   enum OptionScope {
00407     kDirectoryScope,  
00408     kServerScope,     
00409     kProcessScope,    
00410   };
00411 
00412   static const char kCacheExtenderId[];
00413   static const char kCollectFlushEarlyContentFilterId[];
00414   static const char kCssCombinerId[];
00415   static const char kCssFilterId[];
00416   static const char kCssImportFlattenerId[];
00417   static const char kCssInlineId[];
00418   static const char kImageCombineId[];
00419   static const char kImageCompressionId[];
00420   static const char kInPlaceRewriteId[];
00421   static const char kJavascriptCombinerId[];
00422   static const char kJavascriptInlineId[];
00423   static const char kJavascriptMinId[];
00424   static const char kLocalStorageCacheId[];
00425   static const char kPrioritizeCriticalCssId[];
00426 
00427   static const char kPanelCommentPrefix[];
00428 
00431   static const char* FilterName(Filter filter);
00432 
00435   static const char* FilterId(Filter filter);
00436 
00439   static int NumFilterIds();
00440 
00442   static const Filter kFirstFilter = kAddBaseTag;
00443 
00444   typedef EnumSet<Filter, kEndOfFilters> FilterSet;
00445   typedef std::vector<Filter> FilterVector;
00446 
00448   typedef std::set<GoogleString> FilterIdSet;
00449 
00455   static bool AddByNameToFilterSet(const StringPiece& option, FilterSet* set,
00456                                    MessageHandler* handler);
00457 
00460   typedef std::pair<StringPiece, StringPiece> OptionStringPair;
00461   typedef std::set<OptionStringPair> OptionSet;
00462 
00465   class PropertyBase {
00466    public:
00467     PropertyBase(const char* id, OptionEnum option_enum)
00468         : id_(id),
00469           help_text_(NULL),
00470           option_enum_(option_enum),
00471           scope_(kDirectoryScope),
00472           do_not_use_for_signature_computation_(false),
00473           index_(-1) {
00474     }
00475     virtual ~PropertyBase();
00476 
00479     virtual void InitializeOption(RewriteOptions* options) const = 0;
00480 
00481     void set_do_not_use_for_signature_computation(bool x) {
00482       do_not_use_for_signature_computation_ = x;
00483     }
00484     bool is_used_for_signature_computation() const {
00485       return !do_not_use_for_signature_computation_;
00486     }
00487 
00488     void set_scope(OptionScope x) { scope_ = x; }
00489     OptionScope scope() const { return scope_; }
00490 
00491     void set_help_text(const char* x) { help_text_ = x; }
00492     const char* help_text() const { return help_text_; }
00493 
00494     void set_index(int index) { index_ = index; }
00495     const char* id() const { return id_; }
00496     OptionEnum option_enum() const { return option_enum_; }
00497     int index() const { return index_; }
00498 
00499    private:
00500     const char* id_;
00501     const char* help_text_;
00502     OptionEnum option_enum_; 
00503     OptionScope scope_;
00504     bool do_not_use_for_signature_computation_; 
00505     int index_;
00506 
00507     DISALLOW_COPY_AND_ASSIGN(PropertyBase);
00508   };
00509 
00510   typedef std::vector<PropertyBase*> PropertyVector;
00511 
00514   class OptionBase {
00515    public:
00516     OptionBase() {}
00517     virtual ~OptionBase();
00518 
00520     virtual bool SetFromString(const GoogleString& value_string) = 0;
00521     virtual void Merge(const OptionBase* src) = 0;
00522     virtual bool was_set() const = 0;
00523     virtual GoogleString Signature(const Hasher* hasher) const = 0;
00524     virtual GoogleString ToString() const = 0;
00525     const char* id() const { return property()->id(); }
00526     const char* help_text() const { return property()->help_text(); }
00527     OptionScope scope() const { return property()->scope(); }
00528     OptionEnum option_enum() const { return property()->option_enum(); }
00529     bool is_used_for_signature_computation() const {
00530       return property()->is_used_for_signature_computation();
00531     }
00532     virtual const PropertyBase* property() const = 0;
00533   };
00534 
00536   typedef std::vector<OptionBase*> OptionBaseVector;
00537 
00538   enum RewriteLevel {
00543     kPassThrough,
00544 
00550     kCoreFilters,
00551 
00555     kTestingCoreFilters,
00556 
00559     kAllFilters,
00560   };
00561 
00563   enum OptionSettingResult {
00564     kOptionOk,
00565     kOptionNameUnknown,
00566     kOptionValueInvalid
00567   };
00568 
00569   static const int kDefaultBeaconReinstrumentTimeSec;
00570   static const int64 kDefaultBlinkMaxHtmlSizeRewritable;
00571   static const int64 kDefaultCssFlattenMaxBytes;
00572   static const int64 kDefaultCssImageInlineMaxBytes;
00573   static const int64 kDefaultCssInlineMaxBytes;
00574   static const int64 kDefaultCssOutlineMinBytes;
00575   static const int64 kDefaultImageInlineMaxBytes;
00576   static const int64 kDefaultJsInlineMaxBytes;
00577   static const int64 kDefaultJsOutlineMinBytes;
00578   static const int64 kDefaultProgressiveJpegMinBytes;
00579   static const int64 kDefaultMaxCacheableResponseContentLength;
00580   static const int64 kDefaultMaxHtmlCacheTimeMs;
00581   static const int64 kDefaultMaxHtmlParseBytes;
00582   static const int64 kDefaultMaxImageBytesForWebpInCss;
00583   static const int64 kDefaultMetadataInputErrorsCacheTtlMs;
00584   static const int64 kDefaultMinResourceCacheTimeToRewriteMs;
00585   static const int64 kDefaultCacheInvalidationTimestamp;
00586   static const int64 kDefaultIdleFlushTimeMs;
00587   static const int64 kDefaultFlushBufferLimitBytes;
00588   static const int64 kDefaultImplicitCacheTtlMs;
00589   static const int64 kDefaultPrioritizeVisibleContentCacheTimeMs;
00590   static const char kDefaultBeaconUrl[];
00591   static const int64 kDefaultImagesRecompressQuality;
00592   static const int64 kDefaultImageJpegRecompressQuality;
00593   static const int kDefaultImageLimitOptimizedPercent;
00594   static const int kDefaultImageLimitResizeAreaPercent;
00595   static const int64 kDefaultImageResolutionLimitBytes;
00596   static const int64 kDefaultImageJpegNumProgressiveScans;
00597   static const int64 kDefaultImageWebpRecompressQuality;
00598   static const int64 kDefaultImageWebpTimeoutMs;
00599   static const int kDefaultDomainShardCount;
00600   static const int64 kDefaultBlinkHtmlChangeDetectionTimeMs;
00601   static const int64 kDefaultOverrideBlinkCacheTimeMs;
00602 
00605   static const int kDefaultMaxUrlSize;
00606 
00607   static const int kDefaultImageMaxRewritesAtOnce;
00608 
00613   static const int kDefaultMaxUrlSegmentSize;
00614 
00616   static const int kDefaultRewriteDeadlineMs;
00617 
00619   static const int64 kDefaultDistributedTimeoutMs;
00620 
00623   static const int kDefaultMaxInlinedPreviewImagesIndex;
00626   static const int64 kDefaultMinImageSizeLowResolutionBytes;
00629   static const int64 kDefaultMaxImageSizeLowResolutionBytes;
00631   static const int64 kDefaultFinderPropertiesCacheExpirationTimeMs;
00633   static const int64 kDefaultFinderPropertiesCacheRefreshTimeMs;
00634 
00637   static const int64 kDefaultFuriousCookieDurationMs;
00638 
00641   static const int64 kDefaultMetadataCacheStalenessThresholdMs;
00642 
00644   static const int64 kDefaultMaxCombinedJsBytes;
00645 
00646   static const int kDefaultFuriousTrafficPercent;
00648   static const int kDefaultFuriousSlot;
00649 
00650   static const char kDefaultBlockingRewriteKey[];
00651 
00652   static const char kRejectedRequestUrlKeyName[];
00653 
00654   static const int kDefaultPropertyCacheHttpStatusStabilityThreshold;
00655 
00656   static const int kDefaultMaxRewriteInfoLogSize;
00657 
00666   class FuriousSpec {
00667    public:
00672     FuriousSpec(const StringPiece& spec, RewriteOptions* options,
00673                 MessageHandler* handler);
00674 
00678     explicit FuriousSpec(int id);
00679 
00680     virtual ~FuriousSpec();
00681 
00683     virtual FuriousSpec* Clone();
00684 
00685     bool is_valid() const { return id_ >= 0; }
00686 
00688     int id() const { return id_; }
00689     int percent() const { return percent_; }
00690     GoogleString ga_id() const { return ga_id_; }
00691     int slot() const { return ga_variable_slot_; }
00692     RewriteLevel rewrite_level() const { return rewrite_level_; }
00693     FilterSet enabled_filters() const { return enabled_filters_; }
00694     FilterSet disabled_filters() const { return disabled_filters_; }
00695     OptionSet filter_options() const { return filter_options_; }
00696     int64 css_inline_max_bytes() const { return css_inline_max_bytes_; }
00697     int64 js_inline_max_bytes() const { return js_inline_max_bytes_; }
00698     int64 image_inline_max_bytes() const { return image_inline_max_bytes_; }
00699     bool use_default() const { return use_default_; }
00700 
00701    protected:
00705     void Merge(const FuriousSpec& spec);
00706 
00707    private:
00708     FRIEND_TEST(RewriteOptionsTest, FuriousMergeTest);
00709 
00712     void Initialize(const StringPiece& spec, MessageHandler* handler);
00713 
00714     int id_; 
00715     GoogleString ga_id_; 
00716     int ga_variable_slot_;
00717     int percent_; 
00718     RewriteLevel rewrite_level_;
00719     FilterSet enabled_filters_;
00720     FilterSet disabled_filters_;
00721     OptionSet filter_options_;
00722     int64 css_inline_max_bytes_;
00723     int64 js_inline_max_bytes_;
00724     int64 image_inline_max_bytes_;
00727     bool use_default_;
00728     DISALLOW_COPY_AND_ASSIGN(FuriousSpec);
00729   };
00730 
00732   struct ElementAttributeCategory {
00733     GoogleString element;
00734     GoogleString attribute;
00735     semantic_type::Category category;
00736   };
00737 
00744   class Properties {
00745    public:
00754     static bool Initialize(Properties** properties);
00755 
00764     static bool Terminate(Properties** properties_handle);
00765 
00767     int size() const { return property_vector_.size(); }
00768 
00769     const PropertyBase* property(int index) const {
00770       return property_vector_[index];
00771     }
00772     PropertyBase* property(int index) { return property_vector_[index]; }
00773 
00779     void Merge(Properties* properties);
00780 
00781     void push_back(PropertyBase* p) { property_vector_.push_back(p); }
00782 
00783    private:
00786     Properties();
00787     ~Properties();
00788 
00792     int initialization_count_;
00793 
00798     bool owns_properties_;
00799     PropertyVector property_vector_;
00800   };
00801 
00803   struct FilterEnumToIdAndNameEntry {
00804     RewriteOptions::Filter filter_enum;
00805     const char* filter_id;
00806     const char* filter_name;
00807   };
00808 
00809   static bool ParseRewriteLevel(const StringPiece& in, RewriteLevel* out);
00810 
00814   static bool ParseBeaconUrl(const StringPiece& in, BeaconUrl* out);
00815 
00819   bool ImageOptimizationEnabled() const;
00820 
00821   explicit RewriteOptions(ThreadSystem* thread_system);
00822   virtual ~RewriteOptions();
00823 
00827   static bool Initialize();
00828   static bool Terminate();
00829 
00830 #ifndef NDEBUG
00831 
00832 
00833 
00834 
00835 
00836 
00837   bool ModificationOK() const;
00838 
00845   bool MergeOK() const;
00846 #endif
00847 
00852   void InitializeOptions(const Properties* properties);
00853 
00854   bool modified() const { return modified_; }
00855 
00861   void SetDefaultRewriteLevel(RewriteLevel level) {
00863     level_.set_default(level);
00864   }
00865   void SetRewriteLevel(RewriteLevel level) {
00866     set_option(level, &level_);
00867   }
00868 
00870   void AddCustomFetchHeader(const StringPiece& name, const StringPiece& value);
00871 
00872   const NameValue* custom_fetch_header(int i) const {
00873     return custom_fetch_headers_[i];
00874   }
00875 
00876   int num_custom_fetch_headers() const {
00877     return custom_fetch_headers_.size();
00878   }
00879 
00882   FuriousSpec* GetFuriousSpec(int id) const;
00883 
00887   bool AvailableFuriousId(int id);
00888 
00891   virtual bool AddFuriousSpec(const StringPiece& spec, MessageHandler* handler);
00892 
00900   virtual bool SetFuriousState(int id);
00901 
00905   void SetFuriousStateStr(const StringPiece& experiment_index);
00906 
00907   int furious_id() const { return furious_id_; }
00908 
00909   int furious_spec_id(int i) const {
00910     return furious_specs_[i]->id();
00911   }
00912 
00916   GoogleString GetFuriousStateStr() const;
00917 
00918   FuriousSpec* furious_spec(int i) const {
00919     return furious_specs_[i];
00920   }
00921 
00922   int num_furious_experiments() const { return furious_specs_.size(); }
00923 
00935   void AddUrlValuedAttribute(const StringPiece& element,
00936                              const StringPiece& attribute,
00937                              semantic_type::Category category);
00938 
00941   void UrlValuedAttribute(int index,
00942                           StringPiece* element,
00943                           StringPiece* attribute,
00944                           semantic_type::Category* category) const;
00945 
00946   int num_url_valued_attributes() const {
00947     if (url_valued_attributes_ == NULL) {
00948       return 0;
00949     } else {
00950       return url_valued_attributes_->size();
00951     }
00952   }
00953 
00955   bool RegisterLibrary(
00956       uint64 bytes, StringPiece md5_hash, StringPiece canonical_url) {
00957     return javascript_library_identification_.RegisterLibrary(
00958         bytes, md5_hash, canonical_url);
00959   }
00960 
00963   const JavascriptLibraryIdentification* javascript_library_identification()
00964       const {
00965     if (Enabled(kCanonicalizeJavascriptLibraries)) {
00966       return &javascript_library_identification_;
00967     } else {
00968       return NULL;
00969     }
00970   }
00971 
00972   RewriteLevel level() const { return level_.value(); }
00973 
00978   bool AdjustFiltersByCommaSeparatedList(const StringPiece& filters,
00979                                          MessageHandler* handler);
00980 
00984   bool EnableFiltersByCommaSeparatedList(const StringPiece& filters,
00985                                          MessageHandler* handler);
00986 
00990   bool DisableFiltersByCommaSeparatedList(const StringPiece& filters,
00991                                           MessageHandler* handler);
00992 
00996   bool ForbidFiltersByCommaSeparatedList(const StringPiece& filters,
00997                                          MessageHandler* handler);
00998 
01000   void DisableAllFilters();
01001 
01009   void DisableAllFiltersNotExplicitlyEnabled();
01010 
01013   void DistributeFiltersByCommaSeparatedList(const StringPiece& filter_ids,
01014                                                MessageHandler* handler);
01017   void DistributeFilter(const StringPiece& filter_id);
01018 
01021   bool Distributable(const StringPiece& filter_id) const;
01022 
01026   void EnableFilter(Filter filter);
01029   void ForceEnableFilter(Filter filter);
01030   void DisableFilter(Filter filter);
01031   void ForbidFilter(Filter filter);
01032   void EnableFilters(const FilterSet& filter_set);
01033   void DisableFilters(const FilterSet& filter_set);
01034   void ForbidFilters(const FilterSet& filter_set);
01037   void ClearFilters();
01038 
01041   void EnableExtendCacheFilters();
01042 
01043   bool Enabled(Filter filter) const;
01044   bool Forbidden(Filter filter) const;
01045   bool Forbidden(StringPiece filter_id) const;
01046 
01048   void GetEnabledFiltersRequiringScriptExecution(FilterVector* filters) const;
01049 
01051   void DisableFiltersRequiringScriptExecution();
01052 
01057   static bool AddCommaSeparatedListToOptionSet(
01058       const StringPiece& options, OptionSet* set, MessageHandler* handler);
01059 
01064   OptionSettingResult SetOptionFromName(
01065       StringPiece name, StringPiece value, GoogleString* msg);
01066 
01072   OptionSettingResult ParseAndSetOptionFromName1(
01073       StringPiece name, StringPiece arg,
01074       GoogleString* msg, MessageHandler* handler);
01075 
01076   OptionSettingResult ParseAndSetOptionFromName2(
01077       StringPiece name, StringPiece arg1, StringPiece arg2,
01078       GoogleString* msg, MessageHandler* handler);
01079 
01080   OptionSettingResult ParseAndSetOptionFromName3(
01081       StringPiece name, StringPiece arg1, StringPiece arg2, StringPiece arg3,
01082       GoogleString* msg, MessageHandler* handler);
01083 
01087   virtual OptionSettingResult ParseAndSetOptionFromEnum1(
01088       OptionEnum name, StringPiece arg,
01089       GoogleString* msg, MessageHandler* handler);
01090 
01091   virtual OptionSettingResult ParseAndSetOptionFromEnum2(
01092       OptionEnum name, StringPiece arg1, StringPiece arg2,
01093       GoogleString* msg, MessageHandler* handler);
01094 
01095   virtual OptionSettingResult ParseAndSetOptionFromEnum3(
01096       OptionEnum name, StringPiece arg1, StringPiece arg2, StringPiece arg3,
01097       GoogleString* msg, MessageHandler* handler);
01098 
01100   OptionSettingResult SetOptionFromEnum(OptionEnum option_enum,
01101                                         StringPiece value);
01102 
01108   bool OptionValue(OptionEnum option_enum, const char** id,
01109                    bool* was_set, GoogleString* value) const;
01110 
01113   bool SetOptionsFromName(const OptionSet& option_set);
01114 
01117   bool SetOptionFromNameAndLog(StringPiece name,
01118                                StringPiece value,
01119                                MessageHandler* handler);
01120 
01123   static bool ParseFromString(const GoogleString& value_string, bool* value);
01124   static bool ParseFromString(const GoogleString& value_string,
01125                               EnabledEnum* value);
01126   static bool ParseFromString(const GoogleString& value_string, int* value) {
01127     return StringToInt(value_string, value);
01128   }
01129   static bool ParseFromString(const GoogleString& value_string, int64* value) {
01130     return StringToInt64(value_string, value);
01131   }
01132   static bool ParseFromString(const GoogleString& value_string,
01133                               GoogleString* value) {
01134     *value = value_string;
01135     return true;
01136   }
01137   static bool ParseFromString(const GoogleString& value_string,
01138                               RewriteLevel* value) {
01139     return ParseRewriteLevel(value_string, value);
01140   }
01141   static bool ParseFromString(const GoogleString& value_string,
01142                               BeaconUrl* value) {
01143     return ParseBeaconUrl(value_string, value);
01144   }
01145 
01148   int64 css_outline_min_bytes() const { return css_outline_min_bytes_.value(); }
01149   void set_css_outline_min_bytes(int64 x) {
01150     set_option(x, &css_outline_min_bytes_);
01151   }
01152 
01153   GoogleString ga_id() const { return ga_id_.value(); }
01154   void set_ga_id(GoogleString id) {
01155     set_option(id, &ga_id_);
01156   }
01157 
01158   bool increase_speed_tracking() const {
01159     return increase_speed_tracking_.value();
01160   }
01161   void set_increase_speed_tracking(bool x) {
01162     set_option(x, &increase_speed_tracking_);
01163   }
01164 
01165   int64 js_outline_min_bytes() const { return js_outline_min_bytes_.value(); }
01166   void set_js_outline_min_bytes(int64 x) {
01167     set_option(x, &js_outline_min_bytes_);
01168   }
01169 
01170   int64 progressive_jpeg_min_bytes() const {
01171     return progressive_jpeg_min_bytes_.value();
01172   }
01173   void set_progressive_jpeg_min_bytes(int64 x) {
01174     set_option(x, &progressive_jpeg_min_bytes_);
01175   }
01176 
01177   int64 css_flatten_max_bytes() const { return css_flatten_max_bytes_.value(); }
01178   void set_css_flatten_max_bytes(int64 x) {
01179     set_option(x, &css_flatten_max_bytes_);
01180   }
01181   bool cache_small_images_unrewritten() const {
01182     return cache_small_images_unrewritten_.value();
01183   }
01184   void set_cache_small_images_unrewritten(bool x) {
01185     set_option(x, &cache_small_images_unrewritten_);
01186   }
01187   int64 image_resolution_limit_bytes() const {
01188     return image_resolution_limit_bytes_.value();
01189   }
01190   void set_image_resolution_limit_bytes(int64 x) {
01191     set_option(x, &image_resolution_limit_bytes_);
01192   }
01193 
01195   int64 ImageInlineMaxBytes() const;
01196   void set_image_inline_max_bytes(int64 x);
01198   int64 CssImageInlineMaxBytes() const;
01199   void set_css_image_inline_max_bytes(int64 x) {
01200     set_option(x, &css_image_inline_max_bytes_);
01201   }
01203   int64 MaxImageInlineMaxBytes() const;
01204   int64 css_inline_max_bytes() const { return css_inline_max_bytes_.value(); }
01205   void set_css_inline_max_bytes(int64 x) {
01206     set_option(x, &css_inline_max_bytes_);
01207   }
01208   int64 js_inline_max_bytes() const { return js_inline_max_bytes_.value(); }
01209   void set_js_inline_max_bytes(int64 x) {
01210     set_option(x, &js_inline_max_bytes_);
01211   }
01212   int64 max_html_cache_time_ms() const {
01213     return max_html_cache_time_ms_.value();
01214   }
01215   void set_max_html_cache_time_ms(int64 x) {
01216     set_option(x, &max_html_cache_time_ms_);
01217   }
01218   int64 max_html_parse_bytes() const {
01219     return max_html_parse_bytes_.value();
01220   }
01221   void set_max_html_parse_bytes(int64 x) {
01222     set_option(x, &max_html_parse_bytes_);
01223   }
01224   int64 max_image_bytes_for_webp_in_css() const {
01225     return max_image_bytes_for_webp_in_css_.value();
01226   }
01227   void set_max_image_bytes_for_webp_in_css(int64 x) {
01228     set_option(x, &max_image_bytes_for_webp_in_css_);
01229   }
01230   int64 max_cacheable_response_content_length() const {
01231     return max_cacheable_response_content_length_.value();
01232   }
01233   void set_max_cacheable_response_content_length(int64 x) {
01234     set_option(x, &max_cacheable_response_content_length_);
01235   }
01236   int64 min_resource_cache_time_to_rewrite_ms() const {
01237     return min_resource_cache_time_to_rewrite_ms_.value();
01238   }
01239   void set_min_resource_cache_time_to_rewrite_ms(int64 x) {
01240     set_option(x, &min_resource_cache_time_to_rewrite_ms_);
01241   }
01242   bool need_to_store_experiment_data() const {
01243     return need_to_store_experiment_data_;
01244   }
01245   void set_need_to_store_experiment_data(bool x) {
01246     need_to_store_experiment_data_ = x;
01247   }
01248 
01249   int64 blocking_fetch_timeout_ms() const {
01250     return blocking_fetch_timeout_ms_.value();
01251   }
01252   void set_blocking_fetch_timeout_ms(int64 x) {
01253     set_option(x, &blocking_fetch_timeout_ms_);
01254   }
01255   bool override_ie_document_mode() const {
01256     return override_ie_document_mode_.value();
01257   }
01258   void set_override_ie_document_mode(bool x) {
01259     set_option(x, &override_ie_document_mode_);
01260   }
01261 
01262   int64 blink_blacklist_end_timestamp_ms() const {
01263     return blink_blacklist_end_timestamp_ms_.value();
01264   }
01265   void set_blink_blacklist_end_timestamp_ms(int64 x) {
01266     set_option(x, &blink_blacklist_end_timestamp_ms_);
01267   }
01268 
01269   bool persist_blink_blacklist() const {
01270     return persist_blink_blacklist_.value();
01271   }
01272   void set_persist_blink_blacklist(bool x) {
01273     set_option(x, &persist_blink_blacklist_);
01274   }
01275 
01279   bool IsUrlCacheValid(StringPiece url, int64 time_ms) const;
01280 
01284   bool IsUrlPurged(StringPiece url, int64 time_ms) const;
01285 
01302   void AddUrlCacheInvalidationEntry(StringPiece url_pattern,
01303                                     int64 timestamp_ms,
01304                                     bool ignores_metadata_and_pcache);
01305 
01307   void PurgeUrl(StringPiece url, int64 timestamp_ms);
01308 
01311   bool IsUrlCacheInvalidationEntriesSorted() const;
01312 
01315   void set_cache_invalidation_timestamp_mutex(ThreadSystem::RWLock* lock) {
01316     cache_invalidation_timestamp_.set_mutex(lock);
01317   }
01318 
01320   int64 cache_invalidation_timestamp() const {
01321     ThreadSystem::ScopedReader lock(cache_invalidation_timestamp_.mutex());
01322     return cache_invalidation_timestamp_.value();
01323   }
01324 
01331   void set_cache_invalidation_timestamp(int64 timestamp_ms) {
01332     cache_invalidation_timestamp_.mutex()->DCheckLocked();
01333     DCHECK_LT(0, timestamp_ms);
01334     set_option(timestamp_ms, &cache_invalidation_timestamp_);
01335   }
01336 
01343   bool UpdateCacheInvalidationTimestampMs(int64 timestamp_ms);
01344 
01347   int64 idle_flush_time_ms() const {
01348     return idle_flush_time_ms_.value();
01349   }
01350   void set_idle_flush_time_ms(int64 x) {
01351     set_option(x, &idle_flush_time_ms_);
01352   }
01353 
01355   int64 flush_buffer_limit_bytes() const {
01356     return flush_buffer_limit_bytes_.value();
01357   }
01358 
01359   void set_flush_buffer_limit_bytes(int64 x) {
01360     set_option(x, &flush_buffer_limit_bytes_);
01361   }
01362 
01365   int max_url_segment_size() const { return max_url_segment_size_.value(); }
01366   void set_max_url_segment_size(int x) {
01367     set_option(x, &max_url_segment_size_);
01368   }
01369 
01370   int image_max_rewrites_at_once() const {
01371     return image_max_rewrites_at_once_.value();
01372   }
01373   void set_image_max_rewrites_at_once(int x) {
01374     set_option(x, &image_max_rewrites_at_once_);
01375   }
01376 
01378   int max_url_size() const { return max_url_size_.value(); }
01379   void set_max_url_size(int x) {
01380     set_option(x, &max_url_size_);
01381   }
01382 
01383   int rewrite_deadline_ms() const { return rewrite_deadline_ms_.value(); }
01384   void set_rewrite_deadline_ms(int x) {
01385     set_option(x, &rewrite_deadline_ms_);
01386   }
01387 
01388   bool test_instant_fetch_rewrite_deadline() const {
01389     return test_instant_fetch_rewrite_deadline_.value();
01390   }
01391   void set_test_instant_fetch_rewrite_deadline(bool x) {
01392     set_option(x, &test_instant_fetch_rewrite_deadline_);
01393   }
01394 
01395   void set_test_only_prioritize_critical_css_dont_apply_original_css(bool x) {
01396     set_option(x, &test_only_prioritize_critical_css_dont_apply_original_css_);
01397   }
01398   bool test_only_prioritize_critical_css_dont_apply_original_css() const {
01399     return test_only_prioritize_critical_css_dont_apply_original_css_.value();
01400   }
01401 
01402   int domain_shard_count() const { return domain_shard_count_.value(); }
01405   void set_domain_shard_count(int64 x) {
01406     int value = x;
01407     set_option(value, &domain_shard_count_);
01408   }
01409 
01410   void set_enabled(EnabledEnum x) {
01411     set_option(x, &enabled_);
01412   }
01413   bool enabled() const {
01414     return enabled_.value() == kEnabledOn;
01415   }
01416   bool unplugged() const {
01417     return enabled_.value() == kEnabledUnplugged;
01418   }
01419 
01420   void set_add_options_to_urls(bool x) {
01421     set_option(x, &add_options_to_urls_);
01422   }
01423 
01424   bool add_options_to_urls() const {
01425     return add_options_to_urls_.value();
01426   }
01427 
01428   void set_in_place_rewriting_enabled(bool x) {
01429     set_option(x, &in_place_rewriting_enabled_);
01430   }
01431 
01432   void set_oblivious_pagespeed_urls(bool x) {
01433     set_option(x, &oblivious_pagespeed_urls_);
01434   }
01435 
01436   bool oblivious_pagespeed_urls() const {
01437     return oblivious_pagespeed_urls_.value();
01438   }
01439 
01440   bool in_place_rewriting_enabled() const {
01441     return in_place_rewriting_enabled_.value();
01442   }
01443 
01444   void set_in_place_wait_for_optimized(bool x) {
01445     set_option(x, &in_place_wait_for_optimized_);
01446   }
01447 
01448   bool in_place_wait_for_optimized() const {
01449     return in_place_wait_for_optimized_.value();
01450   }
01451 
01452   void set_in_place_rewrite_deadline_ms(int x) {
01453     set_option(x, &in_place_rewrite_deadline_ms_);
01454   }
01455 
01456   int in_place_rewrite_deadline_ms() const {
01457     return in_place_rewrite_deadline_ms_.value();
01458   }
01459 
01460   void set_in_place_preemptive_rewrite_css(bool x) {
01461     set_option(x, &in_place_preemptive_rewrite_css_);
01462   }
01463   bool in_place_preemptive_rewrite_css() const {
01464     return in_place_preemptive_rewrite_css_.value();
01465   }
01466 
01467   void set_in_place_preemptive_rewrite_css_images(bool x) {
01468     set_option(x, &in_place_preemptive_rewrite_css_images_);
01469   }
01470   bool in_place_preemptive_rewrite_css_images() const {
01471     return in_place_preemptive_rewrite_css_images_.value();
01472   }
01473 
01474   void set_in_place_preemptive_rewrite_images(bool x) {
01475     set_option(x, &in_place_preemptive_rewrite_images_);
01476   }
01477   bool in_place_preemptive_rewrite_images() const {
01478     return in_place_preemptive_rewrite_images_.value();
01479   }
01480 
01481   void set_in_place_preemptive_rewrite_javascript(bool x) {
01482     set_option(x, &in_place_preemptive_rewrite_javascript_);
01483   }
01484   bool in_place_preemptive_rewrite_javascript() const {
01485     return in_place_preemptive_rewrite_javascript_.value();
01486   }
01487 
01488   void set_combine_across_paths(bool x) {
01489     set_option(x, &combine_across_paths_);
01490   }
01491   bool combine_across_paths() const { return combine_across_paths_.value(); }
01492 
01493   void set_log_background_rewrites(bool x) {
01494     set_option(x, &log_background_rewrites_);
01495   }
01496   bool log_background_rewrites() const {
01497     return log_background_rewrites_.value();
01498   }
01499 
01500   void set_log_rewrite_timing(bool x) {
01501     set_option(x, &log_rewrite_timing_);
01502   }
01503   bool log_rewrite_timing() const { return log_rewrite_timing_.value(); }
01504 
01505   void set_log_url_indices(bool x) {
01506     set_option(x, &log_url_indices_);
01507   }
01508   bool log_url_indices() const { return log_url_indices_.value(); }
01509 
01510   void set_lowercase_html_names(bool x) {
01511     set_option(x, &lowercase_html_names_);
01512   }
01513   bool lowercase_html_names() const { return lowercase_html_names_.value(); }
01514 
01515   void set_always_rewrite_css(bool x) {
01516     set_option(x, &always_rewrite_css_);
01517   }
01518   bool always_rewrite_css() const { return always_rewrite_css_.value(); }
01519 
01520   void set_respect_vary(bool x) {
01521     set_option(x, &respect_vary_);
01522   }
01523   bool respect_vary() const { return respect_vary_.value(); }
01524 
01525   void set_respect_x_forwarded_proto(bool x) {
01526     set_option(x, &respect_x_forwarded_proto_);
01527   }
01528   bool respect_x_forwarded_proto() const {
01529     return respect_x_forwarded_proto_.value();
01530   }
01531 
01532   void set_flush_html(bool x) { set_option(x, &flush_html_); }
01533   bool flush_html() const { return flush_html_.value(); }
01534 
01535   void set_serve_stale_if_fetch_error(bool x) {
01536     set_option(x, &serve_stale_if_fetch_error_);
01537   }
01538   bool serve_stale_if_fetch_error() const {
01539     return serve_stale_if_fetch_error_.value();
01540   }
01541 
01542   void set_enable_blink_critical_line(bool x) {
01543     set_option(x, &enable_blink_critical_line_);
01544   }
01545   bool enable_blink_critical_line() const {
01546     return enable_blink_critical_line_.value();
01547   }
01548 
01549   void set_enable_flush_early_critical_css(bool x) {
01550     set_option(x, &enable_flush_early_critical_css_);
01551   }
01552   bool enable_flush_early_critical_css() const {
01553     return enable_flush_early_critical_css_.value();
01554   }
01555 
01556   void set_default_cache_html(bool x) { set_option(x, &default_cache_html_); }
01557   bool default_cache_html() const { return default_cache_html_.value(); }
01558 
01559   void set_modify_caching_headers(bool x) {
01560     set_option(x, &modify_caching_headers_);
01561   }
01562   bool modify_caching_headers() const {
01563     return modify_caching_headers_.value();
01564   }
01565 
01566   void set_inline_only_critical_images(bool x) {
01567     set_option(x, &inline_only_critical_images_);
01568   }
01569   bool inline_only_critical_images() const {
01570     return inline_only_critical_images_.value();
01571   }
01572 
01573   void set_critical_images_beacon_enabled(bool x) {
01574     set_option(x, &critical_images_beacon_enabled_);
01575   }
01576   bool critical_images_beacon_enabled() const {
01577     return critical_images_beacon_enabled_.value();
01578   }
01579 
01580   void set_beacon_reinstrument_beacon_time_sec(int x) {
01581     set_option(x, &beacon_reinstrument_time_sec_);
01582   }
01583   int beacon_reinstrument_time_sec() const {
01584     return beacon_reinstrument_time_sec_.value();
01585   }
01586 
01587   void set_lazyload_images_after_onload(bool x) {
01588     set_option(x, &lazyload_images_after_onload_);
01589   }
01590   bool lazyload_images_after_onload() const {
01591     return lazyload_images_after_onload_.value();
01592   }
01593 
01594   void set_lazyload_images_blank_url(const StringPiece& p) {
01595     set_option(GoogleString(p.data(), p.size()), &lazyload_images_blank_url_);
01596   }
01597   const GoogleString& lazyload_images_blank_url() const {
01598     return lazyload_images_blank_url_.value();
01599   }
01600 
01601   void set_max_inlined_preview_images_index(int x) {
01602     set_option(x, &max_inlined_preview_images_index_);
01603   }
01604   int max_inlined_preview_images_index() const {
01605     return max_inlined_preview_images_index_.value();
01606   }
01607 
01608   void set_min_image_size_low_resolution_bytes(int64 x) {
01609     set_option(x, &min_image_size_low_resolution_bytes_);
01610   }
01611   int64 min_image_size_low_resolution_bytes() const {
01612     return min_image_size_low_resolution_bytes_.value();
01613   }
01614 
01615   void set_max_image_size_low_resolution_bytes(int64 x) {
01616     set_option(x, &max_image_size_low_resolution_bytes_);
01617   }
01618   int64 max_image_size_low_resolution_bytes() const {
01619     return max_image_size_low_resolution_bytes_.value();
01620   }
01621 
01622   void set_furious_cookie_duration_ms(int64 x) {
01623     set_option(x, &furious_cookie_duration_ms_);
01624   }
01625   int64 furious_cookie_duration_ms() const {
01626     return furious_cookie_duration_ms_.value();
01627   }
01628 
01629   void set_finder_properties_cache_expiration_time_ms(int64 x) {
01630     set_option(x, &finder_properties_cache_expiration_time_ms_);
01631   }
01632   int64 finder_properties_cache_expiration_time_ms() const {
01633     return finder_properties_cache_expiration_time_ms_.value();
01634   }
01635 
01636   void set_finder_properties_cache_refresh_time_ms(int64 x) {
01637     set_option(x, &finder_properties_cache_refresh_time_ms_);
01638   }
01639   int64 finder_properties_cache_refresh_time_ms() const {
01640     return finder_properties_cache_refresh_time_ms_.value();
01641   }
01642   bool css_preserve_urls() const {
01643     return css_preserve_urls_.value();
01644   }
01645   void set_css_preserve_urls(bool x) {
01646     set_option(x, &css_preserve_urls_);
01647   }
01648 
01649   bool image_preserve_urls() const {
01650     return image_preserve_urls_.value();
01651   }
01652   void set_image_preserve_urls(bool x) {
01653     set_option(x, &image_preserve_urls_);
01654   }
01655 
01656   bool js_preserve_urls() const {
01657     return js_preserve_urls_.value();
01658   }
01659   void set_js_preserve_urls(bool x) {
01660     set_option(x, &js_preserve_urls_);
01661   }
01662 
01663   void set_metadata_cache_staleness_threshold_ms(int64 x) {
01664     set_option(x, &metadata_cache_staleness_threshold_ms_);
01665   }
01666   int64 metadata_cache_staleness_threshold_ms() const {
01667     return metadata_cache_staleness_threshold_ms_.value();
01668   }
01669 
01670   void set_metadata_input_errors_cache_ttl_ms(int64 x) {
01671     set_option(x, &metadata_input_errors_cache_ttl_ms_);
01672   }
01673   int64 metadata_input_errors_cache_ttl_ms() const {
01674     return metadata_input_errors_cache_ttl_ms_.value();
01675   }
01676 
01677   const BeaconUrl& beacon_url() const { return beacon_url_.value(); }
01678   void set_beacon_url(const GoogleString& beacon_url) {
01679     beacon_url_.SetFromString(beacon_url);
01680   }
01681 
01683   virtual bool trim_urls_in_css() const { return true; }
01684 
01685   int64 image_jpeg_recompress_quality() const {
01686     return image_jpeg_recompress_quality_.value();
01687   }
01688   void set_image_jpeg_recompress_quality(int64 x) {
01689     set_option(x, &image_jpeg_recompress_quality_);
01690   }
01691 
01692   int64 image_jpeg_recompress_quality_for_small_screens() const {
01693     return image_jpeg_recompress_quality_for_small_screens_.value();
01694   }
01695   void set_image_jpeg_recompress_quality_for_small_screens(int64 x) {
01696     set_option(x, &image_jpeg_recompress_quality_for_small_screens_);
01697   }
01698 
01699   int64 image_recompress_quality() const {
01700     return image_recompress_quality_.value();
01701   }
01702   void set_image_recompress_quality(int64 x) {
01703     set_option(x, &image_recompress_quality_);
01704   }
01705 
01706   int image_limit_optimized_percent() const {
01707     return image_limit_optimized_percent_.value();
01708   }
01709   void set_image_limit_optimized_percent(int x) {
01710     set_option(x, &image_limit_optimized_percent_);
01711   }
01712   int image_limit_resize_area_percent() const {
01713     return image_limit_resize_area_percent_.value();
01714   }
01715   void set_image_limit_resize_area_percent(int x) {
01716     set_option(x, &image_limit_resize_area_percent_);
01717   }
01718 
01719   int64 image_jpeg_num_progressive_scans() const {
01720     return image_jpeg_num_progressive_scans_.value();
01721   }
01722   void set_image_jpeg_num_progressive_scans(int64 x) {
01723     set_option(x, &image_jpeg_num_progressive_scans_);
01724   }
01725 
01726   int64 image_jpeg_num_progressive_scans_for_small_screens() const {
01727     return image_jpeg_num_progressive_scans_for_small_screens_.value();
01728   }
01729   void set_image_jpeg_num_progressive_scans_for_small_screens(int64 x) {
01730     set_option(x, &image_jpeg_num_progressive_scans_for_small_screens_);
01731   }
01732 
01733   int64 image_webp_recompress_quality() const {
01734     return image_webp_recompress_quality_.value();
01735   }
01736   void set_image_webp_recompress_quality(int64 x) {
01737     set_option(x, &image_webp_recompress_quality_);
01738   }
01739 
01740   int64 image_webp_recompress_quality_for_small_screens() const {
01741     return image_webp_recompress_quality_for_small_screens_.value();
01742   }
01743   void set_image_webp_recompress_quality_for_small_screens(int64 x) {
01744     set_option(x, &image_webp_recompress_quality_for_small_screens_);
01745   }
01746   int64 image_webp_timeout_ms() const {
01747     return image_webp_timeout_ms_.value();
01748   }
01749   void set_image_webp_timeout_ms(int64 x) {
01750     set_option(x, &image_webp_timeout_ms_);
01751   }
01752 
01753   bool domain_rewrite_hyperlinks() const {
01754     return domain_rewrite_hyperlinks_.value();
01755   }
01756   void set_domain_rewrite_hyperlinks(bool x) {
01757     set_option(x, &domain_rewrite_hyperlinks_);
01758   }
01759 
01760   bool client_domain_rewrite() const {
01761     return client_domain_rewrite_.value();
01762   }
01763   void set_client_domain_rewrite(bool x) {
01764     set_option(x, &client_domain_rewrite_);
01765   }
01766 
01767   void set_flush_more_resources_early_if_time_permits(bool x) {
01768     set_option(x, &flush_more_resources_early_if_time_permits_);
01769   }
01770   bool flush_more_resources_early_if_time_permits() const {
01771     return flush_more_resources_early_if_time_permits_.value();
01772   }
01773 
01774   void set_flush_more_resources_in_ie_and_firefox(bool x) {
01775     set_option(x, &flush_more_resources_in_ie_and_firefox_);
01776   }
01777   bool flush_more_resources_in_ie_and_firefox() const {
01778     return flush_more_resources_in_ie_and_firefox_.value();
01779   }
01780 
01781   void set_enable_defer_js_experimental(bool x) {
01782     set_option(x, &enable_defer_js_experimental_);
01783   }
01784   bool enable_defer_js_experimental() const {
01785     return enable_defer_js_experimental_.value();
01786   }
01787 
01788   void set_enable_cache_purge(bool x) {
01789     set_option(x, &enable_cache_purge_);
01790   }
01791   bool enable_cache_purge() const {
01792     return enable_cache_purge_.value();
01793   }
01794 
01795   void set_lazyload_highres_images(bool x) {
01796     set_option(x, &lazyload_highres_images_);
01797   }
01798   bool lazyload_highres_images() const {
01799     return lazyload_highres_images_.value();
01800   }
01801 
01802   void set_enable_blink_debug_dashboard(bool x) {
01803     set_option(x, &enable_blink_debug_dashboard_);
01804   }
01805   bool enable_blink_debug_dashboard() const {
01806     return enable_blink_debug_dashboard_.value();
01807   }
01808 
01809   void set_enable_blink_html_change_detection(bool x) {
01810     set_option(x, &enable_blink_html_change_detection_);
01811   }
01812   bool enable_blink_html_change_detection() const {
01813     return enable_blink_html_change_detection_.value();
01814   }
01815 
01816   void set_enable_blink_html_change_detection_logging(bool x) {
01817     set_option(x, &enable_blink_html_change_detection_logging_);
01818   }
01819   bool enable_blink_html_change_detection_logging() const {
01820     return enable_blink_html_change_detection_logging_.value();
01821   }
01822 
01823   void set_use_smart_diff_in_blink(bool x) {
01824     set_option(x, &use_smart_diff_in_blink_);
01825   }
01826   bool use_smart_diff_in_blink() const {
01827     return use_smart_diff_in_blink_.value();
01828   }
01829 
01830   void set_use_fallback_property_cache_values(bool x) {
01831     set_option(x, &use_fallback_property_cache_values_);
01832   }
01833   bool use_fallback_property_cache_values() const {
01834     return use_fallback_property_cache_values_.value();
01835   }
01836 
01837   void set_enable_lazyload_in_blink(bool x) {
01838     set_option(x, &enable_lazyload_in_blink_);
01839   }
01840   bool enable_lazyload_in_blink() const {
01841     return enable_lazyload_in_blink_.value();
01842   }
01843 
01844   void set_enable_prioritizing_scripts(bool x) {
01845     set_option(x, &enable_prioritizing_scripts_);
01846   }
01847   bool enable_prioritizing_scripts() const {
01848     return enable_prioritizing_scripts_.value();
01849   }
01850 
01851   void set_blink_html_change_detection_time_ms(int64 x) {
01852     set_option(x, &blink_html_change_detection_time_ms_);
01853   }
01854   int64 blink_html_change_detection_time_ms() const {
01855     return blink_html_change_detection_time_ms_.value();
01856   }
01857 
01858   void set_override_blink_cache_time_ms(int64 x) {
01859     set_option(x, &override_blink_cache_time_ms_);
01860   }
01861   int64 override_blink_cache_time_ms() const {
01862     return override_blink_cache_time_ms_.value();
01863   }
01864 
01865   void set_blink_non_cacheables_for_all_families(const StringPiece& p) {
01866     set_option(GoogleString(p.data(), p.size()),
01867                &blink_non_cacheables_for_all_families_);
01868   }
01869   const GoogleString& blink_non_cacheables_for_all_families() const {
01870     return blink_non_cacheables_for_all_families_.value();
01871   }
01872 
01873   const GoogleString& blocking_rewrite_key() const {
01874     return blocking_rewrite_key_.value();
01875   }
01876   void set_blocking_rewrite_key(const StringPiece& p) {
01877     set_option(p.as_string(), &blocking_rewrite_key_);
01878   }
01879 
01880   bool rewrite_uncacheable_resources() const {
01881     return rewrite_uncacheable_resources_.value();
01882   }
01883 
01884   void set_rewrite_uncacheable_resources(bool x) {
01885     set_option(x, &rewrite_uncacheable_resources_);
01886   }
01887 
01890   bool IsInBlinkCacheableFamily(const GoogleUrl& gurl) const;
01891 
01896   int64 GetBlinkCacheTimeFor(const GoogleUrl& gurl) const;
01897 
01902   GoogleString GetBlinkNonCacheableElementsFor(const GoogleUrl& gurl) const;
01903 
01905   void AddBlinkCacheableFamily(const StringPiece url_pattern,
01906                                int64 cache_time_ms,
01907                                const StringPiece non_cacheable_elements);
01908 
01909   void set_running_furious_experiment(bool x) {
01910     set_option(x, &running_furious_);
01911   }
01912   bool running_furious() const {
01913     return running_furious_.value();
01914   }
01915 
01917   void set_furious_ga_slot(int x) {
01918     set_option(x, &furious_ga_slot_);
01919   }
01920 
01921   int furious_ga_slot() const { return furious_ga_slot_.value(); }
01922 
01923   void set_report_unload_time(bool x) {
01924     set_option(x, &report_unload_time_);
01925   }
01926   bool report_unload_time() const {
01927     return report_unload_time_.value();
01928   }
01929 
01930   void set_implicit_cache_ttl_ms(int64 x) {
01931     set_option(x, &implicit_cache_ttl_ms_);
01932   }
01933   int64 implicit_cache_ttl_ms() const {
01934     return implicit_cache_ttl_ms_.value();
01935   }
01936 
01937   void set_x_header_value(const StringPiece& p) {
01938     set_option(p.as_string(), &x_header_value_);
01939   }
01940   const GoogleString& x_header_value() const {
01941     return x_header_value_.value();
01942   }
01943 
01944   void set_distributed_rewrite_servers(const StringPiece& p) {
01945       set_option(p.as_string(), &distributed_rewrite_servers_);
01946   }
01947   const GoogleString& distributed_rewrite_servers() const {
01948     return distributed_rewrite_servers_.value();
01949   }
01950 
01951   void set_distributed_rewrite_timeout_ms(const int64 x) {
01952     set_option(x, &distributed_rewrite_timeout_ms_);
01953   }
01954   int64 distributed_rewrite_timeout_ms() const {
01955     return distributed_rewrite_timeout_ms_.value();
01956   }
01957 
01958   void set_avoid_renaming_introspective_javascript(bool x) {
01959     set_option(x, &avoid_renaming_introspective_javascript_);
01960   }
01961   bool avoid_renaming_introspective_javascript() const {
01962     return avoid_renaming_introspective_javascript_.value();
01963   }
01964 
01965   void set_passthrough_blink_for_last_invalid_response_code(bool x) {
01966     set_option(x, &passthrough_blink_for_last_invalid_response_code_);
01967   }
01968   bool passthrough_blink_for_last_invalid_response_code() const {
01969     return passthrough_blink_for_last_invalid_response_code_.value();
01970   }
01971 
01972   int64 blink_max_html_size_rewritable() const {
01973     return blink_max_html_size_rewritable_.value();
01974   }
01975   void set_blink_max_html_size_rewritable(int64 x) {
01976     set_option(x, &blink_max_html_size_rewritable_);
01977   }
01978 
01979   void set_apply_blink_if_no_families(bool x) {
01980     set_option(x, &apply_blink_if_no_families_);
01981   }
01982   bool apply_blink_if_no_families() const {
01983     return apply_blink_if_no_families_.value();
01984   }
01985 
01986   void set_critical_line_config(const StringPiece& p) {
01987       set_option(GoogleString(p.data(), p.size()), &critical_line_config_);
01988   }
01989   const GoogleString& critical_line_config() const {
01990     return critical_line_config_.value();
01991   }
01992 
01993   void set_forbid_all_disabled_filters(bool x) {
01994     set_option(x, &forbid_all_disabled_filters_);
01995   }
01996   bool forbid_all_disabled_filters() const {
01997     return forbid_all_disabled_filters_.value();
01998   }
01999 
02000   bool reject_blacklisted() const { return reject_blacklisted_.value(); }
02001   void set_reject_blacklisted(bool x) {
02002     set_option(x, &reject_blacklisted_);
02003   }
02004 
02005   HttpStatus::Code reject_blacklisted_status_code() const {
02006     return static_cast<HttpStatus::Code>(
02007         reject_blacklisted_status_code_.value());
02008   }
02009   void set_reject_blacklisted_status_code(HttpStatus::Code x) {
02010     set_option(static_cast<int>(x), &reject_blacklisted_status_code_);
02011   }
02012 
02013   bool support_noscript_enabled() const {
02014     return support_noscript_enabled_.value();
02015   }
02016   void set_support_noscript_enabled(bool x) {
02017     set_option(x, &support_noscript_enabled_);
02018   }
02019 
02020   bool enable_extended_instrumentation() const {
02021     return enable_extended_instrumentation_.value();
02022   }
02023   void set_enable_extended_instrumentation(bool x) {
02024     set_option(x, &enable_extended_instrumentation_);
02025   }
02026 
02027   void set_max_combined_js_bytes(int64 x) {
02028     set_option(x, &max_combined_js_bytes_);
02029   }
02030   int64 max_combined_js_bytes() const {
02031     return max_combined_js_bytes_.value();
02032   }
02033 
02034   void set_pre_connect_url(const StringPiece& p) {
02035     set_option(GoogleString(p.data(), p.size()), &pre_connect_url_);
02036   }
02037   const GoogleString& pre_connect_url() const {
02038     return pre_connect_url_.value();
02039   }
02040   void set_property_cache_http_status_stability_threshold(int x) {
02041     set_option(x, &property_cache_http_status_stability_threshold_);
02042   }
02043   int property_cache_http_status_stability_threshold() const {
02044     return property_cache_http_status_stability_threshold_.value();
02045   }
02046 
02047   void set_max_rewrite_info_log_size(int x) {
02048     set_option(x, &max_rewrite_info_log_size_);
02049   }
02050   int max_rewrite_info_log_size() const {
02051     return max_rewrite_info_log_size_.value();
02052   }
02053 
02054   void set_enable_aggressive_rewriters_for_mobile(bool x) {
02055     set_option(x, &enable_aggressive_rewriters_for_mobile_);
02056   }
02057   bool enable_aggressive_rewriters_for_mobile() const {
02058     return enable_aggressive_rewriters_for_mobile_.value();
02059   }
02060 
02061   void set_allow_logging_urls_in_log_record(bool x) {
02062     set_option(x, &allow_logging_urls_in_log_record_);
02063   }
02064   bool allow_logging_urls_in_log_record() const {
02065     return allow_logging_urls_in_log_record_.value();
02066   }
02067 
02068   void set_non_cacheables_for_cache_partial_html(const StringPiece& p) {
02069     set_option(p.as_string(), &non_cacheables_for_cache_partial_html_);
02070   }
02071   const GoogleString& non_cacheables_for_cache_partial_html() const {
02072     return non_cacheables_for_cache_partial_html_.value();
02073   }
02074 
02075   void set_enable_fix_reflow(bool x) {
02076     set_option(x, &enable_fix_reflow_);
02077   }
02078   bool enable_fix_reflow() const {
02079     return enable_fix_reflow_.value();
02080   }
02081 
02097   virtual void Merge(const RewriteOptions& src);
02098 
02101   void Allow(const StringPiece& wildcard_pattern) {
02102     Modify();
02103     allow_resources_.Allow(wildcard_pattern);
02104   }
02105 
02108   void Disallow(const StringPiece& wildcard_pattern) {
02109     Modify();
02110     allow_resources_.Disallow(wildcard_pattern);
02111   }
02112 
02116   virtual void DisallowTroublesomeResources();
02117 
02122   virtual void DisallowResourcesForProxy();
02123 
02124   DomainLawyer* domain_lawyer() { return &domain_lawyer_; }
02125   const DomainLawyer* domain_lawyer() const { return &domain_lawyer_; }
02126 
02127   FileLoadPolicy* file_load_policy() { return &file_load_policy_; }
02128   const FileLoadPolicy* file_load_policy() const { return &file_load_policy_; }
02129 
02132   bool IsAllowed(const StringPiece& url) const {
02133     return allow_resources_.Match(url, true);
02134   }
02135 
02137   void RetainComment(const StringPiece& comment) {
02138     Modify();
02139     retain_comments_.Allow(comment);
02140   }
02141 
02145   bool IsRetainedComment(const StringPiece& comment) const {
02146     return retain_comments_.Match(comment, false);
02147   }
02148 
02150   void DisableLazyloadForClassName(const StringPiece& class_name) {
02151     Modify();
02152     lazyload_enabled_classes_.Disallow(class_name);
02153   }
02154 
02156   bool IsLazyloadEnabledForClassName(const StringPiece& class_name) const {
02157     return lazyload_enabled_classes_.Match(class_name, true);
02158   }
02159 
02160   void set_override_caching_ttl_ms(int64 x) {
02161     set_option(x, &override_caching_ttl_ms_);
02162   }
02163   int64 override_caching_ttl_ms() const {
02164     return override_caching_ttl_ms_.value();
02165   }
02166 
02169   void AddOverrideCacheTtl(const StringPiece& wildcard) {
02170     Modify();
02171     override_caching_wildcard_.Allow(wildcard);
02172   }
02173 
02175   bool IsCacheTtlOverridden(const StringPiece& url) const {
02176     return override_caching_wildcard_.Match(url, false);
02177   }
02178 
02179   void AddRejectedUrlWildcard(const GoogleString& wildcard) {
02180     AddRejectedHeaderWildcard(kRejectedRequestUrlKeyName, wildcard);
02181   }
02182 
02183   void AddRejectedHeaderWildcard(const StringPiece& header_name,
02184                                  const GoogleString& wildcard) {
02185     Modify();
02186     std::pair<FastWildcardGroupMap::iterator, bool> insert_result =
02187         rejected_request_map_.insert(std::make_pair(
02188             header_name, static_cast<FastWildcardGroup*>(NULL)));
02189 
02190     if (insert_result.second) {
02191       insert_result.first->second = new FastWildcardGroup;
02192     }
02193     insert_result.first->second->Allow(wildcard);
02194   }
02195 
02198   bool IsRequestDeclined(const GoogleString& url,
02199                          const RequestHeaders* request_headers) const;
02200 
02204   virtual RewriteOptions* Clone() const;
02205 
02207   virtual RewriteOptions* NewOptions() const;
02208 
02214   void ComputeSignature();
02215 
02220   void Freeze();
02221 
02228   void ClearSignatureWithCaution();
02229 
02232   void ClearSignatureForTesting() {
02233     ClearSignatureWithCaution();
02234   }
02235 
02237   const GoogleString& signature() const {
02245     ThreadSystem::ScopedReader lock(cache_invalidation_timestamp_.mutex());
02246     DCHECK(frozen_);
02247     DCHECK(!signature_.empty());
02248     return signature_;
02249   }
02250 
02251   virtual GoogleString OptionsToString() const;
02252   GoogleString FilterSetToString(const FilterSet& filter_set) const;
02253 
02256   virtual GoogleString ToExperimentString() const;
02257 
02261   virtual GoogleString ToExperimentDebugString() const;
02262 
02264   virtual bool NeedLowResImages() const {
02265     return Enabled(kDelayImages);
02266   }
02267 
02270   static Filter LookupFilterById(const StringPiece& filter_id);
02271 
02275   static OptionEnum LookupOptionEnumById(const StringPiece& option_id);
02276 
02278   static const char* LookupOptionEnum(OptionEnum option_enum) {
02279     return (option_enum < kEndOfOptions) ?
02280         option_enum_to_name_array_[option_enum] : NULL;
02281   }
02282 
02283   static OptionEnum LookupOption(const StringPiece& option_name);
02284 
02287   const OptionBaseVector& all_options() const {
02288     return all_options_;
02289   }
02290 
02294   bool IsEqual(const RewriteOptions& that) const;
02295 
02297   const Hasher* hasher() const { return &hasher_; }
02298 
02299   ThreadSystem* thread_system() const { return thread_system_; }
02300 
02301  protected:
02305   template<class ValueType>
02306   class Property : public PropertyBase {
02307    public:
02312     Property(ValueType default_value,
02313              const char* id,
02314              OptionEnum option_enum)
02315         : PropertyBase(id, option_enum),
02316           default_value_(default_value) {
02317     }
02318 
02319     void set_default(ValueType value) { default_value_ = value; }
02320     const ValueType& default_value() const { return default_value_; }
02321 
02322    private:
02323     ValueType default_value_;
02324 
02325     DISALLOW_COPY_AND_ASSIGN(Property);
02326   };
02327 
02342   template<class RewriteOptionsSubclass, class OptionClass>
02343   class PropertyLeaf : public Property<typename OptionClass::ValueType> {
02344    public:
02348     typedef OptionClass RewriteOptionsSubclass::*OptionOffset;
02349     typedef typename OptionClass::ValueType ValueType;
02350 
02351     PropertyLeaf(ValueType default_value,
02352                  OptionOffset offset,
02353                  const char* id,
02354                  OptionEnum option_enum)
02355         : Property<ValueType>(default_value, id, option_enum),
02356           offset_(offset) {
02357     }
02358 
02359     virtual void InitializeOption(RewriteOptions* options) const {
02360       RewriteOptionsSubclass* options_subclass =
02361           static_cast<RewriteOptionsSubclass*>(options);
02362       OptionClass& option = options_subclass->*offset_;
02363       option.set_property(this);
02364       DCHECK_NE(-1, this->index()) << "Call Property::set_index first.";
02365       options->set_option_at(this->index(), &option);
02366     }
02367 
02368    private:
02369     OptionOffset offset_;
02370 
02371     DISALLOW_COPY_AND_ASSIGN(PropertyLeaf);
02372   };
02373 
02383   template<class T> class OptionTemplateBase : public OptionBase {
02384    public:
02385     typedef T ValueType;
02386 
02387     OptionTemplateBase() : was_set_(false), property_(NULL) {}
02388 
02389     virtual bool was_set() const { return was_set_; }
02390 
02391     void set(const T& val) {
02392       was_set_ = true;
02393       value_ = val;
02394     }
02395 
02396     void set_default(const T& val) {
02397       if (!was_set_) {
02398         value_ = val;
02399       }
02400     }
02401 
02402     const T& value() const { return value_; }
02403 
02409     virtual void Merge(const OptionBase* src) {
02410       DCHECK(option_enum() == src->option_enum());
02411       MergeHelper(static_cast<const OptionTemplateBase*>(src));
02412     }
02413 
02414     void MergeHelper(const OptionTemplateBase* src) {
02417       if (src->was_set_ || !was_set_) {
02418         value_ = src->value_;
02419         was_set_ = src->was_set_;
02420       }
02421     }
02422 
02424     void set_property(const Property<T>* property) {
02425       property_ = property;
02426 
02431       value_ = property->default_value();
02432     }
02433     virtual const Property<T>* property() const { return property_; }
02434 
02443     void set_global_default(const T& val) {
02444       Property<T>* property = const_cast<Property<T>*>(property_);
02445       property->set_default(val);
02446     }
02447 
02456     void DoNotUseForSignatureComputation() {
02457       Property<T>* property = const_cast<Property<T>*>(property_);
02458       property->set_do_not_use_for_signature_computation(true);
02459     }
02460 
02461    private:
02462     bool was_set_;
02463     T value_;
02464     const Property<T>* property_;
02465 
02466     DISALLOW_COPY_AND_ASSIGN(OptionTemplateBase);
02467   };
02468 
02473   template<class T> class Option : public OptionTemplateBase<T> {
02474    public:
02475     Option() {}
02476 
02478     virtual bool SetFromString(const GoogleString& value_string) {
02479       T value;
02480       bool success = RewriteOptions::ParseFromString(value_string, &value);
02481       if (success) {
02482         this->set(value);
02483       }
02484       return success;
02485     }
02486 
02487     virtual GoogleString Signature(const Hasher* hasher) const {
02488       return RewriteOptions::OptionSignature(this->value(), hasher);
02489     }
02490 
02491     virtual GoogleString ToString() const {
02492       return RewriteOptions::ToString(this->value());
02493     }
02494 
02495    private:
02496     DISALLOW_COPY_AND_ASSIGN(Option);
02497   };
02498 
02511   class MutexedOptionInt64MergeWithMax : public Option<int64> {
02512    public:
02513     MutexedOptionInt64MergeWithMax();
02514     virtual ~MutexedOptionInt64MergeWithMax();
02515 
02520     virtual void Merge(const OptionBase* src_base);
02521 
02532     void checked_set(const int64& value) {
02533       mutex_->DCheckLocked();
02534       Option<int64>::set(value);
02535     }
02536 
02550     ThreadSystem::RWLock* mutex() const { return mutex_.get(); }
02551 
02557     void set_mutex(ThreadSystem::RWLock* lock) { mutex_.reset(lock); }
02558 
02559    private:
02560     scoped_ptr<ThreadSystem::RWLock> mutex_;
02561   };
02562 
02563  protected:
02565   template<class RewriteOptionsSubclass, class OptionClass>
02566   static PropertyBase* AddProperty(
02567       typename OptionClass::ValueType default_value,
02568       OptionClass RewriteOptionsSubclass::*offset,
02569       const char* id,
02570       OptionEnum option_enum,
02571       OptionScope scope,
02572       const char* help_text,
02573       Properties* properties) {
02574     PropertyBase* property =
02575         new PropertyLeaf<RewriteOptionsSubclass, OptionClass>(
02576             default_value, offset, id, option_enum);
02577     property->set_scope(scope);
02578     property->set_help_text(help_text);
02579     properties->push_back(property);
02580     return property;
02581   }
02582 
02596   static void MergeSubclassProperties(Properties* properties);
02597 
02599   void ForbidFiltersForPreserveUrl();
02600 
02606   void set_option_at(int index, OptionBase* option) {
02607     all_options_[index] = option;
02608   }
02609 
02613   template<class T>
02614   void set_option(const T& new_value, OptionTemplateBase<T>* option) {
02615     option->set(new_value);
02616     Modify();
02617   }
02618 
02620   void Modify();
02621 
02629   void set_default_x_header_value(const StringPiece& x_header_value) {
02630     x_header_value_.set_global_default(x_header_value.as_string());
02631   }
02632 
02635   bool SetupFuriousRewriters();
02636 
02638   virtual void SetRequiredFuriousFilters();
02639 
02643   bool InsertFuriousSpecInVector(FuriousSpec* spec);
02644 
02646   Option<BeaconUrl> beacon_url_;
02647 
02649   Option<GoogleString> x_header_value_;
02650 
02651  private:
02652   struct OptionIdCompare;
02653 
02654   static Properties* properties_; 
02655   static Properties* all_properties_; 
02656 
02657   FRIEND_TEST(RewriteOptionsTest, FuriousMergeTest);
02658 
02660   bool HasRejectedHeader(const StringPiece& header_name,
02661                          const RequestHeaders* request_headers) const;
02662 
02663   bool IsRejectedUrl(const GoogleString& url) const {
02664     return IsRejectedRequest(kRejectedRequestUrlKeyName, url);
02665   }
02666 
02667   bool IsRejectedRequest(const StringPiece& header_name,
02668                          const StringPiece& value) const {
02669     FastWildcardGroupMap::const_iterator it = rejected_request_map_.find(
02670         header_name);
02671     if (it != rejected_request_map_.end()) {
02672       return it->second->Match(value, false);
02673     }
02674     return false;
02675   }
02676 
02677 
02684   struct PrioritizeVisibleContentFamily {
02685     PrioritizeVisibleContentFamily(StringPiece url_pattern_string,
02686                                    int64 cache_time_ms_in,
02687                                    StringPiece non_cacheable_elements_in)
02688         : url_pattern(url_pattern_string),
02689           cache_time_ms(cache_time_ms_in),
02690           non_cacheable_elements(non_cacheable_elements_in.data(),
02691                                  non_cacheable_elements_in.size()) {}
02692 
02693     PrioritizeVisibleContentFamily* Clone() const {
02694       return new PrioritizeVisibleContentFamily(
02695           url_pattern.spec(), cache_time_ms, non_cacheable_elements);
02696     }
02697 
02698     GoogleString ComputeSignature() const {
02699       return StrCat(url_pattern.spec(), ";", Integer64ToString(cache_time_ms),
02700                     ";", non_cacheable_elements);
02701     }
02702 
02703     GoogleString ToString() const {
02704       return StrCat("URL pattern: ", url_pattern.spec(), ",  Cache time (ms): ",
02705                     Integer64ToString(cache_time_ms), ",  Non-cacheable: ",
02706                     non_cacheable_elements);
02707     }
02708 
02709     Wildcard url_pattern;
02710     int64 cache_time_ms;
02711     GoogleString non_cacheable_elements;
02712   };
02713 
02716   struct UrlCacheInvalidationEntry {
02717     UrlCacheInvalidationEntry(StringPiece url_pattern_in,
02718                               int64 timestamp_ms_in,
02719                               bool ignores_metadata_and_pcache_in)
02720         : url_pattern(url_pattern_in),
02721           timestamp_ms(timestamp_ms_in),
02722           ignores_metadata_and_pcache(ignores_metadata_and_pcache_in) {}
02723 
02724     UrlCacheInvalidationEntry* Clone() const {
02725       return new UrlCacheInvalidationEntry(
02726           url_pattern.spec(), timestamp_ms, ignores_metadata_and_pcache);
02727     }
02728 
02729     GoogleString ComputeSignature() const {
02730       if (ignores_metadata_and_pcache) {
02731         return "";
02732       }
02733       return StrCat(url_pattern.spec(), "@", Integer64ToString(timestamp_ms));
02734     }
02735 
02736     GoogleString ToString() const {
02737       return StrCat(
02738           url_pattern.spec(), ", ",
02739           (ignores_metadata_and_pcache ? "STRICT" : "REFERENCE"), " @ ",
02740           Integer64ToString(timestamp_ms));
02741     }
02742 
02743     Wildcard url_pattern;
02744     int64 timestamp_ms;
02745     bool ignores_metadata_and_pcache;
02746   };
02747 
02748   typedef std::vector<UrlCacheInvalidationEntry*>
02749       UrlCacheInvalidationEntryVector;
02750   typedef dense_hash_map<GoogleString, int64> UrlCacheInvalidationMap;
02751 
02765   template<class OptionClass, class RewriteOptionsSubclass>
02766   static void AddRequestProperty(typename OptionClass::ValueType default_value,
02767                                  OptionClass RewriteOptionsSubclass::*offset,
02768                                  const char* id) {
02769     AddProperty(default_value, offset, id, kEndOfOptions, kProcessScope,
02770                 NULL, properties_);
02771   }
02772 
02775   template<class RewriteOptionsSubclass, class OptionClass>
02776   static void AddBaseProperty(typename OptionClass::ValueType default_value,
02777                               OptionClass RewriteOptionsSubclass::*offset,
02778                               const char* id,
02779                               OptionEnum option_enum,
02780                               OptionScope scope,
02781                               const char* help) {
02782     AddProperty(default_value, offset, id, option_enum, scope, help,
02783                 properties_);
02784   }
02785 
02786   static void AddProperties();
02787   bool AddCommaSeparatedListToFilterSetState(
02788       const StringPiece& filters, FilterSet* set, MessageHandler* handler);
02789   static bool AddCommaSeparatedListToFilterSet(
02790       const StringPiece& filters, FilterSet* set, MessageHandler* handler);
02791   static Filter LookupFilter(const StringPiece& filter_name);
02794   void ResolveConflicts();
02797   static void InitOptionEnumToNameArray();
02799   static void InitFilterIdToEnumArray();
02800   static void InitOptionIdToEnumArray();
02803   const PrioritizeVisibleContentFamily* FindPrioritizeVisibleContentFamily(
02804       const StringPiece str) const;
02805 
02809   OptionSettingResult FormatSetOptionMessage(
02810       OptionSettingResult result, OptionEnum option_enum, StringPiece name,
02811       StringPiece value, GoogleString* msg);
02812 
02815   static GoogleString OptionSignature(bool x, const Hasher* hasher) {
02816     return x ? "T" : "F";
02817   }
02818   static GoogleString OptionSignature(int x, const Hasher* hasher) {
02819     return IntegerToString(x);
02820   }
02821   static GoogleString OptionSignature(int64 x, const Hasher* hasher) {
02822     return Integer64ToString(x);
02823   }
02824   static GoogleString OptionSignature(const GoogleString& x,
02825                                       const Hasher* hasher);
02826   static GoogleString OptionSignature(RewriteLevel x,
02827                                       const Hasher* hasher);
02828   static GoogleString OptionSignature(const BeaconUrl& beacon_url,
02829                                       const Hasher* hasher);
02830 
02833   static GoogleString ToString(bool x) {
02834     return x ? "True" : "False";
02835   }
02836   static GoogleString ToString(int x) {
02837     return IntegerToString(x);
02838   }
02839   static GoogleString ToString(int64 x) {
02840     return Integer64ToString(x);
02841   }
02842   static GoogleString ToString(const GoogleString& x) {
02843     return x;
02844   }
02845   static GoogleString ToString(RewriteLevel x);
02846   static GoogleString ToString(const BeaconUrl& beacon_url);
02847 
02850   static bool PropertyLessThanByEnum(PropertyBase* p1, PropertyBase* p2) {
02851     return p1->option_enum() < p2->option_enum();
02852   }
02853 
02855   static bool OptionEnumLessThanArg(OptionBase* option, OptionEnum arg) {
02856     return option->option_enum() < arg;
02857   }
02858 
02860   static bool CompareUrlCacheInvalidationEntry(UrlCacheInvalidationEntry* e1,
02861                                                UrlCacheInvalidationEntry* e2) {
02862     return e1->timestamp_ms < e2->timestamp_ms;
02863   }
02864 
02866   static bool FilterEnumToIdAndNameEntryLessThanById(
02867       const FilterEnumToIdAndNameEntry* e1,
02868       const FilterEnumToIdAndNameEntry* e2) {
02869     return strcmp(e1->filter_id, e2->filter_id) < 0;
02870   }
02871 
02872   bool modified_;
02873   bool frozen_;
02874   FilterSet enabled_filters_;
02875   FilterSet disabled_filters_;
02876   FilterSet forbidden_filters_;
02877 
02880   FilterIdSet distributable_filters_;
02881 
02887   Option<RewriteLevel> level_;
02888 
02891   UrlCacheInvalidationEntryVector url_cache_invalidation_entries_;
02892 
02894   UrlCacheInvalidationMap url_cache_invalidation_map_;
02895 
02896   MutexedOptionInt64MergeWithMax cache_invalidation_timestamp_;
02897   Option<int64> css_flatten_max_bytes_;
02898   Option<bool> cache_small_images_unrewritten_;
02900   Option<int64> image_resolution_limit_bytes_;
02901   Option<int64> css_image_inline_max_bytes_;
02902   Option<int64> css_inline_max_bytes_;
02903   Option<int64> css_outline_min_bytes_;
02904 
02906   Option<bool> css_preserve_urls_;
02907   Option<bool> js_preserve_urls_;
02908   Option<bool> image_preserve_urls_;
02909 
02910   Option<int64> image_inline_max_bytes_;
02911   Option<int64> js_inline_max_bytes_;
02912   Option<int64> js_outline_min_bytes_;
02913   Option<int64> progressive_jpeg_min_bytes_;
02915   Option<int64> max_html_cache_time_ms_;
02918   Option<int64> max_html_parse_bytes_;
02920   Option<int64> max_image_bytes_for_webp_in_css_;
02922   Option<int64> min_resource_cache_time_to_rewrite_ms_;
02923   Option<int64> idle_flush_time_ms_;
02924   Option<int64> flush_buffer_limit_bytes_;
02925 
02929   Option<int64> blocking_fetch_timeout_ms_;
02930 
02933   Option<int64> image_recompress_quality_;
02934 
02936   Option<int64> image_jpeg_recompress_quality_;
02937   Option<int64> image_jpeg_recompress_quality_for_small_screens_;
02938   Option<int64> image_jpeg_num_progressive_scans_;
02939   Option<int64> image_jpeg_num_progressive_scans_for_small_screens_;
02940 
02942   Option<int> image_limit_optimized_percent_;
02943   Option<int> image_limit_resize_area_percent_;
02944 
02946   Option<int64> image_webp_recompress_quality_;
02947   Option<int64> image_webp_recompress_quality_for_small_screens_;
02948   Option<int64> image_webp_timeout_ms_;
02949 
02950   Option<int> image_max_rewrites_at_once_;
02951   Option<int> max_url_segment_size_; 
02952   Option<int> max_url_size_; 
02953 
02954 
02955   Option<int> rewrite_deadline_ms_;
02957   Option<int> domain_shard_count_;
02958 
02959   Option<EnabledEnum> enabled_;
02960 
02961   Option<bool> distributable_;
02962 
02965   Option<bool> add_options_to_urls_;
02966 
02968   Option<bool> in_place_rewriting_enabled_;
02970   Option<bool> in_place_wait_for_optimized_;
02973   Option<int> in_place_rewrite_deadline_ms_;
02976   Option<bool> in_place_preemptive_rewrite_css_;
02978   Option<bool> in_place_preemptive_rewrite_css_images_;
02981   Option<bool> in_place_preemptive_rewrite_images_;
02984   Option<bool> in_place_preemptive_rewrite_javascript_;
02985   Option<bool> combine_across_paths_;
02986   Option<bool> log_background_rewrites_;
02987   Option<bool> log_rewrite_timing_; 
02988   Option<bool> log_url_indices_;
02989   Option<bool> lowercase_html_names_;
02990   Option<bool> always_rewrite_css_; 
02991   Option<bool> respect_vary_;
02992   Option<bool> respect_x_forwarded_proto_;
02993   Option<bool> flush_html_;
02996   Option<bool> serve_stale_if_fetch_error_;
02998   Option<bool> enable_blink_critical_line_;
03000   Option<bool> enable_flush_early_critical_css_;
03005   Option<bool> default_cache_html_;
03010   Option<bool> modify_caching_headers_;
03014   Option<bool> lazyload_images_after_onload_;
03017   Option<GoogleString> lazyload_images_blank_url_;
03021   Option<bool> inline_only_critical_images_;
03024   Option<bool> critical_images_beacon_enabled_;
03027   Option<bool> client_domain_rewrite_;
03030   Option<bool> domain_rewrite_hyperlinks_;
03031 
03035   Option<bool> running_furious_;
03036 
03037   Option<int> furious_ga_slot_;
03038 
03041   Option<bool> increase_speed_tracking_;
03042 
03046   Option<bool> report_unload_time_;
03047 
03049   Option<bool> flush_more_resources_early_if_time_permits_;
03050 
03052   Option<bool> flush_more_resources_in_ie_and_firefox_;
03053 
03055   Option<bool> enable_defer_js_experimental_;
03056 
03066   Option<bool> enable_cache_purge_;
03067 
03069   Option<bool> enable_inline_preview_images_experimental_;
03070 
03072   Option<bool> lazyload_highres_images_;
03073 
03076   Option<bool> avoid_renaming_introspective_javascript_;
03077 
03079   Option<bool> override_ie_document_mode_;
03080 
03082   Option<bool> test_instant_fetch_rewrite_deadline_;
03083 
03087   Option<bool> test_only_prioritize_critical_css_dont_apply_original_css_;
03088 
03094   Option<GoogleString> blocking_rewrite_key_;
03095 
03099   Option<int> beacon_reinstrument_time_sec_;
03100 
03103   Option<int> max_inlined_preview_images_index_;
03105   Option<int64> min_image_size_low_resolution_bytes_;
03107   Option<int64> max_image_size_low_resolution_bytes_;
03108 
03111   Option<bool> oblivious_pagespeed_urls_;
03112 
03114   Option<int64> finder_properties_cache_expiration_time_ms_;
03115 
03119   Option<int64> finder_properties_cache_refresh_time_ms_;
03122   Option<int64> furious_cookie_duration_ms_;
03123 
03126   Option<int64> metadata_cache_staleness_threshold_ms_;
03127 
03129   Option<int64> metadata_input_errors_cache_ttl_ms_;
03130 
03134   Option<int64> implicit_cache_ttl_ms_;
03135 
03137   Option<int64> max_cacheable_response_content_length_;
03138 
03145   std::vector<PrioritizeVisibleContentFamily*>
03146       prioritize_visible_content_families_;
03147 
03149   Option<int64> blink_blacklist_end_timestamp_ms_;
03151   Option<bool> persist_blink_blacklist_;
03152 
03153   Option<GoogleString> ga_id_;
03154 
03157   Option<bool> passthrough_blink_for_last_invalid_response_code_;
03159   Option<int64> blink_max_html_size_rewritable_;
03162   Option<int64> blink_html_change_detection_time_ms_;
03166   Option<bool> apply_blink_if_no_families_;
03168   Option<bool> enable_blink_debug_dashboard_;
03170   Option<bool> enable_blink_html_change_detection_;
03172   Option<bool> enable_blink_html_change_detection_logging_;
03174   Option<bool> use_smart_diff_in_blink_;
03176   Option<bool> use_fallback_property_cache_values_;
03178   Option<bool> enable_lazyload_in_blink_;
03180   Option<bool> enable_prioritizing_scripts_;
03182   Option<bool> rewrite_uncacheable_resources_;
03184   Option<int64> override_blink_cache_time_ms_;
03187   Option<GoogleString> blink_non_cacheables_for_all_families_;
03189   Option<GoogleString> critical_line_config_;
03191   Option<GoogleString> distributed_rewrite_servers_;
03194   Option<int64> distributed_rewrite_timeout_ms_;
03200   Option<bool> forbid_all_disabled_filters_;
03202   Option<bool> enable_aggressive_rewriters_for_mobile_;
03203 
03209   Option<bool> reject_blacklisted_;
03210   Option<int> reject_blacklisted_status_code_;
03211 
03215   Option<bool> support_noscript_enabled_;
03216 
03219   Option<bool> enable_extended_instrumentation_;
03220 
03223   Option<int64> max_combined_js_bytes_;
03224 
03226   Option<GoogleString> pre_connect_url_;
03229   Option<int> property_cache_http_status_stability_threshold_;
03231   Option<int> max_rewrite_info_log_size_;
03232 
03237   Option<int64> override_caching_ttl_ms_;
03238   FastWildcardGroup override_caching_wildcard_;
03239 
03241   Option<bool> allow_logging_urls_in_log_record_;
03242 
03244   Option<GoogleString> non_cacheables_for_cache_partial_html_;
03245 
03247   Option<bool> enable_fix_reflow_;
03248 
03252   OptionBaseVector all_options_;
03253   size_t initialized_options_; 
03254 
03256   static const char* option_enum_to_name_array_[kEndOfOptions];
03257 
03260   static const FilterEnumToIdAndNameEntry* filter_id_to_enum_array_[
03261       kEndOfFilters];
03262 
03267   static const PropertyBase** option_id_to_property_array_;
03268 
03275   bool options_uniqueness_checked_;
03276 
03278   bool need_to_store_experiment_data_;
03280   int furious_id_;
03281   int furious_percent_; 
03282   std::vector<FuriousSpec*> furious_specs_;
03283 
03285   std::vector<NameValue*> custom_fetch_headers_;
03286 
03289   scoped_ptr<std::vector<ElementAttributeCategory> > url_valued_attributes_;
03290 
03291   JavascriptLibraryIdentification javascript_library_identification_;
03292 
03293   DomainLawyer domain_lawyer_;
03294   FileLoadPolicy file_load_policy_;
03295 
03296   FastWildcardGroup allow_resources_;
03297   FastWildcardGroup retain_comments_;
03298   FastWildcardGroup lazyload_enabled_classes_;
03299 
03302   typedef std::map<StringPiece, FastWildcardGroup*> FastWildcardGroupMap;
03303   FastWildcardGroupMap rejected_request_map_;
03304 
03305   GoogleString signature_;
03306   MD5Hasher hasher_; 
03307 
03308   ThreadSystem* thread_system_;
03309 
03322   scoped_ptr<ThreadSystem::ThreadId> last_thread_id_;
03323 
03324   DISALLOW_COPY_AND_ASSIGN(RewriteOptions);
03325 };
03326 
03327 }  
03328 
03329 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines