| // Copyright 2011 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| // Author: jmarantz@google.com (Joshua Marantz) |
| |
| #ifndef NET_INSTAWEB_APACHE_APACHE_SERVER_CONTEXT_H_ |
| #define NET_INSTAWEB_APACHE_APACHE_SERVER_CONTEXT_H_ |
| |
| #include "net/instaweb/apache/apache_config.h" |
| #include "net/instaweb/http/public/request_context.h" |
| #include "net/instaweb/rewriter/public/rewrite_stats.h" |
| #include "net/instaweb/rewriter/public/server_context.h" |
| #include "net/instaweb/util/public/basictypes.h" |
| #include "net/instaweb/util/public/scoped_ptr.h" |
| #include "net/instaweb/util/public/string.h" |
| #include "net/instaweb/util/public/string_util.h" |
| |
| struct request_rec; |
| struct server_rec; |
| |
| namespace net_instaweb { |
| |
| class AbstractMutex; |
| class ApacheRewriteDriverFactory; |
| class Histogram; |
| class RewriteDriverPool; |
| class RewriteDriver; |
| class RewriteStats; |
| class SharedMemStatistics; |
| class Statistics; |
| class UrlAsyncFetcherStats; |
| class Variable; |
| |
| // Creates an Apache-specific ServerContext. This differs from base class |
| // that it incorporates by adding per-VirtualHost configuration, including: |
| // - file-cache path & limits |
| // - default RewriteOptions. |
| // Additionally, there are startup semantics for apache's prefork model |
| // that require a phased initialization. |
| class ApacheServerContext : public ServerContext { |
| public: |
| ApacheServerContext(ApacheRewriteDriverFactory* factory, |
| server_rec* server, |
| const StringPiece& version); |
| virtual ~ApacheServerContext(); |
| |
| GoogleString hostname_identifier() { return hostname_identifier_; } |
| ApacheRewriteDriverFactory* apache_factory() { return apache_factory_; } |
| ApacheConfig* config(); |
| bool InitFileCachePath(); |
| |
| // These return configuration objects that hold settings from |
| // <ModPagespeedIf spdy> and <ModPagespeedIf !spdy> sections of configuration. |
| // They initialize lazily, so are not thread-safe; however they are only |
| // meant to be used during configuration parsing. These methods should be |
| // called only if there is actually a need to put something in them, since |
| // otherwise we may end up constructing separate SPDY vs. non-SPDY |
| // configurations needlessly. |
| ApacheConfig* SpdyConfigOverlay(); |
| ApacheConfig* NonSpdyConfigOverlay(); |
| |
| // These return true if the given overlays were constructed (in response |
| // to having something in config files to put in them). |
| bool has_spdy_config_overlay() const { |
| return spdy_config_overlay_.get() != NULL; |
| } |
| |
| bool has_non_spdy_config_overlay() const { |
| return non_spdy_config_overlay_.get() != NULL; |
| } |
| |
| // These two take ownership of their parameters. |
| void set_spdy_config_overlay(ApacheConfig* x) { |
| spdy_config_overlay_.reset(x); |
| } |
| |
| void set_non_spdy_config_overlay(ApacheConfig* x) { |
| non_spdy_config_overlay_.reset(x); |
| } |
| |
| // Returns special configuration that should be used for SPDY sessions |
| // instead of config(). Returns NULL if config() should be used instead. |
| ApacheConfig* SpdyConfig() { return spdy_specific_config_.get(); } |
| |
| // Pool to pass to NewRewriteDriverFromPool to get a RewriteDriver configured |
| // with SPDY-specific options. May be NULL in case there is no spdy-specific |
| // configuration. |
| RewriteDriverPool* spdy_driver_pool() { return spdy_driver_pool_; } |
| |
| // This should be called after all configuration parsing is done to collapse |
| // configuration inside the config overlays into actual ApacheConfig objects. |
| // It will also compute signatures when done. |
| void CollapseConfigOverlaysAndComputeSignatures(); |
| |
| // Initialize this ServerContext to have its own statistics domain. |
| // Must be called after global_statistics has been created and had |
| // ::Initialize called on it. |
| void CreateLocalStatistics(Statistics* global_statistics); |
| |
| // Should be called after the child process is forked. |
| void ChildInit(); |
| |
| bool initialized() const { return initialized_; } |
| |
| // Called on notification from Apache on child exit. Returns true |
| // if this is the last ServerContext that exists. |
| bool PoolDestroyed(); |
| |
| // Poll; if we haven't checked the timestamp of |
| // $FILE_PREFIX/cache.flush in the past |
| // cache_flush_poll_interval_sec_ (default 5) seconds do so, and if |
| // the timestamp has expired then update the |
| // cache_invalidation_timestamp in global_options, thus flushing the |
| // cache. |
| // |
| // TODO(jmarantz): allow configuration of this option. |
| // TODO(jmarantz): allow a URL-based mechanism to flush cache, even if |
| // we implement it by simply writing the cache.flush file so other |
| // servers can see it. Note that using shared-memory is not a great |
| // plan because we need the cache-invalidation to persist across server |
| // restart. |
| void PollFilesystemForCacheFlush(); |
| |
| // Accumulate in a histogram the amount of time spent rewriting HTML. |
| // TODO(sligocki): Remove in favor of RewriteStats::rewrite_latency_histogram. |
| void AddHtmlRewriteTimeUs(int64 rewrite_time_us); |
| |
| static void InitStats(Statistics* statistics); |
| |
| const server_rec* server() const { return server_rec_; } |
| |
| virtual RewriteDriverPool* SelectDriverPool(bool using_spdy); |
| |
| virtual void ApplySessionFetchers(const RequestContextPtr& req, |
| RewriteDriver* driver); |
| |
| Variable* statistics_404_count(); |
| |
| // Reports an error status to the HTTP resource request, and logs |
| // the error as a Warning to the log file, and bumps a stat as |
| // needed. |
| void ReportResourceNotFound(StringPiece error_message, request_rec* request) { |
| ReportNotFoundHelper(error_message, request, |
| rewrite_stats()->resource_404_count()); |
| } |
| |
| // Reports an error status to the HTTP statistics request, and logs |
| // the error as a Warning to the log file, and bumps a stat as |
| // needed. |
| void ReportStatisticsNotFound(StringPiece error_message, |
| request_rec* request) { |
| ReportNotFoundHelper(error_message, request, statistics_404_count()); |
| } |
| |
| // Reports an error status to the HTTP slurp request, and logs |
| // the error as a Warning to the log file, and bumps a stat as |
| // needed. |
| void ReportSlurpNotFound(StringPiece error_message, request_rec* request) { |
| ReportNotFoundHelper(error_message, request, |
| rewrite_stats()->slurp_404_count()); |
| } |
| |
| private: |
| bool UpdateCacheFlushTimestampMs(int64 timestamp_ms); |
| |
| void ReportNotFoundHelper(StringPiece url, |
| request_rec* request, |
| Variable* error_count); |
| |
| ApacheRewriteDriverFactory* apache_factory_; |
| server_rec* server_rec_; |
| GoogleString version_; |
| |
| // hostname_identifier_ equals to "server_hostname:port" of Apache, |
| // it's used to distinguish the name of shared memory, |
| // so that each vhost has its own SharedCircularBuffer. |
| GoogleString hostname_identifier_; |
| |
| bool initialized_; |
| |
| // Non-NULL if we have per-vhost stats. |
| scoped_ptr<Statistics> split_statistics_; |
| |
| // May be NULL. Owned by *split_statistics_. |
| SharedMemStatistics* local_statistics_; |
| |
| // These are non-NULL if we have per-vhost stats. |
| scoped_ptr<RewriteStats> local_rewrite_stats_; |
| scoped_ptr<UrlAsyncFetcherStats> stats_fetcher_; |
| |
| // May be NULL. Constructed once we see things in config files that should |
| // be stored in these. |
| scoped_ptr<ApacheConfig> spdy_config_overlay_; |
| scoped_ptr<ApacheConfig> non_spdy_config_overlay_; |
| |
| // May be NULL if we don't have any special settings for when using SPDY. |
| scoped_ptr<ApacheConfig> spdy_specific_config_; |
| |
| // Owned by ServerContext via a call to ManageRewriteDriverPool. |
| // May be NULL if we don't have a spdy-specific configuration. |
| RewriteDriverPool* spdy_driver_pool_; |
| |
| Histogram* html_rewrite_time_us_histogram_; |
| |
| // State used to implement periodic polling of $FILE_PREFIX/cache.flush. |
| // last_cache_flush_check_sec_ is ctor-initialized to 0 so the first |
| // time we Poll we will read the file. |
| scoped_ptr<AbstractMutex> cache_flush_mutex_; |
| int64 last_cache_flush_check_sec_; // seconds since 1970 |
| |
| Variable* cache_flush_count_; |
| Variable* cache_flush_timestamp_ms_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ApacheServerContext); |
| }; |
| |
| } // namespace net_instaweb |
| |
| #endif // NET_INSTAWEB_APACHE_APACHE_SERVER_CONTEXT_H_ |