// Copyright 2010 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)
//         lsong@google.com (Libo Song)
//
// Register handlers, define configuration options and set up other things
// that mod_pagespeed needs to do to be an Apache module.

#include <unistd.h>

#include <cerrno>
#include <cstddef>
#include <map>
#include <memory>
#include <set>
#include <utility>  // for pair
#include <vector>

#include "base/logging.h"
#include "net/instaweb/public/global_constants.h"
#include "net/instaweb/public/version.h"
#include "net/instaweb/rewriter/public/process_context.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_query.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "pagespeed/apache/apache_config.h"
#include "pagespeed/apache/apache_rewrite_driver_factory.h"
#include "pagespeed/apache/apache_server_context.h"
#include "pagespeed/apache/apr_timer.h"
#include "pagespeed/apache/header_util.h"
#include "pagespeed/apache/instaweb_context.h"
#include "pagespeed/apache/instaweb_handler.h"
#include "pagespeed/apache/interface_mod_spdy.h"
#include "pagespeed/apache/mod_instaweb.h"
#include "pagespeed/apache/mod_spdy_fetcher.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/system/in_place_resource_recorder.h"
#include "pagespeed/system/loopback_route_fetcher.h"
#include "pagespeed/system/system_rewrite_options.h"
#include "pagespeed/system/system_server_context.h"

#include "util_filter.h"                                             // NOLINT
// Note: a very useful reference is this file, which demos many Apache module
// options:
//    http://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/examples/mod_example_hooks.c

// The httpd header must be after the pagepseed_server_context.h. Otherwise,
// the compiler will complain
// "strtoul_is_not_a_portable_function_use_strtol_instead".
#include "ap_release.h"                                              // NOLINT
#include "apr_pools.h"                                               // NOLINT
#include "apr_strings.h"                                             // NOLINT
#include "http_config.h"                                             // NOLINT
#include "http_protocol.h"                                           // NOLINT
#include "http_request.h"                                            // NOLINT
#include "httpd.h"                                                   // NOLINT

// This include-file is order-dependent; it must come after the above apache
// includes, and not be in abc-order with the net/instaweb/... includes.
#include "pagespeed/apache/apache_logging_includes.h"

#include "pagespeed/apache/log_message_handler.h"
#include "unixd.h"                                                 // NOLINT

#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER >= 4)
#define MPS_APACHE_24
#endif

// Apache 2.4 renames unixd_config -> ap_unixd_config
#ifdef MPS_APACHE_24
#define unixd_config ap_unixd_config
#endif

struct apr_pool_t;

namespace net_instaweb {

namespace {

// Passed to CheckGlobalOption
enum VHostHandling {
  kTolerateInVHost,
  kErrorInVHost
};

// TODO(sligocki): Separate options parsing from all the other stuff here.
// Instaweb directive names -- these must match
// install/common/pagespeed.conf.template.
// If you add a new option, please add it to the #ALL_DIRECTIVES section of
// install/debug.conf.template to make sure it will parse.

const char kModPagespeedIf[] = "<ModPagespeedIf";

const char kModPagespeedAdminDomains[] = "ModPagespeedAdminDomains";
const char kModPagespeedAllow[] = "ModPagespeedAllow";
const char kModPagespeedBlockingRewriteRefererUrls[] =
    "ModPagespeedBlockingRewriteRefererUrls";
const char kModPagespeedConsoleDomains[] = "ModPagespeedConsoleDomains";
const char kModPagespeedCreateSharedMemoryMetadataCache[] =
    "ModPagespeedCreateSharedMemoryMetadataCache";
const char kModPagespeedCustomFetchHeader[] = "ModPagespeedCustomFetchHeader";
const char kModPagespeedDisableFilters[] = "ModPagespeedDisableFilters";
const char kModPagespeedDisableForBots[] = "ModPagespeedDisableForBots";
const char kModPagespeedDisallow[] = "ModPagespeedDisallow";
const char kModPagespeedDomain[] = "ModPagespeedDomain";
const char kModPagespeedDownstreamCachePurgeLocationPrefix[] =
    "ModPagespeedDownstreamCachePurgeLocationPrefix";
const char kModPagespeedEnableFilters[] = "ModPagespeedEnableFilters";
const char kModPagespeedFetchProxy[] = "ModPagespeedFetchProxy";
const char kModPagespeedFetcherTimeoutMs[] = "ModPagespeedFetcherTimeOutMs";
const char kModPagespeedFileCachePath[] = "ModPagespeedFileCachePath";
const char kModPagespeedForbidFilters[] = "ModPagespeedForbidFilters";
const char kModPagespeedForceCaching[] = "ModPagespeedForceCaching";
const char kModPagespeedExperimentVariable[] = "ModPagespeedExperimentVariable";
const char kModPagespeedExperimentSpec[] = "ModPagespeedExperimentSpec";
const char kModPagespeedGeneratedFilePrefix[] =
    "ModPagespeedGeneratedFilePrefix";
const char kModPagespeedGlobalAdminDomains[] = "ModPagespeedGlobalAdminDomains";
const char kModPagespeedGlobalStatisticsDomains[] =
    "ModPagespeedGlobalStatisticsDomains";
const char kModPagespeedImageInlineMaxBytes[] =
    "ModPagespeedImageInlineMaxBytes";
const char kModPagespeedImageMaxRewritesAtOnce[] =
    "ModPagespeedImageMaxRewritesAtOnce";
const char kModPagespeedInheritVHostConfig[] = "ModPagespeedInheritVHostConfig";
const char kModPagespeedInstallCrashHandler[] =
    "ModPagespeedInstallCrashHandler";
const char kModPagespeedLibrary[] = "ModPagespeedLibrary";
const char kModPagespeedListOutstandingUrlsOnError[] =
    "ModPagespeedListOutstandingUrlsOnError";
const char kModPagespeedLoadFromFile[] = "ModPagespeedLoadFromFile";
const char kModPagespeedLoadFromFileMatch[] = "ModPagespeedLoadFromFileMatch";
const char kModPagespeedLoadFromFileRule[] = "ModPagespeedLoadFromFileRule";
const char kModPagespeedLoadFromFileRuleMatch[] =
    "ModPagespeedLoadFromFileRuleMatch";
const char kModPagespeedLogDir[] = "ModPagespeedLogDir";
const char kModPagespeedMapOriginDomain[] = "ModPagespeedMapOriginDomain";
const char kModPagespeedMapProxyDomain[] = "ModPagespeedMapProxyDomain";
const char kModPagespeedMapRewriteDomain[] = "ModPagespeedMapRewriteDomain";
const char kModPagespeedMessageBufferSize[] = "ModPagespeedMessageBufferSize";
const char kModPagespeedMessagesDomains[] = "ModPagespeedMessagesDomains";
const char kModPagespeedNumExpensiveRewriteThreads[] =
    "ModPagespeedNumExpensiveRewriteThreads";
const char kModPagespeedNumRewriteThreads[] = "ModPagespeedNumRewriteThreads";
const char kModPagespeedNumShards[] = "ModPagespeedNumShards";
const char kModPagespeedPreserveSubresourceHints[] =
    "ModPagespeedPreserveSubresourceHints";
const char kModPagespeedProxySuffix[] = "ModPagespeedProxySuffix";
const char kModPagespeedRetainComment[] = "ModPagespeedRetainComment";
const char kModPagespeedRunExperiment[] = "ModPagespeedRunExperiment";
const char kModPagespeedShardDomain[] = "ModPagespeedShardDomain";
const char kModPagespeedSpeedTracking[] = "ModPagespeedIncreaseSpeedTracking";
const char kModPagespeedStaticAssetPrefix[] = "ModPagespeedStaticAssetPrefix";
const char kModPagespeedStatisticsDomains[] = "ModPagespeedStatisticsDomains";
const char kModPagespeedStatisticsLoggingFile[] =
    "ModPagespeedStatisticsLoggingFile";
const char kModPagespeedTrackOriginalContentLength[] =
    "ModPagespeedTrackOriginalContentLength";
const char kModPagespeedUrlPrefix[] = "ModPagespeedUrlPrefix";
const char kModPagespeedUrlValuedAttribute[] = "ModPagespeedUrlValuedAttribute";
const char kModPagespeedUsePerVHostStatistics[] =
    "ModPagespeedUsePerVHostStatistics";

// The following are deprecated due to spelling
const char kModPagespeedImgInlineMaxBytes[] = "ModPagespeedImgInlineMaxBytes";
const char kModPagespeedImgMaxRewritesAtOnce[] =
    "ModPagespeedImgMaxRewritesAtOnce";
const char kModPagespeedImageWebpRecompressionQuality[] =
    "ModPagespeedImageWebpRecompressionQuality";
const char kModPagespeedImageWebpRecompressionQualityForSmallScreens[] =
    "ModPagespeedImageWebpRecompressionQualityForSmallScreens";

// The following three are deprecated because we didn't finish the feature.
const char kModPagespeedCollectRefererStatistics[] =
    "ModPagespeedCollectRefererStatistics";
const char kModPagespeedHashRefererStatistics[] =
    "ModPagespeedHashRefererStatistics";
const char kModPagespeedRefererStatisticsOutputLevel[] =
    "ModPagespeedRefererStatisticsOutputLevel";

enum RewriteOperation {REWRITE, FLUSH, FINISH};

// TODO(sligocki): Move inside PSOL.
// Check if pagespeed optimization rules applicable.
bool check_pagespeed_applicable(request_rec* request,
                                const ContentType& content_type) {
  // We can't operate on Content-Ranges.
  if (apr_table_get(request->headers_out, "Content-Range") != NULL) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: header Content-Range set.");
    return false;
  }

  // Only rewrite HTML-like content.
  if (!content_type.IsHtmlLike()) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: request->content_type does "
                  "not appear to be HTML (was %s)", request->content_type);
    return false;
  }

  // mod_pagespeed often creates requests while rewriting an HTML.  These
  // requests are only intended to fetch resources (images, css, javascript) but
  // in some circumstances they can end up fetching HTML.  This HTML, if
  // rewritten, could in turn spawn more requests which could cascade into a
  // bad situation.  To mod_pagespeed, any fetched HTML is an error condition,
  // so there's no reason to rewrite it anyway.
  if (InstawebHandler::is_pagespeed_subrequest(request)) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: User-Agent appears to be "
                  "mod_pagespeed");
    return false;
  }

  return true;
}

// Create a new bucket from buf using HtmlRewriter.
// TODO(lsong): the content is copied multiple times. The buf is
// copied/processed to string output, then output is copied to new bucket.
apr_bucket* rewrite_html(InstawebContext* context, request_rec* request,
                         RewriteOperation operation, const char* buf, int len) {
  if (context == NULL) {
    LOG(DFATAL) << "Context is null";
    return NULL;
  }
  if (buf != NULL) {
    context->PopulateHeaders(request);
    context->Rewrite(buf, len);
  }
  if (operation == REWRITE) {
    return NULL;
  } else if (operation == FLUSH) {
    context->Flush();
    // If the flush happens before any rewriting, don't fallthrough and
    // replace the headers with those in the context, because they haven't
    // been populated yet so we end up with NO headers. See issue 385.
    if (context->output().empty()) {
      return NULL;
    }
  } else if (operation == FINISH) {
    context->Finish();
  }

  // Check to see if we've added in the headers already.  If not,
  // clear out the existing headers (to avoid duplication), add them,
  // and make a note of it.
  if (!context->sent_headers()) {
    ResponseHeaders* headers = context->response_headers();
    apr_table_clear(request->headers_out);
    ResponseHeadersToApacheRequest(*headers, request);
    headers->Clear();
    context->set_sent_headers(true);
  }

  const GoogleString& output = context->output();
  if (output.empty()) {
    return NULL;
  }

  // Use the rewritten content. Create in heap since output will
  // be emptied for reuse.
  apr_bucket* bucket = apr_bucket_heap_create(
      output.data(), output.size(), NULL,
      request->connection->bucket_alloc);
  context->clear();
  return bucket;
}

// Apache's pool-based cleanup is not effective on process shutdown.  To allow
// valgrind to report clean results, we must take matters into our own hands.
// We employ a statically allocated class object and rely on its destructor to
// get a reliable cleanup hook.  I am, in general, strongly opposed to this
// sort of technique, and it violates the C++ Style Guide:
//   http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
// However, it is not possible to use valgrind to track memory leaks
// in our Apache module without this approach.
//
// We also need this context hold any data needed for statistics
// collected in advance of the creation of the Statistics object, such
// as directives-parsing time.
class ApacheProcessContext {
 public:
  ApacheProcessContext() : apache_cmds_(NULL) {
    ApacheRewriteDriverFactory::Initialize();
    InstallCommands();
  }

  ~ApacheProcessContext() {
    ApacheRewriteDriverFactory::Terminate();
    delete [] apache_cmds_;
    log_message_handler::ShutDown();
    // We must reset the factory to NULL before ProcessContext's dtor
    // is called, which terminates the protobuf libraries.  It is unsafe
    // to free our structures after the protobuf library has been shut down.
    factory_.reset(NULL);
  }

  void InstallCommands();

  ApacheRewriteDriverFactory* factory(server_rec* server) {
    // We are not mutex-protecting the factory-creation for now as the
    // server_rec initialization loop appears to be single-threaded in
    // Apache.
    if (factory_.get() == NULL) {
      factory_.reset(new ApacheRewriteDriverFactory(
          process_context_, server, kModPagespeedVersion));
      factory_->Init();
    }
    return factory_.get();
  }

  // Checks cmd to see if it's process scope, and if so if it's used in an
  // incorrect context, returning an error message if so.
  const char* CheckProcessScope(const cmd_parms* cmd, bool* is_process_scope);

  scoped_ptr<ApacheRewriteDriverFactory> factory_;
  // Process-scoped static variable cleanups, mainly for valgrind.
  ProcessContext process_context_;
  command_rec* apache_cmds_;

  typedef std::map<const command_rec*, VHostHandling> VhostCommandHandlingMap;
  VhostCommandHandlingMap vhost_command_handling_map_;
  StringVector cmd_names_;
};
ApacheProcessContext apache_process_context;

typedef void (ApacheServerContext::*AddTimeFn)(int64 delta);

class ScopedTimer {
 public:
  ScopedTimer(ApacheServerContext* server_context, AddTimeFn add_time_fn)
      : server_context_(server_context),
        add_time_fn_(add_time_fn),
        start_time_us_(timer_.NowUs()) {
  }

  ~ScopedTimer() {
    int64 delta_us = timer_.NowUs() - start_time_us_;
    (server_context_->*add_time_fn_)(delta_us);
  }

 private:
  ApacheServerContext* server_context_;
  AddTimeFn add_time_fn_;
  AprTimer timer_;
  int64 start_time_us_;
};

// Builds a new context for an HTML request, returning NULL if we decide
// that we should not handle the request for various reasons.
// TODO(sligocki): Move most of these checks into non-Apache specific code.
InstawebContext* build_context_for_request(request_rec* request) {
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(request->server);
  // Escape ASAP if we're in unplugged mode.
  if (server_context->global_config()->unplugged()) {
    return NULL;
  }

  if (request->unparsed_uri == NULL) {
    // TODO(jmarantz): consider adding Debug message if unparsed_uri is NULL,
    // possibly of request->the_request which was non-null in the case where
    // I found this in the debugger.
    ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, request,
                  "Request not rewritten because: "
                  "request->unparsed_uri == NULL");
    return NULL;
  }

  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                "ModPagespeed OutputFilter called for request %s",
                request->unparsed_uri);

  // Requests with a non-NULL main pointer are internal requests created by
  // apache (or other modules in apache).  We don't need to process them.
  // E.g. An included header file will be processed as a separate request.
  // mod_pagespeed needs to process only the "completed" page with the header
  // inlined, not the separate header request.
  // See http://httpd.apache.org/dev/apidoc/apidoc_request_rec.html for
  // request documentation.
  if (request->main != NULL) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: request->main != NULL");
    return NULL;
  }

  // TODO(sligocki): Should we rewrite any other statuses?
  // Maybe 206 Partial Content?
  // TODO(sligocki): Make this decision inside PSOL.
  if (request->status != 200) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: request->status != 200 "
                  "(was %d)", request->status);
    return NULL;
  }

  const ContentType* content_type =
      MimeTypeToContentType(request->content_type);
  // TODO(sligocki): Move inside PSOL.
  if (content_type == NULL) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: request->content_type was "
                  "not a recognized type (was %s)", request->content_type);
    return NULL;
  }

  // Check if pagespeed optimization is applicable.
  // TODO(sligocki): Put other checks in this function.
  if (!check_pagespeed_applicable(request, *content_type)) {
    return NULL;
  }

  // Check if mod_instaweb has already rewritten the HTML.  If the server is
  // setup as both the original and the proxy server, mod_pagespeed filter may
  // be applied twice. To avoid this, skip the content if it is already
  // optimized by mod_pagespeed.
  // TODO(sligocki): Move inside PSOL.
  if (apr_table_get(request->headers_out, kModPagespeedHeader) != NULL) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: X-Mod-Pagespeed header set.");
    return NULL;
  }

  InstawebHandler instaweb_handler(request);
  const RewriteOptions* options = instaweb_handler.options();
  instaweb_handler.SetupSpdyConnectionIfNeeded();

  const GoogleUrl& stripped_gurl = instaweb_handler.stripped_gurl();
  if (!stripped_gurl.IsWebValid()) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: invalid URL %s.",
                  stripped_gurl.spec_c_str());
    return NULL;
  }

  // TODO(sligocki): Move inside PSOL.
  // Is PageSpeed turned off? We check after parsing query params so that
  // they can override .conf settings.
  if (!options->enabled()) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: PageSpeed is off");
    return NULL;
  }

  GoogleString final_url;
  stripped_gurl.Spec().CopyToString(&final_url);

  // TODO(sligocki): Move inside PSOL.
  // Do Disallow statements restrict us from rewriting this URL?
  if (!options->IsAllowed(final_url)) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: ModPagespeedDisallow");
    return NULL;
  }

  instaweb_handler.RemoveStrippedResponseHeadersFromApacheRequest();
  ServerContext::ScanSplitHtmlRequest(instaweb_handler.request_context(),
                                      options, &final_url);

  InstawebContext* context = new InstawebContext(
      request,
      instaweb_handler.ReleaseRequestHeaders(),
      *content_type, server_context,
      final_url, instaweb_handler.request_context(),
      instaweb_handler.pagespeed_query_params(),
      instaweb_handler.pagespeed_option_cookies(),
      instaweb_handler.use_custom_options(),
      *options);

  // TODO(sligocki): Move inside PSOL.
  InstawebContext::ContentEncoding encoding = context->content_encoding();
  if ((encoding == InstawebContext::kGzip) ||
      (encoding == InstawebContext::kDeflate)) {
    // Unset the content encoding because the InstawebContext will decode the
    // content before parsing.
    apr_table_unset(request->headers_out, HttpAttributes::kContentEncoding);
    apr_table_unset(request->err_headers_out, HttpAttributes::kContentEncoding);
  } else if (encoding == InstawebContext::kOther) {
    // We don't know the encoding, so we cannot rewrite the HTML.
    const char* encoding = apr_table_get(request->headers_out,
                                         HttpAttributes::kContentEncoding);
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                  "Request not rewritten because: Content-Encoding is "
                  "unsupported (was %s)", encoding);
    return NULL;
  }

  // Set X-Mod-Pagespeed header.
  // TODO(sligocki): Move inside PSOL.
  apr_table_set(request->headers_out,
                kModPagespeedHeader, options->x_header_value().c_str());

  apr_table_unset(request->headers_out, HttpAttributes::kContentLength);
  apr_table_unset(request->headers_out, "Content-MD5");
  apr_table_unset(request->headers_out, HttpAttributes::kContentEncoding);

  // Make sure compression is enabled for this response.
  ap_add_output_filter("DEFLATE", NULL, request, request->connection);

  if (options->modify_caching_headers()) {
    ap_add_output_filter(kModPagespeedFixHeadersName, NULL, request,
                         request->connection);
  }

  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, request,
                "Request accepted.");
  return context;
}

// This returns 'false' if the output filter should stop its loop over
// the brigade and return an error.
bool process_bucket(ap_filter_t* filter, request_rec* request,
                    InstawebContext* context, apr_bucket* bucket,
                    apr_status_t* return_code) {
  // Remove the bucket from the old brigade. We will create new bucket or
  // reuse the bucket to insert into the new brigade.
  APR_BUCKET_REMOVE(bucket);
  *return_code = APR_SUCCESS;
  apr_bucket_brigade* context_bucket_brigade = context->bucket_brigade();
  apr_bucket* new_bucket = NULL;
  if (!APR_BUCKET_IS_METADATA(bucket)) {
    const char* buf = NULL;
    size_t bytes = 0;
    *return_code = apr_bucket_read(bucket, &buf, &bytes, APR_BLOCK_READ);
    if (*return_code == APR_SUCCESS) {
      new_bucket = rewrite_html(context, request, REWRITE, buf, bytes);
    } else {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, *return_code, request,
                    "Reading bucket failed (rcode=%d)", *return_code);
      apr_bucket_delete(bucket);
      return false;
    }
    // Processed the bucket, now delete it.
    apr_bucket_delete(bucket);
    if (new_bucket != NULL) {
      APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, new_bucket);
    }
  } else if (APR_BUCKET_IS_EOS(bucket)) {
    new_bucket = rewrite_html(context, request, FINISH, NULL, 0);
    if (new_bucket != NULL) {
      APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, new_bucket);
    }
    // Insert the EOS bucket to the new brigade.
    APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, bucket);
    // OK, we have seen the EOS. Time to pass it along down the chain.
    *return_code = ap_pass_brigade(filter->next, context_bucket_brigade);
    return false;
  } else if (APR_BUCKET_IS_FLUSH(bucket)) {
    new_bucket = rewrite_html(context, request, FLUSH, NULL, 0);
    if (new_bucket != NULL) {
      APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, new_bucket);
    }
    APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, bucket);
    // OK, Time to flush, pass it along down the chain.
    *return_code = ap_pass_brigade(filter->next, context_bucket_brigade);
    if (*return_code != APR_SUCCESS) {
      return false;
    }
  } else {
    // TODO(lsong): remove this log.
    ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, request,
                  "Unknown meta data");
    APR_BRIGADE_INSERT_TAIL(context_bucket_brigade, bucket);
  }
  return true;
}

// Entry point from Apache for streaming HTML-like content.
apr_status_t instaweb_out_filter(ap_filter_t* filter, apr_bucket_brigade* bb) {
  // Do nothing if there is nothing, and stop passing to other filters.
  if (APR_BRIGADE_EMPTY(bb)) {
    return APR_SUCCESS;
  }

  request_rec* request = filter->r;
  InstawebContext* context = static_cast<InstawebContext*>(filter->ctx);

  // Initialize per-request context structure.  Note that instaweb_out_filter
  // may get called multiple times per HTTP request, and this occurs only
  // on the first call.
  if (context == NULL) {
    context = build_context_for_request(request);
    if (context == NULL) {
      ap_remove_output_filter(filter);
      return ap_pass_brigade(filter->next, bb);
    }
    filter->ctx = context;
  }

  ApacheServerContext* server_context = context->apache_server_context();
  ScopedTimer timer(server_context, &ApacheServerContext::AddHtmlRewriteTimeUs);

  apr_status_t return_code = APR_SUCCESS;
  while (!APR_BRIGADE_EMPTY(bb)) {
    apr_bucket* bucket = APR_BRIGADE_FIRST(bb);
    if (!process_bucket(filter, request, context, bucket, &return_code)) {
      return return_code;
    }
  }

  apr_brigade_cleanup(bb);
  return return_code;
}

// This is called when mod_pagespeed rewrites HTML, so that headers related to
// caching maybe updated correctly.
//
// We expect this to run after mod_headers and mod_expires, triggered
// by the call to ap_add_output_filter(kModPagespeedFixHeadersName...)
// in build_context_for_request.
// This method is not called if users set "ModifyCachingHeaders off".
//
// This function removes any Expires, Last-Modified or Etag settings added
// by the user's .conf files.
//
// This function also replaces the Cache-Control header with a no-cache value
// if one of the following conditions are met:
// 1) Downstream caching integration is disabled.
// 2) Downstream caching is enabled, downstream cache beaconing key is
//    configured, and the value of the PS-ShouldBeacon header on the request
//    matches the configured beaconing key.
// It retains the original Cache-Control header in all other cases, which
// correspond to downstream caching integration being enabled and the page
// being served not being instrumented for beaconing.
apr_status_t instaweb_fix_headers_filter(
    ap_filter_t* filter, apr_bucket_brigade* bb) {
  request_rec* request = filter->r;

  // Escape ASAP if we're in unplugged mode.
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(request->server);
  if (server_context->global_config()->unplugged()) {
    ap_remove_output_filter(filter);
    return ap_pass_brigade(filter->next, bb);
  }

  // TODO(sligocki): Consider moving inside PSOL.  Note that this is a
  // little thornier than it looks because PSOL headers are different
  // from Apache headers and to share code easily we'd have to
  // translate.  We can do that easily but it seems like a waste of
  // CPU time since this will occur on every HTML request.  However,
  // there is hope in pagespeed/kernel/http/caching_headers.h, which
  // provides an abstracted interface to any underlying representation.
  // We could build on that pattern to do platform-independent header
  // manipulations in PSOL rather than direct calls to ResponseHeaders.
  //
  // TODO(jmarantz): merge this logic with that in
  // ResponseHeaders::CacheControlValuesToPreserve and
  // ServerContext::ApplyInputCacheControl
  DisableCachingRelatedHeaders(request);

  InstawebHandler instaweb_handler(request);
  const RewriteOptions* options = instaweb_handler.options();
  if (!options->IsDownstreamCacheIntegrationEnabled()) {
    // Downstream cache integration is not enabled. Disable original
    // Cache-Control headers.
    DisableCacheControlHeader(request);
  } else {
    // Downstream cache integration is enabled. If a rebeaconing key has been
    // configured and there is a ShouldBeacon header with the correct key,
    // disable original Cache-Control headers so that the instrumented page is
    // served out with no-cache.
    const char* should_beacon = apr_table_get(request->headers_in,
                                              kPsaShouldBeacon);
    if (options->MatchesDownstreamCacheRebeaconingKey(should_beacon)) {
      DisableCacheControlHeader(request);
    }
  }

  // TODO(sligocki): Why remove ourselves? Is it to assure that this filter
  // only looks at the first bucket in the brigade?
  ap_remove_output_filter(filter);
  return ap_pass_brigade(filter->next, bb);
}

// Entry point from Apache for recording resources for IPRO.
// Modeled loosely after ap_content_length_filter() in protocol.c.
// TODO(sligocki): Perhaps we can merge this filter with ApacheToMpsFilter().
apr_status_t instaweb_in_place_filter(ap_filter_t* filter,
                                      apr_bucket_brigade* bb) {
  // Do nothing if there is nothing, and stop passing to other filters.
  if (APR_BRIGADE_EMPTY(bb)) {
    return APR_SUCCESS;
  }

  request_rec* request = filter->r;

  // Escape ASAP if we're in unplugged mode.
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(request->server);
  if (server_context->global_config()->unplugged()) {
    ap_remove_output_filter(filter);
    return ap_pass_brigade(filter->next, bb);
  }

  // This should always be set by handle_as_in_place() in instaweb_handler.cc.
  InPlaceResourceRecorder* recorder =
      static_cast<InPlaceResourceRecorder*>(filter->ctx);
  CHECK(recorder != NULL);

  bool first = true;

  // Iterate through all buckets, saving content in the recorder and passing
  // the buckets along when there is a flush.  Abort early if we hit EOS or the
  // recorder fails.
  for (apr_bucket* bucket = APR_BRIGADE_FIRST(bb);
       !(bucket == APR_BRIGADE_SENTINEL(bb) ||
         APR_BUCKET_IS_EOS(bucket) ||
         recorder->failed());
       bucket = APR_BUCKET_NEXT(bucket)) {
    if (!APR_BUCKET_IS_METADATA(bucket)) {
      if (first) {
        first = false;
        ResponseHeaders response_headers(recorder->http_options());
        ApacheRequestToResponseHeaders(*request, &response_headers, NULL);
        recorder->ConsiderResponseHeaders(
            InPlaceResourceRecorder::kPreliminaryHeaders, &response_headers);
      }

      // Content bucket.
      const char* buf = NULL;
      size_t bytes = 0;
      // Note: Each call to apr_bucket_read() on a FILE bucket will pull in
      // some of the file into a HEAP bucket. Since we do not pass those
      // buckets to the next filter until the end of this function, we are
      // basically buffering up the entire size of the file into memory.
      //
      // Apache documentation says not to do this because of the memory issues:
      //   http://httpd.apache.org/docs/developer/output-filters.html#filtering
      // ... but since our whole point here is to load the resource into
      // memory, it seems reasonable.
      //
      // TODO(sligocki): Should we do an APR_NONBLOCK_READ? mod_content_length
      // seems to do that, but has to deal with APR_STATUS_IS_EAGAIN() and
      // splitting the brigade, etc.
      apr_status_t return_code = apr_bucket_read(bucket, &buf, &bytes,
                                                 APR_BLOCK_READ);
      if (return_code != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, return_code, request,
                      "Reading bucket failed (rcode=%d)", return_code);
        recorder->Fail();
        return return_code;
      }
      StringPiece contents(buf, bytes);
      recorder->Write(contents, recorder->handler());
    } else if (APR_BUCKET_IS_FLUSH(bucket)) {
      recorder->Flush(recorder->handler());
    }
  }
  // instaweb_in_place_check_headers_filter cleans up the recorder.
  return ap_pass_brigade(filter->next, bb);
}

// Runs after mod_headers and other filters which muck with the headers.
// We cannot run instaweb_in_place_filter after them because by then the
// content is gzipped.
// TODO(sligocki): Run as a single filter after mod_headers, etc. using
// an inflater to gunzip the file? Or storing the gzipped version in cache?
//
// The sole purpose of this filter is to pass the finalized headers to recorder.
apr_status_t instaweb_in_place_check_headers_filter(ap_filter_t* filter,
                                                    apr_bucket_brigade* bb) {
  // Do nothing if there is nothing, and stop passing to other filters.
  if (APR_BRIGADE_EMPTY(bb)) {
    return APR_SUCCESS;
  }

  request_rec* request = filter->r;
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(request->server);
  // Escape ASAP if we're in unplugged mode.
  if (server_context->global_config()->unplugged()) {
    ap_remove_output_filter(filter);
    return ap_pass_brigade(filter->next, bb);
  }

  // This should always be set by handle_as_in_place() in instaweb_handler.cc.
  InPlaceResourceRecorder* recorder =
      static_cast<InPlaceResourceRecorder*>(filter->ctx);

  // Although headers come in first bucket, we do not want to call Done
  // until last bucket comes in, so iterate to EOS bucket.
  for (apr_bucket* bucket = APR_BRIGADE_FIRST(bb);
       (recorder != NULL) && (bucket != APR_BRIGADE_SENTINEL(bb));
       bucket = APR_BUCKET_NEXT(bucket)) {
    if (APR_BUCKET_IS_EOS(bucket)) {
      ResponseHeaders response_headers(recorder->http_options());

      // Note: Since we're post-AP_FTYPE_PROTOCOL the error headers and regular
      // headers have already been merged in Apache, so no need to gather
      // the error headers here.
      ApacheRequestToResponseHeaders(*request, &response_headers, NULL);

      // Note: For some reason Apache never actually sets the Date header in
      // request->headers_out, but without it set we consider it uncacheable,
      // so we set it here.
      // TODO(sligocki): Perhaps we should stop requiring Date header to
      // consider resources cacheable?
      AprTimer timer;
      response_headers.SetDate(timer.NowMs());
      response_headers.ComputeCaching();

      // We now have the final headers.  If they don't let us cache then we'll
      // abort even though we've already buffered up the whole resource.
      InstawebHandler::AboutToBeDoneWithRecorder(request, recorder);
      // Deletes recorder
      recorder->DoneAndSetHeaders(&response_headers,
                                  !request->connection->aborted);

      // https://github.com/pagespeed/mod_pagespeed/issues/1191 identifies
      // a case where there must have been two EOS markers passed into
      // this function, either because there were two in the brigade
      // or because this filter was called twice.  To defend against
      // this, null the dead recorder pointer and the reference in filter->ctx.
      recorder = NULL;
      filter->ctx = NULL;
    }
  }

  return ap_pass_brigade(filter->next, bb);
}

void pagespeed_child_init(apr_pool_t* pool, server_rec* server_list) {
  // Create PageSpeed context used by instaweb rewrite-driver.  This is
  // per-process, so we initialize all the server's context by iterating the
  // server lists in server->next.
  bool need_init = true;
  for (server_rec* server = server_list; server != NULL;
       server = server->next) {
    ApacheServerContext* server_context =
        InstawebContext::ServerContextFromServerRec(server);
    if (!server_context->global_config()->unplugged()) {
      if (need_init) {
        ApacheRewriteDriverFactory* factory = apache_process_context.factory(
            server_list);
        factory->ChildInit();
        need_init = false;
      }
      DCHECK(server_context != NULL);
      DCHECK(server_context->initialized());
    }
  }
}

bool give_dir_apache_user_permissions(ApacheRewriteDriverFactory* factory,
                                      const GoogleString& path) {
  // (Apache will not switch from current euid if it's not root --- see
  //  http://httpd.apache.org/docs/2.2/mod/mpm_common.html#user).
  if (geteuid() != 0) {
    return true;
  }

  // .user_id, .group_id default to -1 if they haven't been parsed yet.
  if ((unixd_config.user_id == 0) ||
      (unixd_config.user_id == static_cast<uid_t>(-1)) ||
      (unixd_config.group_id == 0) ||
      (unixd_config.group_id == static_cast<gid_t>(-1))) {
    return true;
  }

  if (chown(path.c_str(), unixd_config.user_id,
            unixd_config.group_id) != 0) {
    factory->message_handler()->Message(
        kError, "Unable to set proper ownership of %s (%s)",
        path.c_str(), strerror(errno));
    return false;
  }
  return true;
}

// If we are running as root, hands over the ownership of data directories
// we made to the eventual Apache uid/gid.
bool give_apache_user_permissions(ApacheRewriteDriverFactory* factory) {
  const StringSet& created_dirs = factory->created_directories();
  bool ret = true;
  for (StringSet::iterator i = created_dirs.begin();
       i != created_dirs.end(); ++i) {
    ret &= give_dir_apache_user_permissions(factory, *i);
  }
  return ret;
}

// Create directory and make sure permissions are set correctly so that
// Apache processes can read and write from it.
const char* init_dir(ApacheServerContext* server_context,
                     apr_pool_t* pool,
                     const char* directive_name,
                     const char* path) {
  const char* ret = NULL;
  if (*path != '/') {
    ret = apr_pstrcat(pool, directive_name, " ", path,
                      " must start with a slash.", NULL);
  } else {
    if (!server_context->InitPath(path) ||
        !give_apache_user_permissions(server_context->apache_factory())) {
      ret = apr_pstrcat(pool, "Directory ", path, " could not be created "
                        "or permissions could not be set.", NULL);
    }
  }
  return ret;
}

// Hook from Apache for initialization after config is read.
// Initialize statistics, set appropriate directory permissions, etc.
int pagespeed_post_config(apr_pool_t* pool, apr_pool_t* plog, apr_pool_t* ptemp,
                          server_rec* server_list) {
  // This routine is complicated by the fact that statistics use inter-process
  // mutexes and have static data, which co-mingles poorly with this otherwise
  // re-entrant module.  The situation that gets interesting is when there are
  // multiple VirtualHosts, some of which have statistics enabled and some of
  // which don't.  We don't want the behavior to be order-dependent so we
  // do multiple passes.
  //
  // TODO(jmarantz): test VirtualHost

  ApacheRewriteDriverFactory* factory = apache_process_context.factory(
      server_list);

  std::vector<SystemServerContext*> server_contexts;
  std::set<ApacheServerContext*> server_contexts_covered;
  for (server_rec* server = server_list; server != NULL;
       server = server->next) {
    ApacheServerContext* server_context =
        InstawebContext::ServerContextFromServerRec(server);
    if (server_contexts_covered.insert(server_context).second) {
      CHECK(server_context != NULL);
      server_contexts.push_back(server_context);
    }

    // We also want propagate all the per-process options to each vhost. The
    // normal merge in merge_server_config isn't enough since that merges the
    // non-per process things from a dummy ServerContext corresponding to the
    // top-level config, not ApacheRewriteDriverFactory::default_options where
    // the process scope options go.
    //
    // We do this here rather than merge_server_config since we want to touch
    // the ServerContext corresponding to the top-level/non-<VirtualHost>
    // block, too.
    server_context->global_config()->MergeOnlyProcessScopeOptions(
        *factory->default_options());
  }

  GoogleString error_message;
  int error_index = -1;
  Statistics* global_statistics = NULL;
  factory->PostConfig(
      server_contexts, &error_message, &error_index, &global_statistics);
  if (error_index != -1) {
    ApacheServerContext* server_context =
        dynamic_cast<ApacheServerContext*>(server_contexts[error_index]);
    server_context->message_handler()->Message(
        kError,
        "mod_pagespeed is enabled. %s:"
        " defn_name=%s"
        " defn_line_number=%d"
        " server_hostname=%s"
        " port=%d",
        error_message.c_str(),
        server_context->server()->defn_name,
        server_context->server()->defn_line_number,
        server_context->server()->server_hostname,
        server_context->server()->port);
    return HTTP_INTERNAL_SERVER_ERROR;
  }

  // chown any directories we created. We may have to do it here in
  // post_config since we may not have our user/group yet during parse
  // (example: Fedora 11).
  //
  // We also have to do it during the parse, however, since if we're started
  // to /just/ check the config with -t (as opposed to doing it as a
  // preliminary for a proper startup) we won't get a post_config!
  give_apache_user_permissions(factory);

  // If no shared-mem statistics are enabled, then init using the default
  // NullStatistics.
  if (global_statistics == NULL) {
    ApacheRewriteDriverFactory::InitStats(factory->statistics());
  }

  factory->RootInit();

  return OK;
}

// Here log transaction will wait for all the asynchronous resource fetchers to
// finish.
apr_status_t pagespeed_log_transaction(request_rec* request) {
  return DECLINED;
}

// Called by Apache via hook once all modules have been loaded & configured
// to let us attach to their optional functions.
void pagespeed_fetch_optional_fns() {
  attach_mod_spdy();
}

int pagespeed_modify_request(request_rec* r) {
  // Escape ASAP if we're in unplugged mode.
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(r->server);
  if (server_context->global_config()->unplugged()) {
    return OK;
  }

  // This method is based in part on mod_remoteip.
  conn_rec* c = r->connection;

  // Detect local requests from us.
  const char* ua = apr_table_get(r->headers_in, HttpAttributes::kUserAgent);
  if (ua != NULL &&
      strstr(ua, " mod_pagespeed/" MOD_PAGESPEED_VERSION_STRING) != NULL) {
#ifdef MPS_APACHE_24
    apr_sockaddr_t* client_addr = c->client_addr;
#else
    apr_sockaddr_t* client_addr = c->remote_addr;
#endif

    if (LoopbackRouteFetcher::IsLoopbackAddr(client_addr)) {
      // Rewrite the client IP in Apache's records to 224.0.0.0, which is a
      // multicast address that should hence not be used by anyone, and at the
      // very least is clearly not 127.0.0.1.
      apr_sockaddr_t* untrusted_sockaddr = NULL;

      // This builds a sockaddr object corresponding to 224.0.0.0
      CHECK_EQ(APR_SUCCESS,
               apr_sockaddr_info_get(&untrusted_sockaddr, "224.0.0.0", APR_INET,
                                     80, 0, client_addr->pool));

      char* untrusted_ip_str = apr_pstrdup(client_addr->pool, "224.0.0.0");
#ifdef MPS_APACHE_24
      r->useragent_ip = untrusted_ip_str;
      r->useragent_addr = untrusted_sockaddr;
#else
      c->remote_ip = untrusted_ip_str;
      c->remote_addr = untrusted_sockaddr;
#endif

      // We set the remote host header to be an empty string --- Apache uses
      // that if there is an error, so it shouldn't pass through any ACLs.
      c->remote_host = apr_pstrdup(client_addr->pool, "");
    }
  }
  return OK;
}

// This function is a callback and it declares what
// other functions should be called for request
// processing and configuration requests. This
// callback function declares the Handlers for
// other events.
void mod_pagespeed_register_hooks(apr_pool_t* pool) {
  // Enable logging using pagespeed style
  log_message_handler::Install(pool);

  // Use instaweb to handle generated resources.
  ap_hook_handler(InstawebHandler::instaweb_handler, NULL, NULL,
                  APR_HOOK_FIRST - 1);

  // Try to provide more accurate IP information for requests we create.
  ap_hook_post_read_request(pagespeed_modify_request, NULL, NULL,
                            APR_HOOK_FIRST);

  // We register our output filter at (AP_FTYPE_RESOURCE + 1) so that
  // mod_pagespeed runs after mod_include.  See Issue
  // http://code.google.com/p/modpagespeed/issues/detail?id=182
  // and httpd/src/modules/filters/mod_include.c, which initializes
  // server-side-includes with ap_register_output_filter(...AP_FTYPE_RESOURCE).
  ap_register_output_filter(
      kModPagespeedFilterName, instaweb_out_filter, NULL,
      static_cast<ap_filter_type>(AP_FTYPE_RESOURCE + 1));

  // For HTML rewrites, we must apply our caching semantics later
  // in the filter-chain than mod_headers or mod_expires.  See:
  //   APACHE_DIST/src/modules/metadata/mod_headers.c:857
  //         --> mod_headers is installed at AP_FTYPE_CONTENT_SET
  //   APACHE_DIST/src/modules/metadata/mod_expires.c:554
  //         --> mod_expires is installed at AP_FTYPE_CONTENT_SET - 2
  // Thus we can override its settings by installing at +1.
  ap_register_output_filter(
      kModPagespeedFixHeadersName, instaweb_fix_headers_filter, NULL,
      static_cast<ap_filter_type>(AP_FTYPE_CONTENT_SET + 1));

  // Run after contents are set, but before mod_deflate, which runs at
  // AP_FTYPE_CONTENT_SET.
  ap_register_output_filter(
      kModPagespeedInPlaceFilterName, instaweb_in_place_filter, NULL,
      static_cast<ap_filter_type>(AP_FTYPE_CONTENT_SET - 1));
  // Run after headers are set by mod_headers, mod_expires, etc. and
  // after Content-Type has been set (which appears to be at
  // AP_FTYPE_PROTOCOL).
  ap_register_output_filter(
      kModPagespeedInPlaceCheckHeadersName,
      instaweb_in_place_check_headers_filter, NULL,
      static_cast<ap_filter_type>(AP_FTYPE_PROTOCOL + 1));

  ap_hook_post_config(pagespeed_post_config, NULL, NULL, APR_HOOK_MIDDLE);
  ap_hook_child_init(pagespeed_child_init, NULL, NULL, APR_HOOK_LAST);
  ap_hook_log_transaction(pagespeed_log_transaction, NULL, NULL, APR_HOOK_LAST);

  // mod_rewrite damages the URLs written by mod_pagespeed.  See
  // Issues 63 & 72.  To defend against this, we must either add
  // additional mod_rewrite rules to exclude pagespeed resources or
  // pre-scan for pagespeed resources before mod_rewrite runs and copy
  // the URL somewhere safe (a request->note) before mod_rewrite
  // corrupts it.  The latter is easier to deploy as it does not
  // require users editing their rewrite rules for mod_pagespeed.
  // mod_rewrite registers at APR_HOOK_FIRST.  We'd like to leave
  // space for user modules at APR_HOOK_FIRST-1, so we go to
  // APR_HOOK_FIRST - 2.
  ap_hook_translate_name(InstawebHandler::save_url_hook, NULL, NULL,
                         APR_HOOK_FIRST - 2);

  // By default, apache imposes limitations on URL segments of around
  // 256 characters that appear to correspond to filename limitations.
  // To prevent that, we hook map_to_storage for our own purposes.
  ap_hook_map_to_storage(InstawebHandler::instaweb_map_to_storage, NULL, NULL,
                         APR_HOOK_FIRST - 2);

  // Hook which will let us connect to optional functions mod_spdy
  // exports.
  ap_hook_optional_fn_retrieve(
      pagespeed_fetch_optional_fns,  // hook function to be called
      NULL,                          // predecessors
      NULL,                          // successors
      APR_HOOK_MIDDLE);              // position

  ModSpdyFetcher::Initialize();
}

apr_status_t pagespeed_child_exit(void* data) {
  ApacheServerContext* server_context = static_cast<ApacheServerContext*>(data);
  if (server_context->PoolDestroyed()) {
    // When the last server context is destroyed, it's important that we also
    // clean up the factory, so we don't end up with dangling pointers in case
    // we are not unloaded fully on a config check (e.g. on Ubuntu 11).
    apache_process_context.factory_.reset(NULL);
  }
  return APR_SUCCESS;
}

void* mod_pagespeed_create_server_config(apr_pool_t* pool, server_rec* server) {
  // Note: when statically loaded server->module_config is NULL when
  // initializing and this is called for the first time.
  ApacheServerContext* server_context =
      server->module_config == NULL
          ? NULL
          : InstawebContext::ServerContextFromServerRec(server);

  if (server_context == NULL) {
    ApacheRewriteDriverFactory* factory = apache_process_context.factory(
        server);
    server_context = factory->MakeApacheServerContext(server);
    apr_pool_cleanup_register(pool, server_context, pagespeed_child_exit,
                              apr_pool_cleanup_null);
  }
  return server_context;
}

const char kBoolHint[] = " on|off";
const char kEnabledEnumHint[] = " on|off|unplugged";
const char kInt64Hint[] = " must specify a 64-bit integer";
const char kIntHint[] = " must specify a 32-bit integer";

const char* ParseHint(bool x) { return kBoolHint; }
const char* ParseHint(int x) { return kIntHint; }
const char* ParseHint(int64 x) { return kInt64Hint; }
const char* ParseHint(RewriteOptions::EnabledEnum x) {
  return kEnabledEnumHint;
}

template<typename OptType, typename Options>
const char* ParseOption(Options* options, cmd_parms* cmd,
                            void (Options::*fn)(OptType val),
                            const char* arg) {
  const char* ret = NULL;
  OptType parsed;
  if (RewriteOptions::ParseFromString(arg, &parsed)) {
    (options->*fn)(parsed);
  } else {
    ret = apr_pstrcat(cmd->pool, cmd->directive->directive,
                      ParseHint(parsed), NULL);
  }
  return ret;
}

template<class Options>
const char* ParseIntBoundedOption(Options* options, cmd_parms* cmd,
                                  void (Options::*fn)(int val),
                                  const char* arg,
                                  int lower, int upper) {
  int val;
  const char* ret = NULL;
  if (StringToInt(arg, &val) &&
      val >= lower &&
      val <= upper) {
    (options->*fn)(val);
  } else {
    GoogleString message = StringPrintf(
        " must specify a 32-bit integer between %d and %d",
        lower, upper);
    ret = apr_pstrcat(cmd->pool, cmd->directive->directive, message.c_str(),
                      NULL);
  }
  return ret;
}

void warn_deprecated(cmd_parms* cmd, const char* remedy) {
  ap_log_error(APLOG_MARK, APLOG_WARNING, APR_SUCCESS, cmd->server,
               "%s is deprecated.  %s",
               cmd->directive->directive, remedy);
}

// Determines the Option structure into which to write a parsed directive.
// If the directive was parsed from the default pagespeed.conf file then
// we will write the information into the factory's RewriteOptions. In that
// case, it's also possible that an overlay config for SPDY should be used,
// in which case we will store it inside the directive object.
//
// However, if this was parsed from a Directory scope or .htaccess file then we
// will be using the RewriteOptions structure from a tree of ApacheConfig
// objects that is built up per-request.
//
// Returns NULL if successful, error string otherwise.
// Writes out the ApacheConfig* into *config_out.
static const char* CmdOptions(const cmd_parms* cmd, void* data,
                              ApacheConfig** config_out) {
  ApacheConfig* config = static_cast<ApacheConfig*>(data);
  if (config == NULL) {
    // See if there is an overlay config.
    if (cmd->directive->data != NULL) {
      config = static_cast<ApacheConfig*>(cmd->directive->data);
    } else {
      ApacheServerContext* server_context =
          InstawebContext::ServerContextFromServerRec(cmd->server);
      config = server_context->global_config();
    }
  } else {
    // If we're here, we are inside path-specific configuration, so we should
    // not see SPDY vs. non-SPDY distinction.
    if (cmd->directive->data != NULL) {
      *config_out = NULL;
      return "Can't use <ModPagespeedIf except at top-level or VirtualHost "
             "context";
    }
  }
  *config_out = config;
  return NULL;
}

// This should be called for global options to see if they were used properly.
// In particular, it returns an error string if a global option is inside a
// <ModPagespeedIf. It also either warns or errors out if we're using a global
// option inside a virtual host, depending on "mode".
//
// Returns NULL if successful, error string otherwise.
static char* CheckGlobalOption(const cmd_parms* cmd,
                               VHostHandling mode,
                               MessageHandler* handler) {
  if (cmd->server->is_virtual) {
    char* vhost_error = apr_pstrcat(
        cmd->pool, "Directive ", cmd->directive->directive,
        " used inside a <VirtualHost> but applies globally.",
        (mode == kTolerateInVHost ?
            " Accepting for backwards compatibility. " :
            NULL),
        NULL);
    if (mode == kErrorInVHost) {
      return vhost_error;
    } else {
      GoogleString message(vhost_error);
      handler->MessageS(kWarning, message);
    }
  }
  if (cmd->directive->data != NULL) {
    return apr_pstrcat(
        cmd->pool, "Global directive ", cmd->directive->directive,
        " invalid inside conditional.", NULL);
  }
  return NULL;
}

const char* ApacheProcessContext::CheckProcessScope(
    const cmd_parms* cmd, bool* is_process_scope) {
  VhostCommandHandlingMap::const_iterator p =
      vhost_command_handling_map_.find(cmd->cmd);
  *is_process_scope = (p != vhost_command_handling_map_.end());
  const char* ret = NULL;
  if (cmd->server->is_virtual || (cmd->directive->data != NULL)) {
    if (*is_process_scope) {
      ret = CheckGlobalOption(cmd, p->second, factory_->message_handler());
    }
  }
  return ret;
}

// Returns true if standard parsing handled the option and sets *err_msg to NULL
// if OK, and to the error string managed in cmd->pool otherwise.
bool StandardParsingHandled(
    cmd_parms* cmd, RewriteOptions::OptionSettingResult result,
    const GoogleString& msg, const char** err_msg) {
  switch (result) {
    case RewriteOptions::kOptionOk:
      *err_msg = NULL;  // No error.
      return true;
    case RewriteOptions::kOptionNameUnknown:
      // RewriteOptions didn't recognize the option, but we might do so
      // with our own code.
      return false;
    case RewriteOptions::kOptionValueInvalid:
      // The option is recognized, but the value is not. Return the error
      // message.
      *err_msg = apr_pstrdup(cmd->pool, msg.c_str());
      return true;
  }
  LOG(DFATAL) << "Should be unreachable";
  return true;
}

// Callback function that parses a single-argument directive.  This is called
// by the Apache config parser.
static const char* ParseDirective(cmd_parms* cmd, void* data, const char* arg) {
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(cmd->server);
  ApacheRewriteDriverFactory* factory = server_context->apache_factory();
  MessageHandler* handler = factory->message_handler();
  StringPiece directive(cmd->directive->directive);
  StringPiece prefix(RewriteQuery::kModPagespeed);
  const char* ret = NULL;
  ApacheConfig* config;
  ret = CmdOptions(cmd, data, &config);
  if (ret != NULL) {
    return ret;
  }

  // We have "FileCachePath" mapped in gperf, but here we do more than just
  // setting the option. This must precede the call to SetOptionFromName which
  // would catch this directive but miss the call to
  // give_apache_user_permissions.
  if (StringCaseEqual(directive, kModPagespeedFileCachePath)) {
    ret = init_dir(server_context, cmd->pool, kModPagespeedFileCachePath, arg);
    if (ret == NULL) {
      config->set_file_cache_path(arg);
    }
    return ret;
  }
  if (StringCaseEqual(directive, kModPagespeedLogDir)) {
    ret = init_dir(server_context, cmd->pool, kModPagespeedLogDir, arg);
    if (ret == NULL) {
      config->set_log_dir(arg);
    }
    return ret;
  }

  // Rename deprecated options so lookup below will succeed.
  if (StringCaseEqual(directive, kModPagespeedImgInlineMaxBytes)) {
    directive = kModPagespeedImageInlineMaxBytes;
  } else if (StringCaseEqual(directive, kModPagespeedImgMaxRewritesAtOnce)) {
    directive = kModPagespeedImageMaxRewritesAtOnce;
  }

  if (directive.starts_with(prefix)) {
    StringPiece option = directive.substr(prefix.size());
    GoogleString msg;

    bool use_global_config = false;
    // See if it's a global option, and perhaps not in place.
    ret = apache_process_context.CheckProcessScope(cmd, &use_global_config);
    if (ret != NULL) {
      return ret;
    }
    // Options that are per-process are always parsed into
    // ApacheRewriteDriverFactory::default_options(), and then propagated
    // in the post-config hook (pagespeed_post_config).
    if (use_global_config) {
      config = ApacheConfig::DynamicCast(factory->default_options());
    }

    // See whether generic RewriteOptions name handling can figure this one out.
    RewriteOptions::OptionSettingResult result =
        config->ParseAndSetOptionFromName1(option, arg, &msg, handler);
    if (result == RewriteOptions::kOptionNameUnknown) {
      // RewriteOptions didn't know; try the driver factory.
      // TODO(morlovich): It may be cleaner to not have process-scope options
      // in RewriteOptions at all, but rather something RewriteDriverFactory
      // specific, as long as we can provide a painless way of integrating it
      // in the server and parsing it (areas where the current manual approach
      // fails).
      result = factory->ParseAndSetOption1(
          option, arg,
          !cmd->server->is_virtual,  // is_process_scope
          &msg, handler);
    }
    if (StandardParsingHandled(cmd, result, msg, &ret)) {
      return ret;
    }
  }

  // Options which we handle manually.
  if (StringCaseEqual(directive, RewriteQuery::kModPagespeed)) {
    ret = ParseOption<RewriteOptions::EnabledEnum>(
        static_cast<RewriteOptions*>(config), cmd, &RewriteOptions::set_enabled,
        arg);
  } else if (StringCaseEqual(directive, kModPagespeedInheritVHostConfig)) {
    ret = CheckGlobalOption(cmd, kErrorInVHost, handler);
    if (ret == NULL) {
      ret = ParseOption<bool>(
          factory, cmd,
          &ApacheRewriteDriverFactory::set_inherit_vhost_config, arg);
    }
  } else if (StringCaseEqual(directive,
                             kModPagespeedCollectRefererStatistics) ||
             StringCaseEqual(directive, kModPagespeedDisableForBots) ||
             StringCaseEqual(directive, kModPagespeedGeneratedFilePrefix) ||
             StringCaseEqual(directive, kModPagespeedHashRefererStatistics) ||
             StringCaseEqual(directive, kModPagespeedNumShards) ||
             StringCaseEqual(directive, kModPagespeedStatisticsLoggingFile) ||
             StringCaseEqual(directive,
                             kModPagespeedRefererStatisticsOutputLevel) ||
             StringCaseEqual(directive, kModPagespeedUrlPrefix)) {
    warn_deprecated(cmd, "Please remove it from your configuration.");
  } else {
    ret = apr_pstrcat(cmd->pool, "Unknown directive ",
                      directive.as_string().c_str(), NULL);
  }

  return ret;
}

// Recursively walks the configuration we've parsed inside a
// <ModPagespeedIf> block, checking to make sure it's sane, and stashing
// pointers to the overlay ApacheConfig's we will use once Apache actually
// bothers calling our ParseDirective* methods. Returns NULL if OK, error string
// on error.
static const char* ProcessParsedScope(ApacheServerContext* server_context,
                                      ap_directive_t* root, bool for_spdy) {
  for (ap_directive_t* cur = root; cur != NULL; cur = cur->next) {
    StringPiece directive(cur->directive);
    if (!StringCaseStartsWith(directive, RewriteQuery::kModPagespeed)) {
      return "Only mod_pagespeed directives should be inside <ModPagespeedIf "
             "blocks";
    }
    if (StringCaseStartsWith(directive, kModPagespeedIf)) {
      return "Can't nest <ModPagespeedIf> blocks";
    }

    if (cur->first_child != NULL) {
      const char* kid_result = ProcessParsedScope(
          server_context, cur->first_child, for_spdy);
      if (kid_result != NULL) {
        return kid_result;
      }
    }

    // Store the appropriate config to use in the ap_directive_t's
    // module data pointer, so we can retrieve it in CmdOptions when executing
    // parsing callback for it.
    cur->data = for_spdy ?
        server_context->SpdyConfigOverlay() :
        server_context->NonSpdyConfigOverlay();
  }
  return NULL;  // All OK.
}

// Callback that parses <ModPagespeedIf>. Unlike with ParseDirective*, we're
// supposed to make a new directive tree, and return it out via *mconfig. It
// will have its directives parsed by Apache at some point later.
static const char* ParseScope(cmd_parms* cmd, ap_directive_t** mconfig,
                              const char* arg) {
  StringPiece mode(arg);
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(cmd->server);

  bool for_spdy = false;
  if (StringCaseEqual(mode, "spdy>")) {
    for_spdy = true;
  } else if (StringCaseEqual(mode, "!spdy>")) {
    for_spdy = false;
  } else {
    return "Conditional must be spdy or !spdy.";
  }

  // We need to manually check nesting since Apache's code doesn't seem to catch
  // violations for sections that parse blocks like <ModPagespeedIf>
  // (technically, commands with EXEC_ON_READ set).
  //
  // Unfortunately, ap_check_cmd_context doesn't work entirely
  // right, either, so we do our own handling inside CmdOptions as well; this is
  // kept mostly to produce a nice complaint in case someone puts
  // a <ModPagespeedIf> inside a <Limit>.
  const char* ret =
      ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE | NOT_IN_LIMIT);
  if (ret != NULL) {
    return ret;
  }

  // Recursively parse this section. This is basically copy-pasted from
  // mod_version.c in Apache sources.
  ap_directive_t* parent = NULL;
  ap_directive_t* current = NULL;

  ret = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd,
                             &current, &parent,
                             apr_pstrdup(cmd->pool, kModPagespeedIf));
  *mconfig = current;

  // Do our syntax checking and stash some ApacheConfig pointers.
  if (ret == NULL) {
    ret = ProcessParsedScope(server_context, current, for_spdy);
  }

  return ret;
}

// Callback function that parses a two-argument directive.  This is called
// by the Apache config parser.
static const char* ParseDirective2(cmd_parms* cmd, void* data,
                                   const char* arg1, const char* arg2) {
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(cmd->server);
  ApacheRewriteDriverFactory* factory = server_context->apache_factory();
  MessageHandler* handler = factory->message_handler();

  ApacheConfig* config;
  const char* ret = CmdOptions(cmd, data, &config);
  if (ret != NULL) {
    return ret;
  }

  StringPiece prefix(RewriteQuery::kModPagespeed);
  StringPiece directive = cmd->directive->directive;
  // Go through generic path first.
  if (directive.starts_with(prefix)) {
    GoogleString msg;
    StringPiece option = directive.substr(prefix.size());
    RewriteOptions::OptionSettingResult result =
        config->ParseAndSetOptionFromName2(option, arg1, arg2, &msg, handler);
    if (result == RewriteOptions::kOptionNameUnknown) {
      // RewriteOptions didn't know; try the driver factory.
      result = factory->ParseAndSetOption2(
          option, arg1, arg2,
          !cmd->server->is_virtual,  // is_process_scope
          &msg, handler);
    }
    if (StandardParsingHandled(cmd, result, msg, &ret)) {
      return ret;
    }
  }

  return "Unknown directive.";
}

// Callback function that parses a three-argument directive.  This is called
// by the Apache config parser.
static const char* ParseDirective3(
    cmd_parms* cmd, void* data,
    const char* arg1, const char* arg2, const char* arg3) {
  ApacheServerContext* server_context =
      InstawebContext::ServerContextFromServerRec(cmd->server);
  ApacheRewriteDriverFactory* factory = server_context->apache_factory();
  MessageHandler* handler = factory->message_handler();
  ApacheConfig* config;
  const char* ret = CmdOptions(cmd, data, &config);
  if (ret != NULL) {
    return ret;
  }

  StringPiece prefix(RewriteQuery::kModPagespeed);
  StringPiece directive = cmd->directive->directive;
  // Go through generic path first.
  if (directive.starts_with(prefix)) {
    GoogleString msg;
    RewriteOptions::OptionSettingResult result =
        config->ParseAndSetOptionFromName3(
            directive.substr(prefix.size()), arg1, arg2, arg3, &msg, handler);
    if (StandardParsingHandled(cmd, result, msg, &ret)) {
      return ret;
    }
  }

  return apr_pstrcat(cmd->pool, cmd->directive->directive,
                     " unknown directive.", NULL);
}

// Setting up Apache options is cumbersome for several reasons:
//
// 1. Apache appears to require the option table be entirely constructed
//    using static data.  So we cannot use helper functions to create the
//    helper table, so that we can populate it from another table.
// 2. You have to fill in the table with a function pointer with a K&R
//    C declaration that does not specify its argument types.  There appears
//    to be a type-correct union hidden behind an ifdef for
//    AP_HAVE_DESIGNATED_INITIALIZER, but that doesn't work.  It gives a
//    syntax error; its comments indicate it is there for Doxygen.
// 3. Although you have to pre-declare all the options, you need to again
//    dispatch based on the name of the options.  You could, conceivably,
//    provide a different function pointer for each call.  This might look
//    feasible with the 'mconfig' argument to AP_INIT_TAKE1, but mconfig
//    must be specified in a static initializer.  So it wouldn't be that easy
//    to, say, create a C++ object for each config parameter.
//
// Googling for AP_MODULE_DECLARE_DATA didn't shed any light on how to do this
// using a style suitable for programming after 1980.  So all we can do is make
// this a little less ugly with wrapper macros and helper functions.
//
// TODO(jmarantz): investigate usage of RSRC_CONF -- perhaps many of these
// options should be allowable inside a Directory or Location by ORing in
// ACCESS_CONF to RSRC_CONF.

#define APACHE_CONFIG_OPTION(name, help) \
  AP_INIT_TAKE1(name, reinterpret_cast<const char*(*)()>(ParseDirective), \
                NULL, RSRC_CONF, help)
#define APACHE_CONFIG_DIR_OPTION(name, help) \
  AP_INIT_TAKE1(name, reinterpret_cast<const char*(*)()>(ParseDirective), \
                NULL, OR_ALL, help)

// For stuff similar to <IfVersion>, and the like.
// Note that Apache does not seem to apply RSRC_CONF (only global/vhost)
// enforcement for these, so they require manual checking.
#define APACHE_SCOPE_OPTION(name, help) \
  AP_INIT_TAKE1(name, reinterpret_cast<const char*(*)()>(ParseScope), \
                NULL, RSRC_CONF | EXEC_ON_READ, help)

// Like APACHE_CONFIG_OPTION, but gets 2 arguments.
#define APACHE_CONFIG_OPTION2(name, help) \
  AP_INIT_TAKE2(name, reinterpret_cast<const char*(*)()>(ParseDirective2), \
                NULL, RSRC_CONF, help)
#define APACHE_CONFIG_DIR_OPTION2(name, help) \
  AP_INIT_TAKE2(name, reinterpret_cast<const char*(*)()>(ParseDirective2), \
                NULL, OR_ALL, help)

// APACHE_CONFIG_OPTION for 3 arguments
#define APACHE_CONFIG_DIR_OPTION3(name, help) \
  AP_INIT_TAKE3(name, reinterpret_cast<const char*(*)()>(ParseDirective3), \
                NULL, OR_ALL, help)

// APACHE_CONFIG_OPTION for 2 or 3 arguments
#define APACHE_CONFIG_DIR_OPTION23(name, help) \
  AP_INIT_TAKE23(name, reinterpret_cast<const char*(*)()>(ParseDirective3), \
                 NULL, OR_ALL, help)

static const command_rec mod_pagespeed_filter_cmds[] = {
  // Special conditional op.
  APACHE_SCOPE_OPTION(
      kModPagespeedIf, "Conditionally apply some mod_pagespeed options. "
      "Possible arguments: spdy, !spdy"),

  APACHE_CONFIG_DIR_OPTION(RewriteQuery::kModPagespeed, "Enable instaweb"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedAllow,
        "wildcard_spec for urls"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedDisableFilters,
        "Comma-separated list of disabled filters"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedDisallow,
        "wildcard_spec for urls"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedDisableForBots, "No longer used."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedDomain,
        "Authorize mod_pagespeed to rewrite resources in a domain."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedDownstreamCachePurgeLocationPrefix,
        "The host:port/path prefix to be used for purging requests from "
        "the downstream cache."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedEnableFilters,
        "Comma-separated list of enabled filters"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedForbidFilters,
        "Comma-separated list of forbidden filters"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedExperimentVariable,
         "Specify the custom variable slot with which to run experiments."
         "Defaults to 1."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedExperimentSpec,
         "Configuration for one side of an experiment in the form: "
         "'id= ;enabled= ;disabled= ;ga= ;percent= ...'"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedListOutstandingUrlsOnError,
        "Adds an error message into the log for every URL fetch in "
        "flight when the HTTP stack encounters a system error, e.g. "
        "Connection Refused"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedPreserveSubresourceHints,
        "Keep all original subresource hints."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedProxySuffix,
        "Sets up a proxy suffix to be used when slurping."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedRetainComment,
        "Retain HTML comments matching wildcard, even with remove_comments "
        "enabled"),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedRunExperiment,
         "Run an experiment to test the effectiveness of rewriters."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedSpeedTracking,
        "Increase the percentage of sites that have Google Analytics page "
        "speed tracking"),

  // All one parameter deprecated options.
  APACHE_CONFIG_DIR_OPTION(kModPagespeedImgInlineMaxBytes,
        "DEPRECATED, use ModPagespeedImageInlineMaxBytes."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedCollectRefererStatistics,
        "Deprecated.  Does nothing."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedHashRefererStatistics,
        "Deprecated.  Does nothing."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedRefererStatisticsOutputLevel,
        "Deprecated.  Does nothing."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedStatisticsLoggingFile,
        "Deprecated.  Does nothing."),
  APACHE_CONFIG_DIR_OPTION(kModPagespeedImageWebpRecompressionQuality,
        "Deprecated.  Use ModPagespeedWebpRecompressionQuality"),
  APACHE_CONFIG_DIR_OPTION(
        kModPagespeedImageWebpRecompressionQualityForSmallScreens,
        "Deprecated.  Use ModPagespeedWebpRecompressionQualityForSmallScreens"),

  // All one parameter options that can only be specified at the server level.
  // (Not in <Directory> blocks.)
  APACHE_CONFIG_OPTION(kModPagespeedFetcherTimeoutMs,
        "Set internal fetcher timeout in milliseconds"),
  APACHE_CONFIG_OPTION(kModPagespeedFetchProxy, "Set the fetch proxy"),
  APACHE_CONFIG_OPTION(kModPagespeedForceCaching,
        "Ignore HTTP cache headers and TTLs"),
  APACHE_CONFIG_OPTION(kModPagespeedGeneratedFilePrefix, "No longer used."),
  APACHE_CONFIG_OPTION(kModPagespeedImgMaxRewritesAtOnce,
        "DEPRECATED, use ModPagespeedImageMaxRewritesAtOnce."),
  APACHE_CONFIG_OPTION(kModPagespeedInheritVHostConfig,
        "Inherit global configuration into VHosts."),
  APACHE_CONFIG_OPTION(kModPagespeedInstallCrashHandler,
         "Try to dump backtrace on crashes. For developer use"),
  APACHE_CONFIG_OPTION(kModPagespeedMessageBufferSize,
        "Set the size of buffer used for /mod_pagespeed_message."),
  APACHE_CONFIG_OPTION(kModPagespeedNumRewriteThreads,
        "Number of threads to use for inexpensive portions of "
        "resource-rewriting. <= 0 to auto-detect"),
  APACHE_CONFIG_OPTION(kModPagespeedNumExpensiveRewriteThreads,
        "Number of threads to use for computation-intensive portions of "
        "resource-rewriting. <= 0 to auto-detect"),
  APACHE_CONFIG_OPTION(kModPagespeedNumShards, "No longer used."),
  APACHE_CONFIG_OPTION(kModPagespeedStaticAssetPrefix,
         "Where to serve static support files for pagespeed filters from."),
  APACHE_CONFIG_OPTION(kModPagespeedTrackOriginalContentLength,
        "Add X-Original-Content-Length headers to rewritten resources"),
  APACHE_CONFIG_OPTION(kModPagespeedUrlPrefix, "No longer used."),
  APACHE_CONFIG_OPTION(kModPagespeedUsePerVHostStatistics,
        "If true, keep track of statistics per VHost and not just globally"),
  APACHE_CONFIG_OPTION(kModPagespeedBlockingRewriteRefererUrls,
                       "wildcard_spec for referer urls which trigger blocking "
                       "rewrites"),

  // All two parameter options that are allowed in <Directory> blocks.
  APACHE_CONFIG_DIR_OPTION2(kModPagespeedCustomFetchHeader,
        "custom_header_name custom_header_value"),
  APACHE_CONFIG_DIR_OPTION23(kModPagespeedMapOriginDomain,
        "to_domain from_domain[,from_domain]* [host_header]"),
  APACHE_CONFIG_DIR_OPTION23(kModPagespeedMapProxyDomain,
        "proxy_domain origin_domain [to_domain]"),
  APACHE_CONFIG_DIR_OPTION2(kModPagespeedMapRewriteDomain,
        "to_domain from_domain[,from_domain]*"),
  APACHE_CONFIG_DIR_OPTION2(kModPagespeedShardDomain,
        "from_domain shard_domain1[,shard_domain2]*"),

  // All two parameter options that can only be specified at the server level.
  // (Not in <Directory> blocks.)
  APACHE_CONFIG_OPTION2(kModPagespeedCreateSharedMemoryMetadataCache,
        "name size_kb"),
  APACHE_CONFIG_OPTION2(kModPagespeedLoadFromFile,
        "url_prefix filename_prefix"),
  APACHE_CONFIG_OPTION2(kModPagespeedLoadFromFileMatch,
        "url_regexp filename_prefix"),
  APACHE_CONFIG_OPTION2(kModPagespeedLoadFromFileRule,
        "<Allow|Disallow> filename_prefix"),
  APACHE_CONFIG_OPTION2(kModPagespeedLoadFromFileRuleMatch,
        "<Allow|Disallow> filename_regexp"),
  APACHE_CONFIG_OPTION2(kModPagespeedStatisticsDomains,
        "<Allow|Disallow> domain_wildcard"),
  APACHE_CONFIG_OPTION2(kModPagespeedGlobalStatisticsDomains,
        "<Allow|Disallow> domain_wildcard"),
  APACHE_CONFIG_OPTION2(kModPagespeedMessagesDomains,
        "<Allow|Disallow> domain_wildcard"),
  APACHE_CONFIG_OPTION2(kModPagespeedConsoleDomains,
        "<Allow|Disallow> domain_wildcard"),
  APACHE_CONFIG_OPTION2(kModPagespeedAdminDomains,
        "<Allow|Disallow> domain_wildcard"),
  APACHE_CONFIG_OPTION2(kModPagespeedGlobalAdminDomains,
        "<Allow|Disallow> domain_wildcard"),

  // All three parameter options that are allowed in <Directory> blocks.
  APACHE_CONFIG_DIR_OPTION3(kModPagespeedUrlValuedAttribute,
        "Specify an additional url-valued attribute."),
  APACHE_CONFIG_DIR_OPTION3(kModPagespeedLibrary,
        "Specify size, md5, and canonical url for JavaScript library, "
        "separated by spaces.\n"
        "These values may be obtained by running:\n"
        "  js_minify --print_size_and_hash library.js\n"
        "Yielding an entry like:\n"
        "  ModPagespeedLibrary 105527 ltVVzzYxo0 "
        "//ajax.googleapis.com/ajax/libs/1.6.1.0/prototype.js"),
};  // Do not null terminate; we use arraysize for initialization.

// We use pool-based cleanup for ApacheConfigs.  This is 99% effective.
// There is at least one base config which is created with create_dir_config,
// but whose pool is never freed.  To allow clean valgrind reports, we
// must delete that config too.  So we keep a backup cleanup-set for
// configs at end-of-process, and keep that set up-to-date when the
// pool deletion does work.
apr_status_t delete_config(void* data) {
  ApacheConfig* config = static_cast<ApacheConfig*>(data);
  delete config;
  return APR_SUCCESS;
}

// Function to allow all modules to create per directory configuration
// structures.
// dir is the directory currently being processed.
// Returns the per-directory structure created.
void* create_dir_config(apr_pool_t* pool, char* dir) {
  if (dir == NULL) {
    return NULL;
  }
  ThreadSystem* thread_system =
      apache_process_context.factory_->thread_system();
  ApacheConfig* config = new ApacheConfig(dir, thread_system);
  config->SetDefaultRewriteLevel(RewriteOptions::kCoreFilters);
  apr_pool_cleanup_register(pool, config, delete_config, apr_pool_cleanup_null);
  return config;
}

// Function to allow all modules to merge the per directory configuration
// structures for two directories.
// base_conf is the directory structure created for the parent directory.
// new_conf is the directory structure currently being processed.
// This function returns the new per-directory structure created
void* merge_dir_config(apr_pool_t* pool, void* base_conf, void* new_conf) {
  ApacheConfig* dir1 = static_cast<ApacheConfig*>(base_conf);
  ApacheConfig* dir2 = static_cast<ApacheConfig*>(new_conf);

  // To make it easier to debug the merged configurations, we store
  // the name of both input configurations as the description for
  // the merged configuration.
  ApacheConfig* dir3 = new ApacheConfig(
      StrCat(
          "Combine(", dir1->description(), ", ", dir2->description(), ")"),
      dir1->thread_system());

  // Apache does not notify us when it is done adding directives to a
  // configuration, so we don't have a good opportunity to Freeze it
  // until it use used as a merge source.  We don't want to do this in
  // Merge because, for C++ cleanliness/readability, we want to let
  // Merge take a const RewrieOptions&, so we must Freeze at the call site.
  dir1->Freeze();
  dir3->Merge(*dir1);
  dir2->Freeze();
  dir3->Merge(*dir2);
  apr_pool_cleanup_register(pool, dir3, delete_config, apr_pool_cleanup_null);
  return dir3;
}

void* merge_server_config(apr_pool_t* pool, void* base_conf, void* new_conf) {
  ApacheServerContext* global_context =
      static_cast<ApacheServerContext*>(base_conf);
  ApacheServerContext* vhost_context =
      static_cast<ApacheServerContext*>(new_conf);
  if (global_context->apache_factory()->inherit_vhost_config()) {
    scoped_ptr<ApacheConfig> merged_config(
        global_context->global_config()->Clone());
    merged_config->Merge(*vhost_context->global_config());
    // Note that we don't need to do any special handling of cache paths here,
    // since it's all related to actually creating the directories + giving
    // permissions, so doing it at top-level is sufficient.
    vhost_context->reset_global_options(merged_config.release());

    // Merge the overlays, if any exist.
    if (global_context->has_spdy_config_overlay() ||
        vhost_context->has_spdy_config_overlay()) {
      scoped_ptr<ApacheConfig> new_spdy_overlay(
          global_context->SpdyConfigOverlay()->Clone());
      new_spdy_overlay->Merge(*vhost_context->SpdyConfigOverlay());
      vhost_context->set_spdy_config_overlay(new_spdy_overlay.release());
    }

    if (global_context->has_non_spdy_config_overlay() ||
        vhost_context->has_non_spdy_config_overlay()) {
      scoped_ptr<ApacheConfig> new_non_spdy_overlay(
          global_context->NonSpdyConfigOverlay()->Clone());
      new_non_spdy_overlay->Merge(*vhost_context->NonSpdyConfigOverlay());
      vhost_context->set_non_spdy_config_overlay(
          new_non_spdy_overlay.release());
    }
  }

  return new_conf;
}

}  // namespace

}  // namespace net_instaweb

extern "C" {
// Export our module so Apache is able to load us.
// See http://gcc.gnu.org/wiki/Visibility for more information.
#if defined(__linux)
#pragma GCC visibility push(default)
#endif

// Declare and populate the module's data structure.  The
// name of this structure ('pagespeed_module') is important - it
// must match the name of the module.  This structure is the
// only "glue" between the httpd core and the module.
module AP_MODULE_DECLARE_DATA pagespeed_module = {
  // Only one callback function is provided.  Real
  // modules will need to declare callback functions for
  // server/directory configuration, configuration merging
  // and other tasks.
  STANDARD20_MODULE_STUFF,
  net_instaweb::create_dir_config,
  net_instaweb::merge_dir_config,
  net_instaweb::mod_pagespeed_create_server_config,
  net_instaweb::merge_server_config,
  NULL,  // directives initialized via static ctor calling InstallCommands().
  net_instaweb::mod_pagespeed_register_hooks,
};

#if defined(__linux)
#pragma GCC visibility pop
#endif
}  // extern "C"

namespace net_instaweb {

// Runs via static construction and module-load time, so that it can
// install the Apache command-table in the module-record before Apache
// initializes the module.
void ApacheProcessContext::InstallCommands() {
  // Similar to the instantiation in ApacheConfig::AddProperties(), we
  // instantiate an ApacheConfig with a null thread system as we
  // are only using it to populate a static table which must be
  // established very early when mod_pagespeed.so is dynamically loaded,
  // to build the Apache directives parse-table before Apache attempts
  // to initialize our module.
  ApacheConfig config_template("install_commands", NULL);
  const RewriteOptions::OptionBaseVector& v = config_template.all_options();
  int num_cmds = arraysize(net_instaweb::mod_pagespeed_filter_cmds);

  // Allocate memory for all the rewrite_options, even though we
  // will only initialize the ones with non-null help.  We could
  // also do a 2-pass to count how many we will allocate.  +1 to
  // leave room for a NULL terminator.
  apache_cmds_ = new command_rec[num_cmds + v.size() + 1];
  memcpy(apache_cmds_, net_instaweb::mod_pagespeed_filter_cmds,
         num_cmds * sizeof(*apache_cmds_));
  command_rec* cmd = apache_cmds_ + num_cmds;
  cmd_names_.resize(v.size());

  for (int i = 0, n = v.size(); i < n; ++i) {
    RewriteOptions::OptionBase* option = v[i];

    // Skip entries with null documentation -- entries lacking doc
    // are an indication that the option is not available for MPS.
    if (option->help_text() != NULL) {
      // Store the fully-qualified option name in a string-array that
      // lasts until the module is destructed.
      StrAppend(&cmd_names_[i], "ModPagespeed", option->option_name());
      cmd->name = cmd_names_[i].c_str();
      cmd->func = reinterpret_cast<const char*(*)()>(ParseDirective);
      cmd->cmd_data = NULL;
      switch (option->scope()) {
        case RewriteOptions::kDirectoryScope:
        case RewriteOptions::kQueryScope:
          cmd->req_override = OR_ALL;
          break;
        case RewriteOptions::kServerScope:
          cmd->req_override = RSRC_CONF;
          break;
        case RewriteOptions::kProcessScopeStrict:
          vhost_command_handling_map_[cmd] = kErrorInVHost;
          cmd->req_override = RSRC_CONF;
          break;
        case RewriteOptions::kProcessScope:
          vhost_command_handling_map_[cmd] = kTolerateInVHost;
          cmd->req_override = RSRC_CONF;
          break;
      }
      cmd->args_how = TAKE1;
      cmd->errmsg = option->help_text();
      ++cmd;
    }
  }
  cmd->name = NULL;
  cmd->func = 0;
  cmd->cmd_data = NULL;
  cmd->req_override = 0;
  cmd->args_how = RAW_ARGS;
  cmd->errmsg = NULL;
  pagespeed_module.cmds = apache_cmds_;
}

}  // namespace net_instaweb
