trunk-tracking: update from r3924 to r3934
There aren't actually any changes required from r3924 to r3934 but the admin
work from previous versions wasn't completely ported before.
This change:
* adds support for /pagespeed_admin and /pagespeed_global_admin
* removes NgxPagespeedConsoleAsyncFetch using NgxBaseFetch instead
* adds options StatisticsPath, GlobalStatisticsPath, ConsolePath,
MessagesPath, AdminPath, and GlobalAdminPath which allow site owners to
control what path these are served under
* changes /ngx_pagespeed_statistics etc from default-on to default-off,
requiring explicit path configuration to function
* does not fix the problem where trunk-tracking fails tests on 1.5 post #653
diff --git a/src/ngx_pagespeed.cc b/src/ngx_pagespeed.cc
index 6d95354..6309ad3 100644
--- a/src/ngx_pagespeed.cc
+++ b/src/ngx_pagespeed.cc
@@ -441,8 +441,11 @@
kPagespeedDisabled,
kBeacon,
kStatistics,
+ kGlobalStatistics,
kConsole,
kMessages,
+ kAdmin,
+ kGlobalAdmin,
kPagespeedSubrequest,
kNotHeadOrGet,
kErrorResponse,
@@ -1567,16 +1570,26 @@
} else if (url.PathSansLeaf() ==
NgxRewriteDriverFactory::kStaticAssetPrefix) {
return RequestRouting::kStaticContent;
- } else if (url.PathSansQuery() == "/ngx_pagespeed_statistics" ||
- url.PathSansQuery() == "/ngx_pagespeed_global_statistics" ) {
- return RequestRouting::kStatistics;
- } else if (url.PathSansQuery() == "/pagespeed_console") {
- return RequestRouting::kConsole;
- } else if (url.PathSansQuery() == "/ngx_pagespeed_message") {
- return RequestRouting::kMessages;
}
- RewriteOptions* global_options = cfg_s->server_context->global_options();
+ NgxRewriteOptions* global_options = cfg_s->server_context->config();
+
+ StringPiece path = url.PathSansQuery();
+ if (path == global_options->statistics_path()) {
+ return RequestRouting::kStatistics;
+ } else if (path == global_options->global_statistics_path()) {
+ return RequestRouting::kGlobalStatistics;
+ } else if (path == global_options->console_path()) {
+ return RequestRouting::kConsole;
+ } else if (path == global_options->messages_path()) {
+ return RequestRouting::kMessages;
+ } else if (!global_options->admin_path().empty() &&
+ path.starts_with(global_options->admin_path())) {
+ return RequestRouting::kAdmin;
+ } else if (!global_options->global_admin_path().empty() &&
+ path.starts_with(global_options->global_admin_path())) {
+ return RequestRouting::kGlobalAdmin;
+ }
const GoogleString* beacon_url;
if (ps_is_https(r)) {
@@ -1592,7 +1605,9 @@
return RequestRouting::kResource;
}
-ngx_int_t ps_resource_handler(ngx_http_request_t* r, bool html_rewrite) {
+ngx_int_t ps_resource_handler(ngx_http_request_t* r,
+ bool html_rewrite,
+ RequestRouting::Response response_category) {
if (r != r->main) {
return NGX_DECLINED;
}
@@ -1653,6 +1668,12 @@
bool pagespeed_resource =
!html_rewrite && cfg_s->server_context->IsPagespeedResource(url);
+ bool is_an_admin_handler =
+ response_category == RequestRouting::kStatistics ||
+ response_category == RequestRouting::kGlobalStatistics ||
+ response_category == RequestRouting::kConsole ||
+ response_category == RequestRouting::kAdmin ||
+ response_category == RequestRouting::kGlobalAdmin;
if (html_rewrite) {
ps_release_base_fetch(ctx);
@@ -1678,7 +1699,7 @@
// Downstream cache integration is not enabled. Disable original
// Cache-Control headers.
ctx->preserve_caching_headers = kDontPreserveHeaders;
- } else if (!pagespeed_resource) {
+ } else if (!pagespeed_resource && !is_an_admin_handler) {
ctx->preserve_caching_headers = kPreserveOnlyCacheControl;
// Downstream cache integration is enabled. If a rebeaconing key has been
// configured and there is a ShouldBeacon header with the correct key,
@@ -1732,6 +1753,42 @@
custom_options.release() /* null if there aren't custom options */,
false /* using_spdy */, cfg_s->server_context, ctx->base_fetch);
return ps_async_wait_response(r);
+ } else if (is_an_admin_handler) {
+ QueryParams query_params;
+ query_params.Parse(url.Query());
+
+ PosixTimer timer;
+ int64 now_ms = timer.NowMs();
+ ctx->base_fetch->response_headers()->SetDateAndCaching(
+ now_ms, 0 /* max-age */, ", no-cache");
+
+ if (response_category == RequestRouting::kStatistics ||
+ response_category == RequestRouting::kGlobalStatistics) {
+ cfg_s->server_context->StatisticsPage(
+ response_category == RequestRouting::kGlobalStatistics,
+ query_params,
+ cfg_s->server_context->config(),
+ ctx->base_fetch);
+ } else if (response_category == RequestRouting::kConsole) {
+ cfg_s->server_context->ConsoleHandler(
+ *cfg_s->server_context->config(),
+ SystemServerContext::kStatistics,
+ query_params,
+ ctx->base_fetch);
+ } else if (response_category == RequestRouting::kAdmin ||
+ response_category == RequestRouting::kGlobalAdmin) {
+ cfg_s->server_context->AdminPage(
+ response_category == RequestRouting::kGlobalAdmin,
+ url,
+ query_params,
+ custom_options == NULL ? cfg_s->server_context->config()
+ : custom_options.get(),
+ ctx->base_fetch);
+ } else {
+ CHECK(false);
+ }
+
+ return ps_async_wait_response(r);
}
if (html_rewrite) {
@@ -2038,7 +2095,8 @@
return ngx_http_next_header_filter(r);
}
- ngx_int_t rc = ps_resource_handler(r, true /* html rewrite */);
+ ngx_int_t rc = ps_resource_handler(r, true /* html rewrite */,
+ RequestRouting::kResource);
if (rc != NGX_OK) {
ctx->html_rewrite = false;
return ngx_http_next_header_filter(r);
@@ -2320,27 +2378,6 @@
return ngx_http_output_filter(r, out);
}
-namespace {
-
-// TODO(jefftk): This class is a temporary shim to just support console fetch,
-// but we eventually want to convert everything in ps_simple_handler to use
-// something akin to NgxBaseFetch (which sends results direct to nginx). This
-// is work in progress (but well along) in the mod_pagespeed world.
-class NgxPagespeedConsoleAsyncFetch : public AsyncFetchUsingWriter {
- public:
- NgxPagespeedConsoleAsyncFetch(const RequestContextPtr& request_context,
- Writer* writer)
- : AsyncFetchUsingWriter(request_context, writer) { }
- virtual void HandleDone(bool status) { }
- virtual void HandleHeadersComplete() { }
-
- void FlushToNgx(const GoogleString& output, ngx_http_request_t* r) {
- send_out_headers_and_body(r, *response_headers(), output);
- }
-};
-
-} // namespace
-
ngx_int_t ps_simple_handler(ngx_http_request_t* r,
NgxServerContext* server_context,
RequestRouting::Response response_category) {
@@ -2376,34 +2413,6 @@
file_contents.CopyToString(&output);
break;
}
- case RequestRouting::kStatistics: {
- bool is_global_request =
- StringCaseStartsWith(
- request_uri_path, "/ngx_pagespeed_global_statistics");
- ps_srv_conf_t* cfg_s = ps_get_srv_config(r);
- RequestContextPtr request_context(
- cfg_s->server_context->NewRequestContext(r));
- NgxPagespeedConsoleAsyncFetch fetch(request_context, &writer);
- server_context->StatisticsPage(
- is_global_request,
- query_params,
- cfg_s->server_context->global_options(),
- &fetch);
- fetch.FlushToNgx(output, r);
- return NGX_OK;
- }
- case RequestRouting::kConsole: {
- ps_srv_conf_t* cfg_s = ps_get_srv_config(r);
- RequestContextPtr request_context(
- cfg_s->server_context->NewRequestContext(r));
- NgxPagespeedConsoleAsyncFetch fetch(request_context, &writer);
- server_context->ConsoleHandler(*server_context->config(),
- SystemServerContext::kStatistics,
- query_params,
- &fetch);
- fetch.FlushToNgx(output, r);
- return NGX_OK;
- }
case RequestRouting::kMessages: {
GoogleString log;
StringWriter log_writer(&log);
@@ -2643,12 +2652,16 @@
case RequestRouting::kBeacon:
return ps_beacon_handler(r);
case RequestRouting::kStaticContent:
- case RequestRouting::kStatistics:
- case RequestRouting::kConsole:
case RequestRouting::kMessages:
return ps_simple_handler(r, cfg_s->server_context, response_category);
+ case RequestRouting::kStatistics:
+ case RequestRouting::kGlobalStatistics:
+ case RequestRouting::kConsole:
+ case RequestRouting::kAdmin:
+ case RequestRouting::kGlobalAdmin:
case RequestRouting::kResource:
- return ps_resource_handler(r, false /* html rewrite */);
+ return ps_resource_handler(
+ r, false /* html rewrite */, response_category);
}
CHECK(0);
diff --git a/src/ngx_rewrite_options.cc b/src/ngx_rewrite_options.cc
index 1f6123e..9f44eaa 100644
--- a/src/ngx_rewrite_options.cc
+++ b/src/ngx_rewrite_options.cc
@@ -37,6 +37,13 @@
namespace {
+const char kStatisticsPath[] = "StatisticsPath";
+const char kGlobalStatisticsPath[] = "GlobalStatisticsPath";
+const char kConsolePath[] = "ConsolePath";
+const char kMessagesPath[] = "MessagesPath";
+const char kAdminPath[] = "AdminPath";
+const char kGlobalAdminPath[] = "GlobalAdminPath";
+
// These options are copied from mod_instaweb.cc, where APACHE_CONFIG_OPTIONX
// indicates that they can not be set at the directory/location level. They set
// options in the RewriteDriverFactory, so they do not appear in RewriteOptions.
@@ -92,7 +99,26 @@
}
void NgxRewriteOptions::AddProperties() {
- // Nothing ngx-specific for now.
+ // Nginx-specific options.
+ add_ngx_option(
+ "", &NgxRewriteOptions::statistics_path_, "nsp", kStatisticsPath,
+ kProcessScope, "Set the statistics path. Ex: /ngx_pagespeed_statistics");
+ add_ngx_option(
+ "", &NgxRewriteOptions::global_statistics_path_, "ngsp",
+ kGlobalStatisticsPath, kProcessScope,
+ "Set the global statistics path. Ex: /ngx_pagespeed_global_statistics");
+ add_ngx_option(
+ "", &NgxRewriteOptions::console_path_, "ncp", kConsolePath, kProcessScope,
+ "Set the console path. Ex: /pagespeed_console");
+ add_ngx_option(
+ "", &NgxRewriteOptions::messages_path_, "nmp", kMessagesPath,
+ kProcessScope, "Set the messages path. Ex: /ngx_pagespeed_message");
+ add_ngx_option(
+ "", &NgxRewriteOptions::admin_path_, "nap", kAdminPath,
+ kProcessScope, "Set the admin path. Ex: /pagespeed_admin");
+ add_ngx_option(
+ "", &NgxRewriteOptions::global_admin_path_, "ngap", kGlobalAdminPath,
+ kProcessScope, "Set the global admin path. Ex: /pagespeed_global_admin");
MergeSubclassProperties(ngx_properties_);
diff --git a/src/ngx_rewrite_options.h b/src/ngx_rewrite_options.h
index ce815d1..94061f8 100644
--- a/src/ngx_rewrite_options.h
+++ b/src/ngx_rewrite_options.h
@@ -68,6 +68,24 @@
static const NgxRewriteOptions* DynamicCast(const RewriteOptions* instance);
static NgxRewriteOptions* DynamicCast(RewriteOptions* instance);
+ const GoogleString& statistics_path() const {
+ return statistics_path_.value();
+ }
+ const GoogleString& global_statistics_path() const {
+ return global_statistics_path_.value();
+ }
+ const GoogleString& console_path() const {
+ return console_path_.value();
+ }
+ const GoogleString& messages_path() const {
+ return messages_path_.value();
+ }
+ const GoogleString& admin_path() const {
+ return admin_path_.value();
+ }
+ const GoogleString& global_admin_path() const {
+ return global_admin_path_.value();
+ }
private:
// Helper methods for ParseAndSetOptions(). Each can:
@@ -109,10 +127,20 @@
static void add_ngx_option(typename OptionClass::ValueType default_value,
OptionClass NgxRewriteOptions::*offset,
const char* id,
- StringPiece option_name) {
- AddProperty(default_value, offset, id, option_name, ngx_properties_);
+ StringPiece option_name,
+ OptionScope scope,
+ const char* help) {
+ AddProperty(default_value, offset, id, option_name, scope, help,
+ ngx_properties_);
}
+ Option<GoogleString> statistics_path_;
+ Option<GoogleString> global_statistics_path_;
+ Option<GoogleString> console_path_;
+ Option<GoogleString> messages_path_;
+ Option<GoogleString> admin_path_;
+ Option<GoogleString> global_admin_path_;
+
// Helper for ParseAndSetOptions. Returns whether the two directives equal,
// ignoring case.
bool IsDirective(StringPiece config_directive, StringPiece compare_directive);
diff --git a/test/nginx_system_test.sh b/test/nginx_system_test.sh
index 5b6763c..9ded976 100755
--- a/test/nginx_system_test.sh
+++ b/test/nginx_system_test.sh
@@ -1123,44 +1123,43 @@
WGET_ARGS=""
-# TODO(jud): Enable this test when support for the admin page has been added.
-# start_test ShowCache without URL gets a form, inputs, preloaded UA.
-# ADMIN_CACHE=$PRIMARY_SERVER/pagespeed_admin/cache
-# OUT=$($WGET_DUMP $ADMIN_CACHE)
-# check_from "$OUT" fgrep -q "<form "
-# check_from "$OUT" fgrep -q "<input "
-# check_from "$OUT" fgrep -q "Cache-Control: max-age=0, no-cache"
-# # Preloaded user_agent value field leading with "Mozilla" set in
-# # ../automatic/system_test_helpers.sh to help test a "normal" flow.
-# check_from "$OUT" fgrep -q 'name=user_agent value="Mozilla'
-#
-# start_test ShowCache with bogus URL gives a 404
-# wget $PRIMARY_SERVER/pagespeed_cache?url=bogus_format >& /dev/null
-# check [ $? = 8 ]
-#
-# start_test ShowCache with valid, present URL, with unique options.
-# options="PageSpeedImageInlineMaxBytes=6765"
-# fetch_until -save $EXAMPLE_ROOT/rewrite_images.html?$options \
-# 'grep -c Puzzle\.jpg\.pagespeed\.ic\.' 1
-# URL_TAIL=$(grep Puzzle $FETCH_UNTIL_OUTFILE | cut -d \" -f 2)
-# SHOW_CACHE_URL=$EXAMPLE_ROOT/$URL_TAIL
-# SHOW_CACHE_QUERY=$ADMIN_CACHE?url=$SHOW_CACHE_URL\&$options
-# OUT=$($WGET_DUMP $SHOW_CACHE_QUERY)
-# check_from "$OUT" fgrep -q cache_ok:true
-# check_from "$OUT" fgrep -q mod_pagespeed_example/images/Puzzle.jpg
-#
-# function show_cache_after_flush() {
-# start_test ShowCache with same URL and matching options misses after flush
-# OUT=$($WGET_DUMP $SHOW_CACHE_QUERY)
-# check_from "$OUT" fgrep -q cache_ok:false
-# }
-#
-# on_cache_flush show_cache_after_flush
-#
-# start_test ShowCache with same URL but new options misses.
-# options="PageSpeedImageInlineMaxBytes=6766"
-# OUT=$($WGET_DUMP $ADMIN_CACHE?url=$SHOW_CACHE_URL\&$options)
-# check_from "$OUT" fgrep -q cache_ok:false
+start_test ShowCache without URL gets a form, inputs, preloaded UA.
+ADMIN_CACHE=$PRIMARY_SERVER/pagespeed_admin/cache
+OUT=$($WGET_DUMP $ADMIN_CACHE)
+check_from "$OUT" fgrep -q "<form "
+check_from "$OUT" fgrep -q "<input "
+check_from "$OUT" fgrep -q "Cache-Control: max-age=0, no-cache"
+# Preloaded user_agent value field leading with "Mozilla" set in
+# ../automatic/system_test_helpers.sh to help test a "normal" flow.
+check_from "$OUT" fgrep -q 'name=user_agent value="Mozilla'
+
+start_test ShowCache with bogus URL gives a 404
+wget $PRIMARY_SERVER/pagespeed_cache?url=bogus_format >& /dev/null
+check [ $? = 8 ]
+
+start_test ShowCache with valid, present URL, with unique options.
+options="PageSpeedImageInlineMaxBytes=6765"
+fetch_until -save $EXAMPLE_ROOT/rewrite_images.html?$options \
+ 'grep -c Puzzle\.jpg\.pagespeed\.ic\.' 1
+URL_TAIL=$(grep Puzzle $FETCH_UNTIL_OUTFILE | cut -d \" -f 2)
+SHOW_CACHE_URL=$EXAMPLE_ROOT/$URL_TAIL
+SHOW_CACHE_QUERY=$ADMIN_CACHE?url=$SHOW_CACHE_URL\&$options
+OUT=$($WGET_DUMP $SHOW_CACHE_QUERY)
+check_from "$OUT" fgrep -q cache_ok:true
+check_from "$OUT" fgrep -q mod_pagespeed_example/images/Puzzle.jpg
+
+function show_cache_after_flush() {
+ start_test ShowCache with same URL and matching options misses after flush
+ OUT=$($WGET_DUMP $SHOW_CACHE_QUERY)
+ check_from "$OUT" fgrep -q cache_ok:false
+}
+
+on_cache_flush show_cache_after_flush
+
+start_test ShowCache with same URL but new options misses.
+options="PageSpeedImageInlineMaxBytes=6766"
+OUT=$($WGET_DUMP $ADMIN_CACHE?url=$SHOW_CACHE_URL\&$options)
+check_from "$OUT" fgrep -q cache_ok:false
# This is dependent upon having a /ngx_pagespeed_beacon handler.
test_filter add_instrumentation beacons load.
@@ -2368,7 +2367,7 @@
STATS=$OUTDIR/blocking_rewrite_stats
IPRO_ROOT=http://ipro.example.com/mod_pagespeed_test/ipro
URL=$IPRO_ROOT/test_image_dont_reuse2.png
-IPRO_STATS_URL=http://ipro.example.com/ngx_pagespeed_statistics?PageSpeed=off
+IPRO_STATS_URL=http://ipro.example.com/ngx_pagespeed_statistics
# Initial stats.
http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP $IPRO_STATS_URL > $STATS.0
diff --git a/test/pagespeed_test.conf.template b/test/pagespeed_test.conf.template
index 8495c4e..e64036d 100644
--- a/test/pagespeed_test.conf.template
+++ b/test/pagespeed_test.conf.template
@@ -27,6 +27,13 @@
proxy_cache_path "@@PROXY_CACHE@@" levels=1:2 keys_zone=htmlcache:60m inactive=90m max_size=50m;
proxy_temp_path "@@TMP_PROXY_CACHE@@";
+ pagespeed StatisticsPath /ngx_pagespeed_statistics;
+ pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics;
+ pagespeed ConsolePath /pagespeed_console;
+ pagespeed MessagesPath /ngx_pagespeed_message;
+ pagespeed AdminPath /pagespeed_admin;
+ pagespeed GlobalAdminPath /pagespeed_global_admin;
+
root "@@SERVER_ROOT@@";
# Block 5a: Decide on Cache-Control header value to use for outgoing
@@ -911,6 +918,11 @@
server_name localhost;
pagespeed FileCachePath "@@FILE_CACHE@@";
+ location ~ ^/pagespeed_admin {
+ allow 127.0.0.1;
+ deny all;
+ }
+
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
add_header "" "";
}