Compare commits
162 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f867347b5a | |||
| 5bd8c93d39 | |||
| d85b22afe6 | |||
| 0456450fd2 | |||
| 90386f459a | |||
| 80c4b7e97b | |||
| 0c7d64221c | |||
| 68185b8605 | |||
| 7f225e2e70 | |||
| 4d728fc081 | |||
| a399e04a00 | |||
| 247a821564 | |||
| f7502b1b40 | |||
| 617f0e6bee | |||
| 42115f54da | |||
| 3d9f2aee37 | |||
| d77c7eac17 | |||
| 97134d951e | |||
| 17e4162334 | |||
| d70dcbc4d0 | |||
| 62c66e2c9c | |||
| 09478cac70 | |||
| 14b4723326 | |||
| ad41e72a83 | |||
| 7a54f88ae8 | |||
| e7be591e91 | |||
| 711b6a4954 | |||
| 916ff52307 | |||
| cd004c6d0c | |||
| 0fd456fa57 | |||
| 3b226aab7e | |||
| 90627b1fbd | |||
| 6cb4b8dde3 | |||
| d2af4962e6 | |||
| b997d79ea7 | |||
| 0baa230bd7 | |||
| 1118910228 | |||
| 7584be2668 | |||
| c8f8aff23f | |||
| 76eeec5972 | |||
| 2d24ec68f1 | |||
| 269ed10ed5 | |||
| 94dde75a86 | |||
| 9b47332d9c | |||
| 4b7a7cc15e | |||
| f8f32efb97 | |||
| 3015cf0372 | |||
| 8644e5d83d | |||
| 7fd0f3ee2f | |||
| a919a926f4 | |||
| ed5a43ef72 | |||
| ee27b5bd7a | |||
| 572f59299e | |||
| ebe7c61f4f | |||
| e542347a20 | |||
| b1d9fbf544 | |||
| 44626a4121 | |||
| 271b0c1f15 | |||
| 1bb10ec599 | |||
| c4fc99c5ae | |||
| 4c09bac0c4 | |||
| 03d69e53b1 | |||
| 15c6f7c345 | |||
| d7f48d88c6 | |||
| fd26b873e9 | |||
| d6c395151f | |||
| dab6b8ac04 | |||
| 77cd95b552 | |||
| be7837507f | |||
| 7094df4c11 | |||
| 76bc257af6 | |||
| 3208d56aa4 | |||
| 090ec03a68 | |||
| e885e02a3c | |||
| 6f5042020b | |||
| f3063e2daa | |||
| 56ee9ff24e | |||
| b290a4c8a3 | |||
| 297b4ab34b | |||
| b975ae59df | |||
| c0e917801d | |||
| a3bc2cae03 | |||
| 7fe4e09076 | |||
| ee20289863 | |||
| c3f2858e31 | |||
| 59005bec88 | |||
| 6634754dba | |||
| a9142f0003 | |||
| 8efb831ba4 | |||
| fcbe51efaf | |||
| 08e284f9cb | |||
| 8582bab69c | |||
| 5264647a65 | |||
| 85d0db2550 | |||
| 8e25b58597 | |||
| 6eee387802 | |||
| 2315173946 | |||
| 54bd8bf4f8 | |||
| 60f91becb7 | |||
| d959f01848 | |||
| f60c754d82 | |||
| 09f53881de | |||
| 929c5c5908 | |||
| 064ced104d | |||
| a73dc7ba74 | |||
| b081bb7aec | |||
| 0a60e0ef8b | |||
| 1926c78ca2 | |||
| c3598134ee | |||
| 43f09a877b | |||
| d023bb35f6 | |||
| 60c1f4cc4e | |||
| b88e067c6d | |||
| b214fb43e3 | |||
| 9e6048f771 | |||
| 653875cb68 | |||
| a512d95258 | |||
| a4441220b1 | |||
| 374ee1c750 | |||
| 059dd20b10 | |||
| 1964ef5219 | |||
| 56a5d41ec3 | |||
| 7ee1efe0dd | |||
| eb2a81ee79 | |||
| 37e1c3618a | |||
| df498ea788 | |||
| 4b4d353156 | |||
| c9d4912746 | |||
| 2b74f6bed3 | |||
| f1a6cd0ade | |||
| 0c01c0644e | |||
| 14aa4fd962 | |||
| 36a7ff9543 | |||
| 706577a34b | |||
| 6703b2d76e | |||
| 40c05b4a4f | |||
| bc875647f1 | |||
| f88a0763fd | |||
| 239ca9aa80 | |||
| 37c51d3b9e | |||
| 2468257e2d | |||
| 4628e1c0ea | |||
| 7f98ab448b | |||
| 103c479fbb | |||
| 887bd8fa98 | |||
| 804f234268 | |||
| ea82f0de19 | |||
| 5f312820e5 | |||
| 7efac4ac4e | |||
| 634b813071 | |||
| d30972985b | |||
| 3a6e833eae | |||
| 90c8ac8a12 | |||
| 6ccc1c513b | |||
| fe47eeb4f3 | |||
| e42f61e263 | |||
| 8bac32c669 | |||
| 4bef2af22c | |||
| 52bd966edd | |||
| 0f7a1f4503 | |||
| 7f477d6575 | |||
| cc10f15f53 |
@@ -2,3 +2,4 @@ test/tmp
|
||||
psol/
|
||||
psol-*.tar.gz
|
||||
*.*.*.*.tar.gz
|
||||
nginx
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
[submodule "testing-dependencies/mod_pagespeed"]
|
||||
path = testing-dependencies/mod_pagespeed
|
||||
url = https://github.com/pagespeed/mod_pagespeed.git
|
||||
[submodule "testing-dependencies/ngx_cache_purge"]
|
||||
path = testing-dependencies/ngx_cache_purge
|
||||
url = https://github.com/FRiCKLE/ngx_cache_purge.git
|
||||
[submodule "testing-dependencies/nginx"]
|
||||
path = testing-dependencies/nginx
|
||||
url = https://github.com/nginx/nginx.git
|
||||
[submodule "testing-dependencies/set-misc-nginx-module"]
|
||||
path = testing-dependencies/set-misc-nginx-module
|
||||
url = https://github.com/openresty/set-misc-nginx-module
|
||||
[submodule "testing-dependencies/ngx_devel_kit"]
|
||||
path = testing-dependencies/ngx_devel_kit
|
||||
url = https://github.com/simpl/ngx_devel_kit
|
||||
[submodule "testing-dependencies/headers-more-nginx-module"]
|
||||
path = testing-dependencies/headers-more-nginx-module
|
||||
url = https://github.com/openresty/headers-more-nginx-module
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
language: c++
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS=-j3
|
||||
# By default travis loads submodules serially, but we can load them in parallel
|
||||
# if we install an updated git and use --jobs. Some timing numbers:
|
||||
# serial: 257s
|
||||
# jobs=4: 182s (29s to install new git, 153s to run the downloads)
|
||||
# jobs=8: 179s (29s to install new git, 150s to run the downloads)
|
||||
# We can't use --depth=1, though, because github doesn't have
|
||||
# allowReachableSHA1InWant set.
|
||||
#
|
||||
# TODO(jefftk): once we're running on a server with git 2.8 or later we can have
|
||||
# --jobs without installing a new git.
|
||||
git:
|
||||
submodules: false
|
||||
before_install:
|
||||
- sudo add-apt-repository --yes ppa:git-core/ppa
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install git
|
||||
- git submodule update --init --recursive --jobs=8
|
||||
install:
|
||||
scripts/build_ngx_pagespeed.sh --devel --assume-yes
|
||||
script:
|
||||
test/run_tests.sh $PWD/testing-dependencies/mod_pagespeed/ \
|
||||
$PWD/nginx/sbin/nginx
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler:
|
||||
- gcc
|
||||
notifications:
|
||||
email:
|
||||
- cheesy@google.com
|
||||
- jefftk@google.com
|
||||
- morlovich@google.com
|
||||
- jmarantz@google.com
|
||||
- huibao@google.com
|
||||
@@ -0,0 +1,4 @@
|
||||
In a release this file would contain the URL to download the pre-compiled PSOL
|
||||
binary, but on development branches (like this one) you have to build PSOL from
|
||||
source yourself. See:
|
||||
https://github.com/pagespeed/ngx_pagespeed/wiki/Building-PSOL-From-Source
|
||||
@@ -1,5 +1,7 @@
|
||||

|
||||
|
||||
[](https://travis-ci.org/pagespeed/ngx_pagespeed)
|
||||
|
||||
ngx_pagespeed speeds up your site and reduces page load time by automatically
|
||||
applying web performance best practices to pages and associated assets (CSS,
|
||||
JavaScript, images) without requiring you to modify your existing content or
|
||||
|
||||
@@ -25,18 +25,28 @@ if [ "$mod_pagespeed_dir" = "unset" ] ; then
|
||||
|
||||
if [ ! -e "$mod_pagespeed_dir" ] ; then
|
||||
echo "ngx_pagespeed: pagespeed optimization library not found:"
|
||||
echo ""
|
||||
echo " You need to separately download the pagespeed library:"
|
||||
echo ""
|
||||
echo " $ cd /path/to/ngx_pagespeed"
|
||||
echo " $ wget https://dl.google.com/dl/page-speed/psol/1.9.32.1.tar.gz"
|
||||
echo " $ tar -xzvf 1.9.32.1.tar.gz # expands to psol/"
|
||||
echo ""
|
||||
echo " Or see the installation instructions:"
|
||||
echo " https://github.com/pagespeed/ngx_pagespeed#how-to-build"
|
||||
|
||||
psol_binary_url="$($ngx_addon_dir/scripts/format_binary_url.sh \
|
||||
$ngx_addon_dir/PSOL_BINARY_URL)"
|
||||
if [[ "$psol_binary_url" != https://* ]]; then
|
||||
echo "
|
||||
This is a development branch of ngx_pagespeed, which means there is no
|
||||
precompiled PSOL library available to link against. Either build from a
|
||||
release tag, like latest-beta, or build PSOL from source:
|
||||
https://github.com/pagespeed/ngx_pagespeed/wiki/Building-PSOL-From-Source"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "
|
||||
You need to separately download the pagespeed library:
|
||||
$ cd $ngx_addon_dir
|
||||
$ wget $psol_binary_url
|
||||
$ tar -xzvf $(basename $psol_binary_url) # expands to psol/
|
||||
|
||||
Or see the installation instructions:
|
||||
https://developers.google.com/speed/pagespeed/module/build_ngx_pagespeed_from_source"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
build_from_source=true
|
||||
fi
|
||||
@@ -67,10 +77,24 @@ fi
|
||||
|
||||
if [ "$NGX_DEBUG" = "YES" ]; then
|
||||
buildtype=Debug
|
||||
# If we're using a psol tarball that doesn't contain Debug/ (which is the case
|
||||
# from 1.12 onward) then this will be overriden to buildtype=Release below.
|
||||
else
|
||||
buildtype=Release
|
||||
fi
|
||||
|
||||
# If the compiler is gcc, we want to use g++ to link, if at all possible,
|
||||
# so that -static-libstdc++ works.
|
||||
# Annoyingly, the feature test doesn't even use $LINK for linking, so that
|
||||
# needs an explicit -lstdc++
|
||||
pagespeed_libs=
|
||||
ps_maybe_gpp_base=`basename $CC| sed s/gcc/g++/`
|
||||
ps_maybe_gpp="`dirname $CC`/$ps_maybe_gpp_base"
|
||||
if [ -n "$NGX_GCC_VER" -a \( -x "$ps_maybe_gpp" \) ]; then
|
||||
LINK=$ps_maybe_gpp
|
||||
fi
|
||||
pagespeed_libs="-lstdc++"
|
||||
|
||||
# The compiler needs to know that __sync_add_and_fetch_4 is ok,
|
||||
# and this requires an instruction that didn't exist on i586 or i386.
|
||||
if [ "$uname_arch" = "i686" ]; then
|
||||
@@ -79,6 +103,14 @@ fi
|
||||
|
||||
CFLAGS="$CFLAGS $FLAG_MARCH"
|
||||
|
||||
# For now, standardize on gcc-4.x ABI --- if we don't set this, people building
|
||||
# with new gcc defaulting to gcc-5 C++11 ABI will have build trouble linking
|
||||
# to our libpsol.a
|
||||
# See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
||||
CFLAGS="$CFLAGS -D_GLIBCXX_USE_CXX11_ABI=0"
|
||||
CC_OLD_TEST_FLAGS="$CC_TEST_FLAGS"
|
||||
CC_TEST_FLAGS="$CC_TEST_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0 --std=c++11"
|
||||
|
||||
case "$NGX_GCC_VER" in
|
||||
4.8*)
|
||||
# On GCC 4.8 and above, -Wall enables -Wunused-local-typedefs. This breaks
|
||||
@@ -97,6 +129,13 @@ case "$NGX_GCC_VER" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# workaround for a bug in nginx-1.9.11, see:
|
||||
# http://hg.nginx.org/nginx/rev/ff1e625ae55b
|
||||
NGX_VERSION=`grep nginx_version src/core/nginx.h | sed -e 's/^.* \(.*\)$/\1/'`
|
||||
if [ "$NGX_VERSION" = "1009011" ]; then
|
||||
CFLAGS="$CFLAGS -Wno-write-strings"
|
||||
fi
|
||||
|
||||
if [ "$WNO_ERROR" = "YES" ]; then
|
||||
CFLAGS="$CFLAGS -Wno-error"
|
||||
fi
|
||||
@@ -107,6 +146,22 @@ if [ "$psol_binary" = "unset" ] ; then
|
||||
psol_binary="\
|
||||
$mod_pagespeed_dir/pagespeed/automatic/pagespeed_automatic.a"
|
||||
else
|
||||
if ! [ -d "$ngx_addon_dir/psol/lib/$buildtype" ]; then
|
||||
echo "
|
||||
You have set --with-debug for building nginx, but precompiled Debug binaries for
|
||||
PSOL, which ngx_pagespeed depends on, aren't available. If you're trying to
|
||||
debug PSOL you need to build it from source. If you just want to run nginx with
|
||||
debug-level logging you can use the Release binaries."
|
||||
echo -n "
|
||||
Use the available Release binaries?"
|
||||
read -p " [Y/n] " yn
|
||||
if [[ "$yn" == N* || "$yn" == n* ]]; then
|
||||
echo "Cancelled."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
buildtype=Release
|
||||
fi
|
||||
psol_library_dir="$ngx_addon_dir/psol/lib/$buildtype/$os_name/$arch_name"
|
||||
psol_binary="$psol_library_dir/pagespeed_automatic.a"
|
||||
fi
|
||||
@@ -129,21 +184,24 @@ ngx_feature_incs="
|
||||
pagespeed_include="\
|
||||
$mod_pagespeed_dir \
|
||||
$mod_pagespeed_dir/third_party/chromium/src \
|
||||
$mod_pagespeed_dir/third_party/google-sparsehash/src \
|
||||
$mod_pagespeed_dir/third_party/google-sparsehash/src/src \
|
||||
$mod_pagespeed_dir/third_party/google-sparsehash/gen/arch/$os_name/$arch_name/include \
|
||||
$mod_pagespeed_dir/third_party/protobuf/src \
|
||||
$mod_pagespeed_dir/third_party/grpc/src/include \
|
||||
$mod_pagespeed_dir/third_party/protobuf/src/src \
|
||||
$mod_pagespeed_dir/third_party/re2/src \
|
||||
$mod_pagespeed_dir/out/$buildtype/obj/gen \
|
||||
$mod_pagespeed_dir/out/$buildtype/obj/gen/protoc_out/instaweb \
|
||||
$mod_pagespeed_dir/third_party/apr/src/include \
|
||||
$mod_pagespeed_dir/third_party/aprutil/src/include \
|
||||
$mod_pagespeed_dir/third_party/apr/gen/arch/$os_name/$arch_name/include \
|
||||
$mod_pagespeed_dir/third_party/aprutil/gen/arch/$os_name/$arch_name/include"
|
||||
$mod_pagespeed_dir/third_party/aprutil/gen/arch/$os_name/$arch_name/include \
|
||||
$mod_pagespeed_dir/url"
|
||||
ngx_feature_path="$pagespeed_include"
|
||||
|
||||
pagespeed_libs="-lstdc++ $psol_binary -lrt -pthread -lm"
|
||||
pagespeed_libs="$psol_binary $pagespeed_libs -lrt -pthread -lm -luuid"
|
||||
ngx_feature_libs="$pagespeed_libs"
|
||||
ngx_feature_test="
|
||||
|
||||
GoogleString output_buffer;
|
||||
net_instaweb::StringWriter write_to_string(&output_buffer);
|
||||
|
||||
@@ -164,59 +222,163 @@ ngx_feature_test="
|
||||
# Test whether we have pagespeed and can compile and link against it.
|
||||
. "$ngx_addon_dir/cpp_feature"
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
ps_src="$ngx_addon_dir/src"
|
||||
ngx_addon_name=ngx_pagespeed
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
|
||||
$ps_src/log_message_handler.h \
|
||||
$ps_src/ngx_base_fetch.h \
|
||||
$ps_src/ngx_caching_headers.h \
|
||||
$ps_src/ngx_event_connection.h \
|
||||
$ps_src/ngx_fetch.h \
|
||||
$ps_src/ngx_gzip_setter.h \
|
||||
$ps_src/ngx_list_iterator.h \
|
||||
$ps_src/ngx_message_handler.h \
|
||||
$ps_src/ngx_pagespeed.h \
|
||||
$ps_src/ngx_rewrite_driver_factory.h \
|
||||
$ps_src/ngx_rewrite_options.h \
|
||||
$ps_src/ngx_server_context.h \
|
||||
$ps_src/ngx_url_async_fetcher.h \
|
||||
$psol_binary"
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
|
||||
$ps_src/log_message_handler.cc \
|
||||
$ps_src/ngx_base_fetch.cc \
|
||||
$ps_src/ngx_caching_headers.cc \
|
||||
$ps_src/ngx_event_connection.cc \
|
||||
$ps_src/ngx_fetch.cc \
|
||||
$ps_src/ngx_gzip_setter.cc \
|
||||
$ps_src/ngx_list_iterator.cc \
|
||||
$ps_src/ngx_message_handler.cc \
|
||||
$ps_src/ngx_pagespeed.cc \
|
||||
$ps_src/ngx_rewrite_driver_factory.cc \
|
||||
$ps_src/ngx_rewrite_options.cc \
|
||||
$ps_src/ngx_server_context.cc \
|
||||
$ps_src/ngx_url_async_fetcher.cc"
|
||||
|
||||
if [ "$position_aux" = "true" ] ; then
|
||||
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $ngx_addon_name"
|
||||
else
|
||||
# Make pagespeed run immediately before gzip.
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES |\
|
||||
sed "s/$HTTP_GZIP_FILTER_MODULE/$HTTP_GZIP_FILTER_MODULE $ngx_addon_name/")
|
||||
fi
|
||||
|
||||
# Make the etag header filter run immediately after gzip.
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES |\
|
||||
sed "s/$HTTP_GZIP_FILTER_MODULE/ngx_pagespeed_etag_filter $HTTP_GZIP_FILTER_MODULE/")
|
||||
CORE_LIBS="$CORE_LIBS $pagespeed_libs"
|
||||
CORE_INCS="$CORE_INCS $pagespeed_include"
|
||||
echo "List of modules (in reverse order of applicability): "$HTTP_FILTER_MODULES
|
||||
else
|
||||
if [ $ngx_found = no ]; then
|
||||
cat << END
|
||||
$0: error: module ngx_pagespeed requires the pagespeed optimization library.
|
||||
Look in obj/autoconf.err for more details.
|
||||
Look in $PWD/$NGX_AUTOCONF_ERR for more details.
|
||||
END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ps_src="$ngx_addon_dir/src"
|
||||
ngx_addon_name=ngx_pagespeed
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
|
||||
$ps_src/log_message_handler.h \
|
||||
$ps_src/ngx_base_fetch.h \
|
||||
$ps_src/ngx_caching_headers.h \
|
||||
$ps_src/ngx_event_connection.h \
|
||||
$ps_src/ngx_fetch.h \
|
||||
$ps_src/ngx_gzip_setter.h \
|
||||
$ps_src/ngx_list_iterator.h \
|
||||
$ps_src/ngx_message_handler.h \
|
||||
$ps_src/ngx_pagespeed.h \
|
||||
$ps_src/ngx_rewrite_driver_factory.h \
|
||||
$ps_src/ngx_rewrite_options.h \
|
||||
$ps_src/ngx_server_context.h \
|
||||
$ps_src/ngx_url_async_fetcher.h \
|
||||
$psol_binary"
|
||||
NPS_SRCS=" \
|
||||
$ps_src/log_message_handler.cc \
|
||||
$ps_src/ngx_base_fetch.cc \
|
||||
$ps_src/ngx_caching_headers.cc \
|
||||
$ps_src/ngx_event_connection.cc \
|
||||
$ps_src/ngx_fetch.cc \
|
||||
$ps_src/ngx_gzip_setter.cc \
|
||||
$ps_src/ngx_list_iterator.cc \
|
||||
$ps_src/ngx_message_handler.cc \
|
||||
$ps_src/ngx_pagespeed.cc \
|
||||
$ps_src/ngx_rewrite_driver_factory.cc \
|
||||
$ps_src/ngx_rewrite_options.cc \
|
||||
$ps_src/ngx_server_context.cc \
|
||||
$ps_src/ngx_url_async_fetcher.cc"
|
||||
# Save our sources in a separate var since we may need it in config.make
|
||||
PS_NGX_SRCS="$NGX_ADDON_SRCS \
|
||||
$NPS_SRCS"
|
||||
|
||||
# Make pagespeed run immediately before gzip and Brotli.
|
||||
if echo $HTTP_FILTER_MODULES | grep ngx_http_brotli_filter_module >/dev/null; then
|
||||
next=ngx_http_brotli_filter_module
|
||||
elif [ $HTTP_GZIP = YES ]; then
|
||||
next=ngx_http_gzip_filter_module
|
||||
else
|
||||
next=ngx_http_range_header_filter_module
|
||||
fi
|
||||
|
||||
if [ -n "$ngx_module_link" ]; then
|
||||
# nginx-1.9.11+
|
||||
ngx_module_type=HTTP_FILTER
|
||||
ngx_module_name="ngx_pagespeed ngx_pagespeed_etag_filter"
|
||||
ngx_module_incs="$ngx_feature_path"
|
||||
ngx_module_deps=
|
||||
ngx_module_srcs="$NPS_SRCS"
|
||||
ngx_module_libs="$ngx_feature_libs"
|
||||
ngx_module_order="ngx_http_range_header_filter_module\
|
||||
ngx_pagespeed_etag_filter\
|
||||
ngx_http_gzip_filter_module \
|
||||
ngx_http_brotli_filter_module \
|
||||
ngx_pagespeed \
|
||||
ngx_http_postpone_filter_module \
|
||||
ngx_http_ssi_filter_module \
|
||||
ngx_http_charset_filter_module \
|
||||
ngx_http_xslt_filter_module \
|
||||
ngx_http_image_filter_module \
|
||||
ngx_http_sub_filter_module \
|
||||
ngx_http_addition_filter_module \
|
||||
ngx_http_gunzip_filter_module \
|
||||
ngx_http_userid_filter_module \
|
||||
ngx_http_headers_filter_module"
|
||||
|
||||
. auto/module
|
||||
|
||||
if [ $ngx_module_link != DYNAMIC ]; then
|
||||
# ngx_module_order doesn't work with static modules,
|
||||
# so we must re-order filters here.
|
||||
if [ "$position_aux" = "true" ] ; then
|
||||
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $ngx_addon_name"
|
||||
else
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES \
|
||||
| sed "s/ngx_pagespeed//" \
|
||||
| sed "s/$next/$next ngx_pagespeed/")
|
||||
fi
|
||||
# Make the etag header filter run immediately before range header filter.
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES \
|
||||
| sed "s/ngx_pagespeed_etag_filter//" \
|
||||
| sed "s/ngx_http_range_header_filter_module/ngx_http_range_header_filter_module ngx_pagespeed_etag_filter/")
|
||||
else
|
||||
if [ "$position_aux" = "true" ] ; then
|
||||
ngx_module_type=HTTP_AUX_FILTER
|
||||
ngx_module_order=""
|
||||
fi
|
||||
fi
|
||||
else
|
||||
CORE_LIBS="$CORE_LIBS $pagespeed_libs"
|
||||
CORE_INCS="$CORE_INCS $pagespeed_include"
|
||||
NGX_ADDON_SRCS="$PS_NGX_SRCS"
|
||||
if [ "$position_aux" = "true" ] ; then
|
||||
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $ngx_addon_name"
|
||||
else
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES | sed "s/$next/$next $ngx_addon_name/")
|
||||
fi
|
||||
|
||||
# Make the etag header filter run immediately before range header filter.
|
||||
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES |\
|
||||
sed "s/ngx_http_range_header_filter_module/ngx_http_range_header_filter_module ngx_pagespeed_etag_filter/")
|
||||
fi
|
||||
|
||||
echo "List of modules (in reverse order of applicability): "$HTTP_FILTER_MODULES
|
||||
|
||||
# Test whether the compiler is compatible
|
||||
ngx_feature="psol-compiler-compat"
|
||||
ngx_feature_name=""
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs=""
|
||||
ngx_feature_path=""
|
||||
ngx_feature_libs="-lstdc++"
|
||||
ngx_feature_test="
|
||||
|
||||
#if defined(__clang__) && defined(__GLIBCXX__)
|
||||
// See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning
|
||||
// for a list of various values of __GLIBCXX__. Note that they're not monotonic
|
||||
// with respect to version numbers.
|
||||
#if __GLIBCXX__ == 20120322 || __GLIBCXX__ == 20120614
|
||||
#error \"clang is using libstdc++ 4.7.0 or 4.7.1, which can cause binary incompatibility.\"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__)
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
|
||||
#error \"GCC < 4.8 no longer supported. Please use gcc >= 4.8 or clang >= 3.3\"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3)
|
||||
#error \"Please use gcc >= 4.8 or clang >= 3.3\"
|
||||
#endif
|
||||
#endif
|
||||
"
|
||||
|
||||
. "$ngx_addon_dir/cpp_feature"
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
cat << END
|
||||
$0: error: module ngx_pagespeed requires gcc >= 4.8 or clang >= 3.3.
|
||||
See https://developers.google.com/speed/pagespeed/module/build_ngx_pagespeed_from_source for some recommendations.
|
||||
Look in $PWD/$NGX_AUTOCONF_ERR for more details.
|
||||
END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
have=NGX_PAGESPEED . auto/have
|
||||
|
||||
CC_TEST_FLAGS="$CC_OLD_TEST_FLAGS"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Since nginx build system doesn't normally do C++, there is no CXXFLAGS for us
|
||||
# to touch, and compilers are understandably unhappy with --std=c++11 on C
|
||||
# files. Hence, we hack the makefile to add it for just our sources.
|
||||
for ps_src_file in $PS_NGX_SRCS; do
|
||||
ps_obj_file="$NGX_OBJS/addon/src/`basename $ps_src_file .cc`.o"
|
||||
echo "$ps_obj_file : CFLAGS += --std=c++11" >> $NGX_MAKEFILE
|
||||
done
|
||||
Executable
+802
@@ -0,0 +1,802 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2016 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.
|
||||
|
||||
function usage() {
|
||||
echo "
|
||||
Usage: build_ngx_pagespeed.sh [options]
|
||||
|
||||
Installs ngx_pagespeed and its dependencies. Can optionally build and install
|
||||
nginx as well. Can be run either as:
|
||||
|
||||
bash <(curl -f -L -sS https://ngxpagespeed.com/install) [options]
|
||||
|
||||
Or:
|
||||
|
||||
git clone git@github.com:pagespeed/ngx_pagespeed.git
|
||||
cd ngx_pagespeed/
|
||||
git checkout <branch>
|
||||
scripts/build_ngx_pagespeed.sh [options]
|
||||
|
||||
Options:
|
||||
-v, --ngx-pagespeed-version <ngx_pagespeed version>
|
||||
What version of ngx_pagespeed to build. Valid options include:
|
||||
* latest-beta
|
||||
* latest-stable
|
||||
* a version number, such as 1.11.33.4
|
||||
|
||||
If you don't specify a version, defaults to latest-stable unless --devel
|
||||
is specified, in which case it defaults to master.
|
||||
|
||||
This option doesn't make sense if we're running within an existing
|
||||
ngx_pagespeed checkout.
|
||||
|
||||
-n, --nginx-version <nginx version>
|
||||
What version of nginx to build. If not set, this script only prepares the
|
||||
ngx_pagespeed module, and expects you to handle including it when you
|
||||
build nginx.
|
||||
|
||||
If you pass in 'latest' then this script scrapes the nginx download page
|
||||
and attempts to determine the latest version automatically.
|
||||
|
||||
-m, --dynamic-module
|
||||
Build ngx_pagespeed as a dynamic module.
|
||||
|
||||
-b, --builddir <directory>
|
||||
Where to build. Defaults to \$HOME.
|
||||
|
||||
-p, --no-deps-check
|
||||
By default, this script checks for the packages it depends on and tries to
|
||||
install them. If you have installed dependencies from source or are on a
|
||||
non-deb non-rpm system, this won't work. In that case, install the
|
||||
dependencies yourself and pass --no-deps-check.
|
||||
|
||||
-s, --psol-from-source
|
||||
Build PSOL from source instead of downloading a pre-built binary module.
|
||||
|
||||
-l, --devel
|
||||
Sets up a development environment in ngx_pagespeed/nginx, building with
|
||||
testing-only dependencies. Includes --psol-from-source, conflicts with
|
||||
--nginx-version. Uses a 'git clone' checkout for ngx_pagespeed and nginx
|
||||
instead of downloading a tarball.
|
||||
|
||||
-t, --build-type
|
||||
When building PSOL from source, what to tell it for BUILD_TYPE. Defaults
|
||||
to 'Release' unless --devel is set in which case it defaults to 'Debug'.
|
||||
|
||||
-y, --assume-yes
|
||||
Assume the answer to all prompts is 'yes, please continue'. Intended for
|
||||
automated usage, such as buildbots.
|
||||
|
||||
-d, --dryrun
|
||||
Don't make any changes to the system, just print what changes you
|
||||
would have made.
|
||||
|
||||
-h, --help
|
||||
Print this message and exit."
|
||||
}
|
||||
|
||||
RED=31
|
||||
GREEN=32
|
||||
YELLOW=33
|
||||
function begin_color() {
|
||||
color="$1"
|
||||
echo -e -n "\e[${color}m"
|
||||
}
|
||||
function end_color() {
|
||||
echo -e -n "\e[0m"
|
||||
}
|
||||
|
||||
function echo_color() {
|
||||
color="$1"
|
||||
shift
|
||||
begin_color "$color"
|
||||
echo "$@"
|
||||
end_color
|
||||
}
|
||||
|
||||
function error() {
|
||||
local error_message="$@"
|
||||
echo_color "$RED" -n "Error: " >&2
|
||||
echo "$@" >&2
|
||||
}
|
||||
|
||||
# Prints an error message and exits with an error code.
|
||||
function fail() {
|
||||
error "$@"
|
||||
|
||||
# Normally I'd use $0 in "usage" here, but since most people will be running
|
||||
# this via curl, that wouldn't actually give something useful.
|
||||
echo >&2
|
||||
echo "For usage information, run this script with --help" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
function status() {
|
||||
echo_color "$GREEN" "$@"
|
||||
}
|
||||
|
||||
# Intended to be called as:
|
||||
# bash <(curl dl.google.com/.../build_ngx_pagespeed.sh) <args>
|
||||
|
||||
# If we set -e or -u then users of this script will see it silently exit on
|
||||
# failure. Instead we need to check the exit status of each command manually.
|
||||
# The run function handles exit-status checking for system-changing commands.
|
||||
# Additionally, this allows us to easily have a dryrun mode where we don't
|
||||
# actually make any changes.
|
||||
INITIAL_ENV=$(printenv | sort)
|
||||
function run() {
|
||||
if "$DRYRUN"; then
|
||||
echo_color "$YELLOW" -n "would run"
|
||||
echo " $@"
|
||||
env_differences=$(comm -13 <(echo "$INITIAL_ENV") <(printenv | sort))
|
||||
if [ -n "$env_differences" ]; then
|
||||
echo " with the following additional environment variables:"
|
||||
echo "$env_differences" | sed 's/^/ /'
|
||||
fi
|
||||
else
|
||||
if ! "$@"; then
|
||||
error "Failure running '$@', exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function redhat_is_installed() {
|
||||
local package_name="$1"
|
||||
rpm -qa $package_name | grep -q .
|
||||
}
|
||||
|
||||
function debian_is_installed() {
|
||||
local package_name="$1"
|
||||
dpkg -l $package_name | grep ^ii | grep -q .
|
||||
}
|
||||
|
||||
function version_sort() {
|
||||
# We'd rather use sort -V, but that's not available on Centos 5. This works
|
||||
# for versions in the form A.B.C.D or shorter, which is enough for our use.
|
||||
sort -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g
|
||||
}
|
||||
|
||||
# Compare two numeric versions in the form "A.B.C". Works with version numbers
|
||||
# having up to four components, since that's enough to handle both nginx (3) and
|
||||
# ngx_pagespeed (4).
|
||||
function version_older_than() {
|
||||
local test_version="$1"
|
||||
local compare_to="$2"
|
||||
|
||||
local older_version=$(echo $@ | tr ' ' '\n' | version_sort | head -n 1)
|
||||
test "$older_version" != "$compare_to"
|
||||
}
|
||||
|
||||
function determine_latest_nginx_version() {
|
||||
# Scrape nginx's download page to try to find the most recent nginx version.
|
||||
|
||||
nginx_download_url="https://nginx.org/en/download.html"
|
||||
function report_error() {
|
||||
fail "
|
||||
Couldn't automatically determine the latest nginx version: failed to $@
|
||||
$nginx_download_url"
|
||||
}
|
||||
|
||||
nginx_download_page=$(curl -sS --fail "$nginx_download_url") || \
|
||||
report_error "download"
|
||||
|
||||
download_refs=$(echo "$nginx_download_page" | \
|
||||
grep -o '/download/nginx-[0-9.]*[.]tar[.]gz') || \
|
||||
report_error "parse"
|
||||
|
||||
versions_available=$(echo "$download_refs" | \
|
||||
sed -e 's~^/download/nginx-~~' -e 's~\.tar\.gz$~~') || \
|
||||
report_error "extract versions from"
|
||||
|
||||
latest_version=$(echo "$versions_available" | version_sort | tail -n 1) || \
|
||||
report_error "determine latest version from"
|
||||
|
||||
if version_older_than "$latest_version" "1.11.4"; then
|
||||
fail "
|
||||
Expected the latest version of nginx to be at least 1.11.4 but found
|
||||
$latest_version on $nginx_download_url"
|
||||
fi
|
||||
|
||||
echo "$latest_version"
|
||||
}
|
||||
|
||||
# Usage:
|
||||
# install_dependencies install_pkg_cmd is_pkg_installed_cmd dep1 dep2 ...
|
||||
#
|
||||
# install_pkg_cmd is a command to install a dependency
|
||||
# is_pkg_installed_cmd is a command that returns true if the dependency is
|
||||
# already installed
|
||||
# each dependency is a package name
|
||||
function install_dependencies() {
|
||||
local install_pkg_cmd="$1"
|
||||
local is_pkg_installed_cmd="$2"
|
||||
shift 2
|
||||
|
||||
local missing_dependencies=""
|
||||
|
||||
for package_name in "$@"; do
|
||||
if ! $is_pkg_installed_cmd $package_name; then
|
||||
missing_dependencies+="$package_name "
|
||||
fi
|
||||
done
|
||||
if [ -n "$missing_dependencies" ]; then
|
||||
status "Detected that we're missing the following depencencies:"
|
||||
echo " $missing_dependencies"
|
||||
status "Installing them:"
|
||||
run sudo $install_pkg_cmd $missing_dependencies
|
||||
fi
|
||||
}
|
||||
|
||||
function gcc_too_old() {
|
||||
# We need gcc >= 4.8
|
||||
local gcc_major_version=$(gcc -dumpversion | awk -F. '{print $1}')
|
||||
if [ "$gcc_major_version" -lt 4 ]; then
|
||||
return 0 # too old
|
||||
elif [ "$gcc_major_version" -gt 4 ]; then
|
||||
return 1 # plenty new
|
||||
fi
|
||||
# It's gcc 4.x, check if x >= 8:
|
||||
local gcc_minor_version=$(gcc -dumpversion | awk -F. '{print $2}')
|
||||
test "$gcc_minor_version" -lt 8
|
||||
}
|
||||
|
||||
function continue_or_exit() {
|
||||
if "$ASSUME_YES"; then
|
||||
return
|
||||
fi
|
||||
|
||||
local prompt="$1"
|
||||
echo_color "$YELLOW" -n "$prompt"
|
||||
read -p " [Y/n] " yn
|
||||
if [[ "$yn" == N* || "$yn" == n* ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# If a string is very simple we don't need to quote it. But we should quote
|
||||
# everything else to be safe.
|
||||
function needs_quoting() {
|
||||
echo "$@" | grep -q '[^a-zA-Z0-9./_=-]'
|
||||
}
|
||||
|
||||
function escape_for_quotes() {
|
||||
echo "$@" | sed -e 's~\\~\\\\~g' -e "s~'~\\\\'~g"
|
||||
}
|
||||
|
||||
function quote_arguments() {
|
||||
local argument_str=""
|
||||
for argument in "$@"; do
|
||||
if [ -n "$argument_str" ]; then
|
||||
argument_str+=" "
|
||||
fi
|
||||
if needs_quoting "$argument"; then
|
||||
argument="'$(escape_for_quotes "$argument")'"
|
||||
fi
|
||||
argument_str+="$argument"
|
||||
done
|
||||
echo "$argument_str"
|
||||
}
|
||||
|
||||
function build_ngx_pagespeed() {
|
||||
getopt --test
|
||||
if [ "$?" != 4 ]; then
|
||||
# Even Centos 5 and Ubuntu 10 LTS have new-style getopt, so I don't expect
|
||||
# this to be hit in practice on systems that are actually able to run
|
||||
# PageSpeed.
|
||||
fail "Your version of getopt is too old. Exiting with no changes made."
|
||||
fi
|
||||
|
||||
opts=$(getopt -o v:n:mb:pslt:ydh \
|
||||
--longoptions ngx-pagespeed-version:,nginx-version:,dynamic-module \
|
||||
--longoptions buildir:,no-deps-check,psol-from-source,devel,build-type: \
|
||||
--longoptions assume-yes,dryrun,help \
|
||||
-n "$(basename "$0")" -- "$@")
|
||||
if [ $? != 0 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$opts"
|
||||
|
||||
NPS_VERSION="DEFAULT"
|
||||
NGINX_VERSION=""
|
||||
BUILDDIR="$HOME"
|
||||
DO_DEPS_CHECK=true
|
||||
PSOL_FROM_SOURCE=false
|
||||
DEVEL=false
|
||||
BUILD_TYPE=""
|
||||
ASSUME_YES=false
|
||||
DRYRUN=false
|
||||
DYNAMIC_MODULE=false
|
||||
while true; do
|
||||
case "$1" in
|
||||
-v | --ngx-pagespeed-version) shift
|
||||
NPS_VERSION="$1"
|
||||
shift
|
||||
;;
|
||||
-n | --nginx-version) shift
|
||||
NGINX_VERSION="$1"
|
||||
shift
|
||||
;;
|
||||
-m | --dynamic-module) shift
|
||||
DYNAMIC_MODULE=true
|
||||
;;
|
||||
-b | --builddir) shift
|
||||
BUILDDIR="$1"
|
||||
shift
|
||||
;;
|
||||
-p | --no-deps-check) shift
|
||||
DO_DEPS_CHECK=false
|
||||
;;
|
||||
-s | --psol-from-source) shift
|
||||
PSOL_FROM_SOURCE=true
|
||||
;;
|
||||
-l | --devel) shift
|
||||
DEVEL=true
|
||||
;;
|
||||
-t | --build-type) shift
|
||||
BUILD_TYPE="$1"
|
||||
shift
|
||||
;;
|
||||
-y | --assume-yes) shift
|
||||
ASSUME_YES="true"
|
||||
;;
|
||||
-d | --dryrun) shift
|
||||
DRYRUN="true"
|
||||
;;
|
||||
-h | --help) shift
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--) shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Invalid argument: $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
USE_GIT_CHECKOUT="$DEVEL"
|
||||
ALREADY_CHECKED_OUT=false
|
||||
if [ -e PSOL_BINARY_URL ]; then
|
||||
status "Detected that we're running in an existing ngx_pagespeed checkout."
|
||||
USE_GIT_CHECKOUT=true
|
||||
ALREADY_CHECKED_OUT=true
|
||||
fi
|
||||
|
||||
if "$ALREADY_CHECKED_OUT"; then
|
||||
if [ "$NPS_VERSION" != "DEFAULT" ]; then
|
||||
fail \
|
||||
"The --ngx-pagespeed-version argument doesn't make sense when running within an existing checkout."
|
||||
fi
|
||||
elif [ "$NPS_VERSION" = "DEFAULT" ]; then
|
||||
if "$DEVEL"; then
|
||||
NPS_VERSION="master"
|
||||
else
|
||||
NPS_VERSION="latest-stable"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$BUILDDIR" ]; then
|
||||
fail "Told to build in $BUILDDIR, but that directory doesn't exist."
|
||||
fi
|
||||
|
||||
BUILD_NGINX=false
|
||||
if [ -n "$NGINX_VERSION" ]; then
|
||||
BUILD_NGINX=true
|
||||
fi
|
||||
|
||||
if "$DEVEL"; then
|
||||
PSOL_FROM_SOURCE=true
|
||||
BUILD_NGINX=true
|
||||
if [ -n "$NGINX_VERSION" ]; then
|
||||
fail \
|
||||
"The --devel argument conflicts with --nginx. In devel mode we use the version of nginx that's included as a submodule."
|
||||
fi
|
||||
if "$DYNAMIC_MODULE"; then
|
||||
fail "Can't currently build a dynamic module in --devel mode."
|
||||
fi
|
||||
fi
|
||||
|
||||
if "$PSOL_FROM_SOURCE" && [ -z "$BUILD_TYPE" ]; then
|
||||
if "$DEVEL"; then
|
||||
BUILD_TYPE="Debug"
|
||||
else
|
||||
BUILD_TYPE="Release"
|
||||
fi
|
||||
elif [ -n "$BUILD_TYPE" ]; then
|
||||
fail "Setting --build-type requires --psol-from-source or --devel."
|
||||
fi
|
||||
|
||||
if [ "$NGINX_VERSION" = "latest" ]; then
|
||||
# When this function fails it prints the debugging information needed first
|
||||
# to stderr.
|
||||
NGINX_VERSION=$(determine_latest_nginx_version) || exit 1
|
||||
fi
|
||||
|
||||
if "$DYNAMIC_MODULE"; then
|
||||
# Check that ngx_pagespeed and nginx are recent enough to support dynamic
|
||||
# modules. Unfortunately NPS_VERSION might be a tag, in which case we don't
|
||||
# know. If it's not a numeric version number, then assume it's recent
|
||||
# enough and if it's not they'll get an ugly compilation error later.
|
||||
# Luckily 1.10.33.5 was a while ago now.
|
||||
#
|
||||
# I'd like to use =~ here, but they changed syntax between v3 and v4 (quotes
|
||||
# moved from mandatory to optional to prohibited).
|
||||
if [[ "${NPS_VERSION#*[^0-9.]}" = "$NPS_VERSION" ]] &&
|
||||
version_older_than "$NPS_VERSION" "1.10.33.5"; then
|
||||
fail "
|
||||
You're trying to build ngx_pagespeed $NPS_VERSION as a dynamic module, but
|
||||
ngx_pagespeed didn't add support for dynamic modules until 1.10.33.5."
|
||||
fi
|
||||
|
||||
if [ ! -z "NGINX_VERSION" ]; then
|
||||
if version_older_than "$NGINX_VERSION" "1.9.13"; then
|
||||
fail "
|
||||
You're trying to build nginx $NGINX_VERSION as a dynamic module but nginx didn't
|
||||
add support for dynamic modules in a way compatible with ngx_pagespeed until
|
||||
1.9.13."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if "$DRYRUN"; then
|
||||
TEMPDIR="/tmp/output-of-mktemp"
|
||||
else
|
||||
TEMPDIR=$(mktemp -d)
|
||||
function cleanup_tempdir {
|
||||
rm -rf "$TEMPDIR"
|
||||
}
|
||||
trap cleanup_tempdir EXIT
|
||||
fi
|
||||
|
||||
extra_flags=()
|
||||
# Now make sure our dependencies are installed.
|
||||
if "$DO_DEPS_CHECK"; then
|
||||
if [ -f /etc/debian_version ]; then
|
||||
status "Detected debian-based distro."
|
||||
|
||||
install_dependencies "apt-get install" debian_is_installed \
|
||||
"build-essential zlib1g-dev libpcre3 libpcre3-dev unzip"
|
||||
|
||||
if gcc_too_old; then
|
||||
if [ ! -e /usr/lib/gcc-mozilla/bin/gcc ]; then
|
||||
status "Detected that gcc is older than 4.8. Installing gcc-mozilla"
|
||||
status "which installs gcc-4.8 into /usr/lib/gcc-mozilla/ and doesn't"
|
||||
status "affect your global gcc installation."
|
||||
run sudo apt-get install gcc-mozilla
|
||||
fi
|
||||
|
||||
extra_flags=("--with-cc=/usr/lib/gcc-mozilla/bin/gcc" \
|
||||
"--with-ld-opt=-static-libstdc++")
|
||||
fi
|
||||
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
status "Detected redhat-based distro."
|
||||
|
||||
install_dependencies "yum install" redhat_is_installed \
|
||||
"gcc-c++ pcre-devel zlib-devel make unzip wget"
|
||||
if gcc_too_old; then
|
||||
if [ ! -e /opt/rh/devtoolset-2/root/usr/bin/gcc ]; then
|
||||
redhat_major_version=$(
|
||||
cat /etc/redhat-release | grep -o -E '[0-9]+' | head -n 1)
|
||||
if [ "$redhat_major_version" == 5 ]; then
|
||||
slc_version=5
|
||||
elif [ "$redhat_major_version" == 6 ]; then
|
||||
slc_version=6
|
||||
else
|
||||
fail "
|
||||
Unexpected major version $redhat_major_version in /etc/redhat-release:
|
||||
$(cat /etc/redhat-release) Expected 5 or 6."
|
||||
fi
|
||||
|
||||
status "Detected that gcc is older than 4.8. Scientific Linux"
|
||||
status "provides a gcc package that installs gcc-4.8 into /opt/ and"
|
||||
status "doesn't affect your global gcc installation."
|
||||
slc_key="https://linux.web.cern.ch/linux/scientific6/docs/repository/"
|
||||
slc_key+="cern/slc6X/i386/RPM-GPG-KEY-cern"
|
||||
slc_key_out="$TEMPDIR/RPM-GPG-KEY-cern"
|
||||
run sudo wget "$slc_key" -O "$slc_key_out"
|
||||
run sudo rpm --import "$slc_key_out"
|
||||
|
||||
repo_fname="/etc/yum.repos.d/slc${slc_version}-devtoolset.repo"
|
||||
if [ -e "$repo_fname" ]; then
|
||||
fail "Expected $repo_fname not to exist; aborting."
|
||||
fi
|
||||
|
||||
repo_url="https://linux.web.cern.ch/linux/scientific${slc_version}/"
|
||||
repo_url+="/docs/repository/cern/devtoolset/"
|
||||
repo_url+="slc${slc_version}-devtoolset.repo"
|
||||
run sudo wget -O "$repo_fname" "$repo_url"
|
||||
run sudo yum install devtoolset-2-gcc-c++ devtoolset-2-binutils
|
||||
fi
|
||||
extra_flags=("--with-cc=/opt/rh/devtoolset-2/root/usr/bin/gcc")
|
||||
fi
|
||||
else
|
||||
fail "
|
||||
This doesn't appear to be a deb-based distro or an rpm-based one. Not going to
|
||||
be able to install dependencies. Please install dependencies manually and rerun
|
||||
with --no-deps-check."
|
||||
fi
|
||||
status "Operating system dependencies are all set."
|
||||
else
|
||||
status "Not checking whether operating system dependencies are installed."
|
||||
fi
|
||||
|
||||
function delete_if_already_exists() {
|
||||
if "$DRYRUN"; then return; fi
|
||||
|
||||
local directory="$1"
|
||||
if [ -d "$directory" ]; then
|
||||
if [ ${#directory} -lt 8 ]; then
|
||||
fail "
|
||||
Not deleting $directory; name is suspiciously short. Something is wrong."
|
||||
fi
|
||||
|
||||
continue_or_exit "OK to delete $directory?"
|
||||
run rm -rf "$directory"
|
||||
fi
|
||||
}
|
||||
|
||||
# In general, the zip github builds for tag foo unzips to ngx_pagespeed-foo,
|
||||
# but it looks like they special case vVERSION tags to ngx_pagespeed-VERSION
|
||||
if [[ "$NPS_VERSION" =~ ^[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*$ ]]; then
|
||||
# We've been given a numeric version number. This has an associated tag
|
||||
# in the form vVERSION-beta.
|
||||
tag_name="v${NPS_VERSION}-beta"
|
||||
nps_downloaded_fname="ngx_pagespeed-${NPS_VERSION}-beta"
|
||||
else
|
||||
# We've been given a tag name, like latest-beta. Download that directly.
|
||||
tag_name="$NPS_VERSION"
|
||||
nps_downloaded_fname="ngx_pagespeed-${NPS_VERSION}"
|
||||
fi
|
||||
|
||||
install_dir="this-only-makes-sense-in-devel-mode"
|
||||
if "$USE_GIT_CHECKOUT"; then
|
||||
# We're either doing a --devel build, or someone is running us from an
|
||||
# existing git checkout.
|
||||
nps_module_dir="$PWD"
|
||||
install_dir="$nps_module_dir"
|
||||
if "$ALREADY_CHECKED_OUT"; then
|
||||
run cd "$nps_module_dir"
|
||||
else
|
||||
status "Checking out ngx_pagespeed..."
|
||||
run git clone "git@github.com:pagespeed/ngx_pagespeed.git" \
|
||||
"$nps_module_dir"
|
||||
run cd "$nps_module_dir"
|
||||
run git checkout "$tag_name"
|
||||
fi
|
||||
submodules_dir="$nps_module_dir/testing-dependencies"
|
||||
if "$DEVEL"; then
|
||||
status "Downloading dependencies..."
|
||||
run git submodule update --init --recursive
|
||||
if [[ "$CONTINUOUS_INTEGRATION" != true ]]; then
|
||||
status "Switching submodules over to git protocol."
|
||||
# This lets us push to github by public key.
|
||||
for config in $(find .git/ -name config) ; do
|
||||
run sed -i s~https://github.com/~git@github.com:~ $config ;
|
||||
done
|
||||
fi
|
||||
fi
|
||||
else
|
||||
nps_baseurl="https://github.com/pagespeed/ngx_pagespeed/archive"
|
||||
nps_downloaded="$TEMPDIR/$nps_downloaded_fname.zip"
|
||||
status "Downloading ngx_pagespeed..."
|
||||
run wget "$nps_baseurl/$tag_name.zip" -O "$nps_downloaded"
|
||||
nps_module_dir="$BUILDDIR/$nps_downloaded_fname"
|
||||
delete_if_already_exists "$nps_module_dir"
|
||||
status "Extracting ngx_pagespeed..."
|
||||
run unzip -q "$nps_downloaded" -d "$BUILDDIR"
|
||||
run cd "$nps_module_dir"
|
||||
fi
|
||||
|
||||
MOD_PAGESPEED_DIR=""
|
||||
PSOL_BINARY=""
|
||||
if "$PSOL_FROM_SOURCE"; then
|
||||
MOD_PAGESPEED_DIR="$PWD/testing-dependencies/mod_pagespeed"
|
||||
git submodule update --init --recursive -- "$MOD_PAGESPEED_DIR"
|
||||
run pushd "$MOD_PAGESPEED_DIR"
|
||||
|
||||
if "$DEVEL"; then
|
||||
if [ ! -d "$HOME/apache2" ]; then
|
||||
run install/build_development_apache.sh 2.2 prefork
|
||||
fi
|
||||
cd devel
|
||||
run make apache_debug_psol
|
||||
PSOL_BINARY="$MOD_PAGESPEED_DIR/out/$BUILD_TYPE/pagespeed_automatic.a"
|
||||
else
|
||||
run install/build_psol.sh --skip_tests --skip_packaging
|
||||
PSOL_BINARY="$MOD_PAGESPEED_DIR/pagespeed/automatic/pagespeed_automatic.a"
|
||||
fi
|
||||
run popd
|
||||
else
|
||||
# Now we need to figure out what precompiled version of PSOL to build
|
||||
# ngx_pagespeed against.
|
||||
if "$DRYRUN"; then
|
||||
psol_url="https://psol.example.com/cant-get-psol-version-in-dry-run.tar.gz"
|
||||
elif [ -e PSOL_BINARY_URL ]; then
|
||||
# Releases after 1.11.33.4 there is a PSOL_BINARY_URL file that tells us
|
||||
# where to look.
|
||||
psol_url="$(scripts/format_binary_url.sh PSOL_BINARY_URL)"
|
||||
if [[ "$psol_url" != https://* ]]; then
|
||||
fail "Got bad psol binary location information: $psol_url"
|
||||
fi
|
||||
else
|
||||
# For past releases we have to grep it from the config file. The url has
|
||||
# always looked like this, and the config file has contained it since
|
||||
# before we started tagging our ngx_pagespeed releases.
|
||||
psol_url="$(grep -o \
|
||||
"https://dl.google.com/dl/page-speed/psol/[0-9.]*.tar.gz" config)"
|
||||
if [ -z "$psol_url" ]; then
|
||||
fail "Couldn't find PSOL url in $PWD/config"
|
||||
fi
|
||||
fi
|
||||
|
||||
status "Downloading PSOL binary..."
|
||||
run wget "$psol_url"
|
||||
|
||||
status "Extracting PSOL..."
|
||||
run tar -xzf $(basename "$psol_url") # extracts to psol/
|
||||
fi
|
||||
|
||||
if "$DYNAMIC_MODULE"; then
|
||||
add_module="--add-dynamic-module=$nps_module_dir"
|
||||
else
|
||||
add_module="--add-module=$nps_module_dir"
|
||||
fi
|
||||
configure_args=("$add_module" "${extra_flags[@]}")
|
||||
|
||||
if "$DEVEL"; then
|
||||
configure_args=("${configure_args[@]}"
|
||||
"--prefix=$install_dir/nginx"
|
||||
"--add-module=$submodules_dir/ngx_cache_purge"
|
||||
"--add-module=$submodules_dir/ngx_devel_kit"
|
||||
"--add-module=$submodules_dir/set-misc-nginx-module"
|
||||
"--add-module=$submodules_dir/headers-more-nginx-module"
|
||||
"--with-ipv6"
|
||||
"--with-http_v2_module")
|
||||
if [ "$BUILD_TYPE" = "Debug" ]; then
|
||||
configure_args=("${configure_args[@]}" "--with-debug")
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
if ! "$BUILD_NGINX"; then
|
||||
# Just prepare the module for them to install.
|
||||
status "ngx_pagespeed is ready to be built against nginx."
|
||||
echo "When running ./configure:"
|
||||
if "$PSOL_FROM_SOURCE"; then
|
||||
echo " Set the following environment variables:"
|
||||
echo " MOD_PAGESPEED_DIR=$MOD_PAGESPEED_DIR"
|
||||
echo " PSOL_BINARY=$PSOL_BINARY"
|
||||
fi
|
||||
echo " Give ./configure the following arguments:"
|
||||
echo " $(quote_arguments "${configure_args[@]}")"
|
||||
echo
|
||||
if [ ${#extra_flags[@]} -eq 0 ]; then
|
||||
echo "If this is for integration with an already-built nginx, make sure"
|
||||
echo "to include any other arguments you originally passed to"
|
||||
echo "./configure. You can see these with 'nginx -V'."
|
||||
else
|
||||
echo "Note: because we need to set $(quote_arguments "${extra_flags[@]}")"
|
||||
echo "on this platform, if you want to integrate ngx_pagespeed with an"
|
||||
echo "already-built nginx you're going to need to rebuild your nginx with"
|
||||
echo "those flags set."
|
||||
fi
|
||||
else
|
||||
if "$DEVEL"; then
|
||||
# Use the nginx we loaded as a submodule
|
||||
nginx_dir="$submodules_dir/nginx"
|
||||
configure_location="auto"
|
||||
else
|
||||
# Download and build the specified nginx version.
|
||||
nginx_leaf="nginx-${NGINX_VERSION}.tar.gz"
|
||||
nginx_fname="$TEMPDIR/$nginx_leaf"
|
||||
status "Downloading nginx..."
|
||||
run wget "http://nginx.org/download/$nginx_leaf" -O "$nginx_fname"
|
||||
nginx_dir="$BUILDDIR/nginx-${NGINX_VERSION}/"
|
||||
delete_if_already_exists "$nginx_dir"
|
||||
status "Extracting nginx..."
|
||||
run tar -xzf "$nginx_fname" --directory "$BUILDDIR"
|
||||
configure_location="."
|
||||
fi
|
||||
run cd "$nginx_dir"
|
||||
|
||||
configure=("$configure_location/configure" "${configure_args[@]}")
|
||||
if ! "$ASSUME_YES"; then
|
||||
echo "About to build nginx. Do you have any additional ./configure"
|
||||
echo "arguments you would like to set? For example, if you would like"
|
||||
echo "to build nginx with https support give --with-http_ssl_module"
|
||||
echo "If you don't have any, just press enter."
|
||||
read -p "> " additional_configure_args
|
||||
if [ -n "$additional_configure_args" ]; then
|
||||
# Split additional_configure_args respecting any internal quotation.
|
||||
# Otherwise things like --with-cc-opt='-foo -bar' won't work.
|
||||
eval additional_configure_args=("$additional_configure_args")
|
||||
configure=("${configure[@]}" "${additional_configure_args[@]}")
|
||||
fi
|
||||
fi
|
||||
echo "About to configure nginx with:"
|
||||
echo " $(quote_arguments "${configure[@]}")"
|
||||
continue_or_exit "Does this look right?"
|
||||
MOD_PAGESPEED_DIR="$MOD_PAGESPEED_DIR" \
|
||||
PSOL_BINARY="$PSOL_BINARY" \
|
||||
run "${configure[@]}"
|
||||
|
||||
if ! "$DEVEL"; then
|
||||
continue_or_exit "Build nginx?"
|
||||
fi
|
||||
run make
|
||||
|
||||
if "$DEVEL"; then
|
||||
run make install
|
||||
|
||||
status "Nginx installed with ngx_pagespeed, and set up for testing."
|
||||
# TODO(jefftk): pull these out into separate scripts.
|
||||
echo "To run tests, pick a pair of ports like 8050 and 8051 and run:"
|
||||
echo " cd $nps_module_dir"
|
||||
echo " RUN_TESTS=true \\"
|
||||
echo " USE_VALGRIND=false \\"
|
||||
echo " TEST_NATIVE_FETCHER=false \\"
|
||||
echo " TEST_SERF_FETCHER=true \\"
|
||||
echo " test/run_tests.sh \\"
|
||||
echo " $MOD_PAGESPEED_DIR \\"
|
||||
echo " $install_dir/nginx/sbin/nginx"
|
||||
echo
|
||||
echo "To rebuild after changes:"
|
||||
echo " First, if you change things in PSOL or update it:"
|
||||
echo " cd $MOD_PAGESPEED_DIR/devel"
|
||||
echo " make apache_debug_psol"
|
||||
echo " Then, whether or not you updated PSOL, rebuild nginx:"
|
||||
echo " cd $install_dir/nginx"
|
||||
echo " make && make install"
|
||||
else
|
||||
continue_or_exit "Install nginx?"
|
||||
run sudo make install
|
||||
|
||||
echo
|
||||
if "$DYNAMIC_MODULE"; then
|
||||
echo "Nginx installed with ngx_pagespeed support available as a"
|
||||
echo "loadable module."
|
||||
echo
|
||||
echo "To load the ngx_pagespeed module, you'll need to add:"
|
||||
echo " load_module \"modules/ngx_pagespeed.so\";"
|
||||
echo "at the top of your main nginx configuration file."
|
||||
else
|
||||
echo "Nginx installed with ngx_pagespeed support compiled-in."
|
||||
fi
|
||||
echo
|
||||
echo "If this is a new installation you probably need an init script to"
|
||||
echo "manage starting and stopping the nginx service. See:"
|
||||
echo " http://wiki.nginx.org/InitScripts"
|
||||
echo
|
||||
echo "You'll also need to configure ngx_pagespeed if you haven't yet:"
|
||||
echo " https://developers.google.com/speed/pagespeed/module/configuration"
|
||||
fi
|
||||
fi
|
||||
if "$DRYRUN"; then
|
||||
echo_color "$YELLOW" "[this was a dry run; your system is unchanged]"
|
||||
fi
|
||||
}
|
||||
|
||||
# Start running things from a call at the end so if this script is executed
|
||||
# after a partial download it doesn't do anything.
|
||||
build_ngx_pagespeed "$@"
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2016 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.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $(basename $0) <url_file>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
url_file=$1
|
||||
|
||||
if [ ! -e "$url_file" ]; then
|
||||
echo "Url file '$url_file' missing!" >&2
|
||||
fi
|
||||
|
||||
# The size names must match install/build_psol.sh in mod_pagespeed
|
||||
if [ "$(uname -m)" = x86_64 ]; then
|
||||
bit_size_name=x64
|
||||
else
|
||||
bit_size_name=ia32
|
||||
fi
|
||||
|
||||
sed -e 's/$BIT_SIZE_NAME\b/'$bit_size_name'/g' $url_file
|
||||
@@ -1,5 +1,19 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2013 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.
|
||||
#
|
||||
# Converts pagespeed_libraries.conf from Apache-format to Nginx-format,
|
||||
# supporting the canonicalize_javascript_libraries filter.
|
||||
# Inspired by https://github.com/pagespeed/ngx_pagespeed/issues/532
|
||||
@@ -13,9 +27,9 @@
|
||||
# Author: vid@zippykid.com (Vid Luther)
|
||||
# jefftk@google.com (Jeff Kaufman)
|
||||
|
||||
URL="https://modpagespeed.googlecode.com/svn/trunk/src/"
|
||||
URL="https://github.com/pagespeed/mod_pagespeed/raw/master/"
|
||||
URL+="net/instaweb/genfiles/conf/pagespeed_libraries.conf"
|
||||
curl -s "$URL" \
|
||||
curl -L -s -S "$URL" \
|
||||
| grep ModPagespeedLibrary \
|
||||
| while read library size hash url ; do
|
||||
echo " pagespeed Library $size $hash $url;"
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2012 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: jefftk@google.com (Jeff Kaufman)
|
||||
#
|
||||
# Usage:
|
||||
# scripts/prepare_psol.sh /path/to/mod_pagespeed/src
|
||||
#
|
||||
# Creates a directory psol/ and copies headers and a few source files from a
|
||||
# depot_tools (glient) checkout into psol/include. Along with creating
|
||||
# binaries, this is a step in preparing psol.tar.gz for distribution.
|
||||
#
|
||||
|
||||
set -u # check for undefined variables
|
||||
set -e # exit on failed commands
|
||||
|
||||
if [ "$(basename "$PWD")" != "ngx_pagespeed" ] ; then
|
||||
echo "$(basename $0) must be invoked from the ngx_pagespeed directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -ne 1 ] ; then
|
||||
echo "Usage: $(basename $0) /path/to/mod_pagespeed/src"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MOD_PAGESPEED_SRC="$1"
|
||||
|
||||
if [ "$(basename "$(dirname "$MOD_PAGESPEED_SRC")")/$( \
|
||||
basename "$MOD_PAGESPEED_SRC")" != "mod_pagespeed/src" ] ; then
|
||||
echo "Usage: $(basename $0) /path/to/mod_pagespeed/src"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e psol ] ; then
|
||||
echo "A psol/ directory already exists. Move it somewhere else and rerun."
|
||||
exit 1
|
||||
fi
|
||||
mkdir psol/
|
||||
# Copy over the .h files, plus a few selected .cc and .c files.
|
||||
rsync -arvz "$MOD_PAGESPEED_SRC/" "psol/include/" --prune-empty-dirs \
|
||||
--exclude=".svn" \
|
||||
--exclude=".git" \
|
||||
--include='*.h' \
|
||||
--include='*/' \
|
||||
--include="apr_thread_compatible_pool.cc" \
|
||||
--include="serf_url_async_fetcher.cc" \
|
||||
--include="apr_mem_cache.cc" \
|
||||
--include="key_value_codec.cc" \
|
||||
--include="apr_memcache2.c" \
|
||||
--include="loopback_route_fetcher.cc" \
|
||||
--include="add_headers_fetcher.cc" \
|
||||
--include="console_css_out.cc" \
|
||||
--include="console_out.cc" \
|
||||
--include="dense_hash_map" \
|
||||
--include="dense_hash_set" \
|
||||
--include="sparse_hash_map" \
|
||||
--include="sparse_hash_set" \
|
||||
--include="sparsetable" \
|
||||
--include="mod_pagespeed_console_out.cc" \
|
||||
--include="mod_pagespeed_console_css_out.cc" \
|
||||
--include="mod_pagespeed_console_html_out.cc" \
|
||||
--exclude='*'
|
||||
mkdir -p psol/lib/Debug/linux/ia32
|
||||
mkdir -p psol/lib/Debug/linux/x64
|
||||
mkdir -p psol/lib/Release/linux/ia32
|
||||
mkdir -p psol/lib/Release/linux/x64
|
||||
|
||||
# Log that we did this.
|
||||
SVN_REVISION="$(svn info $MOD_PAGESPEED_SRC | grep Revision | awk '{print $2}')"
|
||||
SVN_TAG="$(svn info $MOD_PAGESPEED_SRC | grep URL | awk -F/ '{print $(NF-1)}')"
|
||||
|
||||
DATE="$(date +%F)"
|
||||
echo "${DATE}: Copied from mod_pagespeed ${SVN_TAG}@r${SVN_REVISION} ($USER)" \
|
||||
>> psol/include_history.txt
|
||||
|
||||
echo
|
||||
echo "Output is in psol/include. Now put binaries in psol/lib following"
|
||||
echo "https://github.com/pagespeed/ngx_pagespeed/wiki/Building-Release-Binaries"
|
||||
echo "and then you can distribute PSOL."
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
ngx_log_t* log = NULL;
|
||||
ngx_log_t* ngx_log = NULL;
|
||||
|
||||
ngx_uint_t GetNgxLogLevel(int severity) {
|
||||
switch (severity) {
|
||||
@@ -78,7 +78,7 @@ bool LogMessageHandler(int severity, const char* file, int line,
|
||||
message.resize(last_msg_character_index);
|
||||
}
|
||||
|
||||
ngx_log_error(this_log_level, log, 0, "[ngx_pagespeed %s] %s",
|
||||
ngx_log_error(this_log_level, ngx_log, 0, "[ngx_pagespeed %s] %s",
|
||||
net_instaweb::kModPagespeedVersion,
|
||||
message.c_str());
|
||||
|
||||
@@ -99,12 +99,12 @@ namespace log_message_handler {
|
||||
|
||||
|
||||
void Install(ngx_log_t* log_in) {
|
||||
log = log_in;
|
||||
ngx_log = log_in;
|
||||
logging::SetLogMessageHandler(&LogMessageHandler);
|
||||
|
||||
// All VLOG(2) and higher will be displayed as DEBUG logs if the nginx log
|
||||
// level is DEBUG.
|
||||
if (log->log_level >= NGX_LOG_DEBUG) {
|
||||
if (ngx_log->log_level >= NGX_LOG_DEBUG) {
|
||||
logging::SetMinLogLevel(-2);
|
||||
}
|
||||
}
|
||||
|
||||
+66
-12
@@ -12,17 +12,20 @@
|
||||
* 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: jefftk@google.com (Jeff Kaufman)
|
||||
*/
|
||||
|
||||
// Author: jefftk@google.com (Jeff Kaufman)
|
||||
#include "ngx_pagespeed.h" // Must come first, see comments in CollectHeaders.
|
||||
|
||||
#include <unistd.h> //for usleep
|
||||
|
||||
#include "ngx_base_fetch.h"
|
||||
#include "ngx_event_connection.h"
|
||||
#include "ngx_list_iterator.h"
|
||||
|
||||
#include "ngx_pagespeed.h"
|
||||
|
||||
#include "net/instaweb/rewriter/public/rewrite_driver.h"
|
||||
#include "net/instaweb/rewriter/public/rewrite_options.h"
|
||||
#include "net/instaweb/rewriter/public/rewrite_stats.h"
|
||||
#include "pagespeed/kernel/base/google_message_handler.h"
|
||||
#include "pagespeed/kernel/base/message_handler.h"
|
||||
@@ -38,14 +41,19 @@ const char kDone = 'D';
|
||||
NgxEventConnection* NgxBaseFetch::event_connection = NULL;
|
||||
int NgxBaseFetch::active_base_fetches = 0;
|
||||
|
||||
NgxBaseFetch::NgxBaseFetch(ngx_http_request_t* r,
|
||||
NgxBaseFetch::NgxBaseFetch(StringPiece url,
|
||||
ngx_http_request_t* r,
|
||||
NgxServerContext* server_context,
|
||||
const RequestContextPtr& request_ctx,
|
||||
PreserveCachingHeaders preserve_caching_headers,
|
||||
NgxBaseFetchType base_fetch_type)
|
||||
NgxBaseFetchType base_fetch_type,
|
||||
const RewriteOptions* options)
|
||||
: AsyncFetch(request_ctx),
|
||||
url_(url.data(), url.size()),
|
||||
request_(r),
|
||||
server_context_(server_context),
|
||||
options_(options),
|
||||
need_flush_(false),
|
||||
done_called_(false),
|
||||
last_buf_sent_(false),
|
||||
references_(2),
|
||||
@@ -111,11 +119,15 @@ const char* BaseFetchTypeToCStr(NgxBaseFetchType type) {
|
||||
return "admin page";
|
||||
case kIproLookup:
|
||||
return "ipro lookup";
|
||||
case kPageSpeedProxy:
|
||||
return "pagespeed proxy";
|
||||
}
|
||||
CHECK(false);
|
||||
return "can't get here";
|
||||
}
|
||||
|
||||
// TODO(oschaaf): replace the ngx_log_error with VLOGS or pass in a
|
||||
// MessageHandler and use that.
|
||||
void NgxBaseFetch::ReadCallback(const ps_event_data& data) {
|
||||
NgxBaseFetch* base_fetch = reinterpret_cast<NgxBaseFetch*>(data.sender);
|
||||
ngx_http_request_t* r = base_fetch->request();
|
||||
@@ -136,19 +148,40 @@ void NgxBaseFetch::ReadCallback(const ps_event_data& data) {
|
||||
if (refcount == 0 || detached) {
|
||||
return;
|
||||
}
|
||||
|
||||
ps_request_ctx_t* ctx = ps_get_request_context(r);
|
||||
|
||||
CHECK(data.sender == ctx->base_fetch);
|
||||
CHECK(r->count > 0) << "r->count: " << r->count;
|
||||
// If our request context was zeroed, skip this event.
|
||||
// See https://github.com/pagespeed/ngx_pagespeed/issues/1081
|
||||
if (ctx == NULL) {
|
||||
// Should not happen normally, when it does this message will cause our
|
||||
// system tests to fail.
|
||||
ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0,
|
||||
"pagespeed [%p] skipping event: request context gone", r);
|
||||
return;
|
||||
}
|
||||
|
||||
// Normally we expect the sender to equal the active NgxBaseFetch instance.
|
||||
DCHECK(data.sender == ctx->base_fetch);
|
||||
|
||||
// If someone changed our request context or NgxBaseFetch, skip processing.
|
||||
if (data.sender != ctx->base_fetch) {
|
||||
ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0,
|
||||
"pagespeed [%p] skipping event: event originating from disassociated"
|
||||
" NgxBaseFetch instance.", r);
|
||||
return;
|
||||
}
|
||||
|
||||
int rc;
|
||||
bool run_posted = true;
|
||||
// If we are unlucky enough to have our connection finalized mid-ipro-lookup,
|
||||
// we must enter a different flow. Also see ps_in_place_check_header_filter().
|
||||
if ((ctx->base_fetch->base_fetch_type_ != kIproLookup)
|
||||
&& r->connection->error) {
|
||||
ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
|
||||
"pagespeed [%p] request already finalized", r);
|
||||
"pagespeed [%p] request already finalized %d", r, r->count);
|
||||
rc = NGX_ERROR;
|
||||
run_posted = false;
|
||||
} else {
|
||||
rc = ps_base_fetch::ps_base_fetch_handler(r);
|
||||
}
|
||||
@@ -161,8 +194,11 @@ void NgxBaseFetch::ReadCallback(const ps_event_data& data) {
|
||||
|
||||
ngx_connection_t* c = r->connection;
|
||||
ngx_http_finalize_request(r, rc);
|
||||
// See http://forum.nginx.org/read.php?2,253006,253061
|
||||
ngx_http_run_posted_requests(c);
|
||||
|
||||
if (run_posted) {
|
||||
// See http://forum.nginx.org/read.php?2,253006,253061
|
||||
ngx_http_run_posted_requests(c);
|
||||
}
|
||||
}
|
||||
|
||||
void NgxBaseFetch::Lock() {
|
||||
@@ -192,8 +228,11 @@ ngx_int_t NgxBaseFetch::CopyBufferToNginx(ngx_chain_t** link_ptr) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
int rc = string_piece_to_buffer_chain(
|
||||
request_->pool, buffer_, link_ptr, done_called_ /* send_last_buf */);
|
||||
int rc = string_piece_to_buffer_chain(request_->pool, buffer_, link_ptr,
|
||||
done_called_ /* send_last_buf */,
|
||||
need_flush_);
|
||||
need_flush_ = false;
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
@@ -221,6 +260,13 @@ ngx_int_t NgxBaseFetch::CollectAccumulatedWrites(ngx_chain_t** link_ptr) {
|
||||
}
|
||||
|
||||
ngx_int_t NgxBaseFetch::CollectHeaders(ngx_http_headers_out_t* headers_out) {
|
||||
// nginx defines _FILE_OFFSET_BITS to 64, which changes the size of off_t.
|
||||
// If a standard header is accidentally included before the nginx header,
|
||||
// on a 32-bit system off_t will be 4 bytes and we don't assign all the
|
||||
// bits of content_length_n. Sanity check that did not happen.
|
||||
// This could use static_assert, but this file is not built with --std=c++11.
|
||||
bool sanity_check_off_t[sizeof(off_t) == 8 ? 1 : -1] __attribute__ ((unused));
|
||||
|
||||
const ResponseHeaders* pagespeed_headers = response_headers();
|
||||
|
||||
if (content_length_known()) {
|
||||
@@ -271,6 +317,9 @@ void NgxBaseFetch::HandleHeadersComplete() {
|
||||
}
|
||||
|
||||
bool NgxBaseFetch::HandleFlush(MessageHandler* handler) {
|
||||
Lock();
|
||||
need_flush_ = true;
|
||||
Unlock();
|
||||
RequestCollection(kFlush); // A new part of the response body is available
|
||||
return true;
|
||||
}
|
||||
@@ -303,4 +352,9 @@ void NgxBaseFetch::HandleDone(bool success) {
|
||||
DecrefAndDeleteIfUnreferenced();
|
||||
}
|
||||
|
||||
bool NgxBaseFetch::IsCachedResultValid(const ResponseHeaders& headers) {
|
||||
return OptionsAwareHTTPCacheCallback::IsCacheValid(
|
||||
url_, *options_, request_context(), headers);
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
+16
-4
@@ -43,6 +43,9 @@
|
||||
// events it handles.
|
||||
//
|
||||
// When the last reference is dropped, this class will delete itself.
|
||||
//
|
||||
// TODO(jmarantz): consider sharing the cache-invalidation infrastructure
|
||||
// with ApacheFetch, using a common base class.
|
||||
|
||||
#ifndef NGX_BASE_FETCH_H_
|
||||
#define NGX_BASE_FETCH_H_
|
||||
@@ -59,6 +62,7 @@ extern "C" {
|
||||
#include "ngx_server_context.h"
|
||||
|
||||
#include "net/instaweb/http/public/async_fetch.h"
|
||||
#include "net/instaweb/rewriter/public/rewrite_options.h"
|
||||
#include "pagespeed/kernel/base/string.h"
|
||||
#include "pagespeed/kernel/http/headers.h"
|
||||
|
||||
@@ -68,15 +72,18 @@ enum NgxBaseFetchType {
|
||||
kIproLookup,
|
||||
kHtmlTransform,
|
||||
kPageSpeedResource,
|
||||
kAdminPage
|
||||
kAdminPage,
|
||||
kPageSpeedProxy
|
||||
};
|
||||
|
||||
class NgxBaseFetch : public AsyncFetch {
|
||||
public:
|
||||
NgxBaseFetch(ngx_http_request_t* r, NgxServerContext* server_context,
|
||||
NgxBaseFetch(StringPiece url, ngx_http_request_t* r,
|
||||
NgxServerContext* server_context,
|
||||
const RequestContextPtr& request_ctx,
|
||||
PreserveCachingHeaders preserve_caching_headers,
|
||||
NgxBaseFetchType base_fetch_type);
|
||||
NgxBaseFetchType base_fetch_type,
|
||||
const RewriteOptions* options);
|
||||
virtual ~NgxBaseFetch();
|
||||
|
||||
// Statically initializes event_connection, require for PSOL and nginx to
|
||||
@@ -124,6 +131,8 @@ class NgxBaseFetch : public AsyncFetch {
|
||||
ngx_http_request_t* request() { return request_; }
|
||||
NgxBaseFetchType base_fetch_type() { return base_fetch_type_; }
|
||||
|
||||
bool IsCachedResultValid(const ResponseHeaders& headers) override;
|
||||
|
||||
private:
|
||||
virtual bool HandleWrite(const StringPiece& sp, MessageHandler* handler);
|
||||
virtual bool HandleFlush(MessageHandler* handler);
|
||||
@@ -151,13 +160,16 @@ class NgxBaseFetch : public AsyncFetch {
|
||||
int DecrefAndDeleteIfUnreferenced();
|
||||
|
||||
static NgxEventConnection* event_connection;
|
||||
|
||||
|
||||
// Live count of NgxBaseFetch instances that are currently in use.
|
||||
static int active_base_fetches;
|
||||
|
||||
GoogleString url_;
|
||||
ngx_http_request_t* request_;
|
||||
GoogleString buffer_;
|
||||
NgxServerContext* server_context_;
|
||||
const RewriteOptions* options_;
|
||||
bool need_flush_;
|
||||
bool done_called_;
|
||||
bool last_buf_sent_;
|
||||
// How many active references there are to this fetch. Starts at two,
|
||||
|
||||
+5
-3
@@ -315,7 +315,9 @@ bool NgxFetch::Init() {
|
||||
}
|
||||
|
||||
if (!ParseUrl()) {
|
||||
message_handler_->Message(kError, "NgxFetch: ParseUrl() failed");
|
||||
message_handler_->Message(kError,
|
||||
"NgxFetch: ParseUrl() failed for [%s]:%s",
|
||||
str_url_.c_str(), url_.err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -938,8 +940,8 @@ void NgxFetch::FixUserAgent() {
|
||||
user_agent += "NgxNativeFetcher";
|
||||
}
|
||||
GoogleString version = StrCat(
|
||||
" ", kModPagespeedSubrequestUserAgent,
|
||||
"/" MOD_PAGESPEED_VERSION_STRING "-" LASTCHANGE_STRING);
|
||||
" (", kModPagespeedSubrequestUserAgent,
|
||||
"/" MOD_PAGESPEED_VERSION_STRING "-" LASTCHANGE_STRING ")");
|
||||
if (!StringPiece(user_agent).ends_with(version)) {
|
||||
user_agent += version;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,6 @@ void NgxMessageHandler::MessageSImpl(MessageType type,
|
||||
} else {
|
||||
GoogleMessageHandler::MessageSImpl(type, message);
|
||||
}
|
||||
// Prepare a log message for the SharedCircularBuffer only.
|
||||
AddMessageToBuffer(type, message);
|
||||
}
|
||||
|
||||
@@ -111,6 +110,7 @@ void NgxMessageHandler::FileMessageSImpl(
|
||||
} else {
|
||||
GoogleMessageHandler::FileMessageSImpl(type, file, line, message);
|
||||
}
|
||||
AddMessageToBuffer(type, file, line, message);
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
+249
-88
@@ -124,7 +124,7 @@ char* string_piece_to_pool_string(ngx_pool_t* pool, StringPiece sp) {
|
||||
// (potentially) longer string to nginx and want it to take ownership.
|
||||
ngx_int_t string_piece_to_buffer_chain(
|
||||
ngx_pool_t* pool, StringPiece sp, ngx_chain_t** link_ptr,
|
||||
bool send_last_buf) {
|
||||
bool send_last_buf, bool send_flush) {
|
||||
// Below, *link_ptr will be NULL if we're starting the chain, and the head
|
||||
// chain link.
|
||||
*link_ptr = NULL;
|
||||
@@ -198,6 +198,9 @@ ngx_int_t string_piece_to_buffer_chain(
|
||||
|
||||
|
||||
CHECK(tail_link != NULL);
|
||||
if (send_flush) {
|
||||
tail_link->buf->flush = true;
|
||||
}
|
||||
if (send_last_buf) {
|
||||
tail_link->buf->last_buf = true;
|
||||
}
|
||||
@@ -284,7 +287,9 @@ ngx_int_t ps_base_fetch_handler(ngx_http_request_t* r) {
|
||||
// modules running after us to manipulate those responses.
|
||||
if (!status_ok && (ctx->base_fetch->base_fetch_type() != kHtmlTransform
|
||||
&& ctx->base_fetch->base_fetch_type() != kIproLookup)) {
|
||||
return status_code;
|
||||
ps_release_base_fetch(ctx);
|
||||
ngx_http_filter_finalize_request(r, NULL, status_code);
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (ctx->preserve_caching_headers != kDontPreserveHeaders) {
|
||||
@@ -302,6 +307,12 @@ ngx_int_t ps_base_fetch_handler(ngx_http_request_t* r) {
|
||||
STR_CASE_EQ_LITERAL(header->key, "Last-Modified") ||
|
||||
STR_CASE_EQ_LITERAL(header->key, "Expires"))))) {
|
||||
header->hash = 0;
|
||||
if (STR_CASE_EQ_LITERAL(header->key, "Location")) {
|
||||
// There's a possible issue with the location header, where setting
|
||||
// the hash to 0 is not enough. See:
|
||||
// https://github.com/nginx/nginx/blob/master/src/http/ngx_http_header_filter_module.c#L314
|
||||
r->headers_out.location = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -415,6 +426,32 @@ ngx_int_t ps_set_cache_control(ngx_http_request_t* r, char* cache_control) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
// Returns false if the header wasn't found. Otherwise sets cache_control and
|
||||
// returns true;
|
||||
bool ps_get_cache_control(ngx_http_request_t* r, GoogleString* cache_control) {
|
||||
// Use headers_out.cache_control instead of looking for Cache-Control in
|
||||
// headers_out.headers, because if an upstream sent multiple Cache-Control
|
||||
// headers they're already combined in headers_out.cache_control.
|
||||
auto ccp = static_cast<ngx_table_elt_t**>(r->headers_out.cache_control.elts);
|
||||
if (ccp == nullptr) {
|
||||
return false; // Header not present.
|
||||
}
|
||||
bool first_segment = true;
|
||||
for (ngx_uint_t i = 0; i < r->headers_out.cache_control.nelts; i++) {
|
||||
if (ccp[i]->hash == 0) {
|
||||
continue; // Elements with a hash of 0 are marked as excluded.
|
||||
}
|
||||
if (first_segment) {
|
||||
first_segment = false;
|
||||
} else {
|
||||
cache_control->append(", ");
|
||||
}
|
||||
cache_control->append(reinterpret_cast<char*>(ccp[i]->value.data),
|
||||
ccp[i]->value.len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Headers>
|
||||
void copy_headers_from_table(const ngx_list_t &from, Headers* to) {
|
||||
// Standard nginx idiom for iterating over a list. See ngx_list.h
|
||||
@@ -452,11 +489,6 @@ void copy_response_headers_from_ngx(const ngx_http_request_t* r,
|
||||
|
||||
headers->set_status_code(r->headers_out.status);
|
||||
|
||||
if (r->headers_out.location != NULL) {
|
||||
headers->Add(HttpAttributes::kLocation,
|
||||
str_to_string_piece(r->headers_out.location->value));
|
||||
}
|
||||
|
||||
// Manually copy over the content type because it's not included in
|
||||
// request_->headers_out.headers.
|
||||
headers->Add(HttpAttributes::kContentType,
|
||||
@@ -464,7 +496,8 @@ void copy_response_headers_from_ngx(const ngx_http_request_t* r,
|
||||
|
||||
// When we don't have a date header, set one with the current time.
|
||||
if (headers->Lookup1(HttpAttributes::kDate) == NULL) {
|
||||
headers->SetDate(ngx_current_msec);
|
||||
PosixTimer timer;
|
||||
headers->SetDate(timer.NowMs());
|
||||
}
|
||||
|
||||
// TODO(oschaaf): ComputeCaching should be called in setupforhtml()?
|
||||
@@ -490,6 +523,10 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
|
||||
ngx_int_t i;
|
||||
for (i = 0 ; i < pagespeed_headers.NumAttributes() ; i++) {
|
||||
// For IPRO cache misses, these gs_ variables may point to freed memory
|
||||
// when nginx writes the headers to the output as the NgxBaseFetch instance
|
||||
// that owns this memory gets released during request processing. So we
|
||||
// copy these strings later on.
|
||||
const GoogleString& name_gs = pagespeed_headers.Name(i);
|
||||
const GoogleString& value_gs = pagespeed_headers.Value(i);
|
||||
|
||||
@@ -510,6 +547,9 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
} // else we don't preserve any headers.
|
||||
|
||||
ngx_str_t name, value;
|
||||
value.len = value_gs.size();
|
||||
value.data = reinterpret_cast<u_char*>(
|
||||
string_piece_to_pool_string(r->pool, value_gs.c_str()));
|
||||
|
||||
// To prevent the gzip module from clearing weak etags, we output them
|
||||
// using a different name here. The etag header filter module runs behind
|
||||
@@ -520,11 +560,15 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
name.data = reinterpret_cast<u_char*>(
|
||||
const_cast<char*>(kInternalEtagName));
|
||||
} else {
|
||||
name.len = name_gs.length();
|
||||
name.data = reinterpret_cast<u_char*>(const_cast<char*>(name_gs.data()));
|
||||
name.len = name_gs.size();
|
||||
name.data = reinterpret_cast<u_char*>(
|
||||
string_piece_to_pool_string(r->pool, name_gs.c_str()));
|
||||
}
|
||||
|
||||
// In case string_piece_to_pool_string failed:
|
||||
if (name.data == NULL || value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
value.len = value_gs.length();
|
||||
value.data = reinterpret_cast<u_char*>(const_cast<char*>(value_gs.data()));
|
||||
|
||||
// TODO(jefftk): If we're setting a cache control header we'd like to
|
||||
// prevent any downstream code from changing it. Specifically, if we're
|
||||
@@ -535,24 +579,17 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
// net/instaweb/apache/header_util:AddResponseHeadersToRequest
|
||||
|
||||
// Make copies of name and value to put into headers_out.
|
||||
|
||||
u_char* value_s = ngx_pstrdup(r->pool, &value);
|
||||
if (value_s == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (STR_EQ_LITERAL(name, "Cache-Control")) {
|
||||
ps_set_cache_control(r, const_cast<char*>(value_gs.c_str()));
|
||||
ps_set_cache_control(r, reinterpret_cast<char*>(value.data));
|
||||
continue;
|
||||
} else if (STR_EQ_LITERAL(name, "Content-Type")) {
|
||||
// Unlike all the other headers, content_type is just a string.
|
||||
headers_out->content_type.data = value_s;
|
||||
headers_out->content_type.len = value.len;
|
||||
headers_out->content_type = value;
|
||||
|
||||
// We should not include the charset when determining content_type_len, so
|
||||
// scan for the ';' that marks the start of the charset part.
|
||||
for (ngx_uint_t i = 0; i < value.len; i++) {
|
||||
if (value_s[i] == ';') {
|
||||
if (value.data[i] == ';') {
|
||||
break;
|
||||
}
|
||||
headers_out->content_type_len = i + 1;
|
||||
@@ -570,11 +607,10 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
continue;
|
||||
} else if (STR_EQ_LITERAL(name, "Transfer-Encoding")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
u_char* name_s = ngx_pstrdup(r->pool, &name);
|
||||
if (name_s == NULL) {
|
||||
return NGX_ERROR;
|
||||
} else if (STR_EQ_LITERAL(name, "Vary") && value.len
|
||||
&& STR_EQ_LITERAL(value, "Accept-Encoding")) {
|
||||
ps_request_ctx_t* ctx = ps_get_request_context(r);
|
||||
ctx->psol_vary_accept_only = true;
|
||||
}
|
||||
|
||||
ngx_table_elt_t* header = static_cast<ngx_table_elt_t*>(
|
||||
@@ -584,10 +620,10 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
}
|
||||
|
||||
header->hash = 1; // Include this header in the output.
|
||||
header->key.data = name.data;
|
||||
header->key.len = name.len;
|
||||
header->key.data = name_s;
|
||||
header->value.data = value.data;
|
||||
header->value.len = value.len;
|
||||
header->value.data = value_s;
|
||||
|
||||
// Populate the shortcuts to commonly used headers.
|
||||
if (STR_EQ_LITERAL(name, "Date")) {
|
||||
@@ -599,7 +635,10 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
} else if (STR_EQ_LITERAL(name, "Last-Modified")) {
|
||||
headers_out->last_modified = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Location")) {
|
||||
headers_out->location = header;
|
||||
ps_request_ctx_t* ctx = ps_get_request_context(r);
|
||||
if (ctx->location_field_set) {
|
||||
headers_out->location = header;
|
||||
}
|
||||
} else if (STR_EQ_LITERAL(name, "Server")) {
|
||||
headers_out->server = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Content-Length")) {
|
||||
@@ -607,6 +646,16 @@ ngx_int_t copy_response_headers_to_ngx(
|
||||
CHECK(pagespeed_headers.FindContentLength(&len));
|
||||
headers_out->content_length_n = len;
|
||||
headers_out->content_length = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Content-Encoding")) {
|
||||
headers_out->content_encoding = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Refresh")) {
|
||||
headers_out->refresh = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Content-Range")) {
|
||||
headers_out->content_range = header;
|
||||
} else if (STR_EQ_LITERAL(name, "Accept-Ranges")) {
|
||||
headers_out->accept_ranges = header;
|
||||
} else if (STR_EQ_LITERAL(name, "WWW-Authenticate")) {
|
||||
headers_out->www_authenticate = header;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,7 +672,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
// If pagespeed is configured in some server block but not this one our
|
||||
// per-request code will be invoked but server context will be null. In those
|
||||
// cases we neet to short circuit, not changing anything. Currently our
|
||||
// cases we need to short circuit, not changing anything. Currently our
|
||||
// header filter, body filter, and content handler all do this, but if anyone
|
||||
// adds another way for nginx to give us a request to process we need to check
|
||||
// there as well.
|
||||
@@ -664,6 +713,13 @@ char* ps_main_configure(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
|
||||
char* ps_srv_configure(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
|
||||
char* ps_loc_configure(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
|
||||
|
||||
// We want NGX_CONF_MULTI for some very old versions:
|
||||
// https://github.com/pagespeed/ngx_pagespeed/commit/66f1b9aa
|
||||
// but it's gone in recent revisions, so provide a compat #define if needed
|
||||
#ifndef NGX_CONF_MULTI
|
||||
#define NGX_CONF_MULTI 0
|
||||
#endif
|
||||
|
||||
// TODO(jud): Verify that all the offsets should be NGX_HTTP_SRV_CONF_OFFSET and
|
||||
// not NGX_HTTP_LOC_CONF_OFFSET or NGX_HTTP_MAIN_CONF_OFFSET.
|
||||
ngx_command_t ps_commands[] = {
|
||||
@@ -829,14 +885,14 @@ char* ps_configure(ngx_conf_t* cf,
|
||||
cfg_m->driver_factory->thread_system());
|
||||
}
|
||||
|
||||
bool process_script_variables = dynamic_cast<NgxRewriteDriverFactory*>(
|
||||
cfg_m->driver_factory)->process_script_variables();
|
||||
|
||||
if (process_script_variables) {
|
||||
ProcessScriptVariablesMode script_mode =
|
||||
dynamic_cast<NgxRewriteDriverFactory*>(cfg_m->driver_factory)
|
||||
->process_script_variables();
|
||||
if (script_mode != ProcessScriptVariablesMode::kOff) {
|
||||
// To be able to use '$', we map '$ps_dollar' to '$' via a script variable.
|
||||
ngx_str_t name = ngx_string("ps_dollar");
|
||||
ngx_http_variable_t* var = ngx_http_add_variable(
|
||||
cf, &name, NGX_HTTP_VAR_CHANGEABLE);
|
||||
ngx_http_variable_t* var =
|
||||
ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
|
||||
|
||||
if (var == NULL) {
|
||||
return const_cast<char*>(
|
||||
@@ -847,7 +903,7 @@ char* ps_configure(ngx_conf_t* cf,
|
||||
|
||||
const char* status = (*options)->ParseAndSetOptions(
|
||||
args, n_args, cf->pool, handler, cfg_m->driver_factory, option_scope, cf,
|
||||
process_script_variables);
|
||||
script_mode);
|
||||
|
||||
// nginx expects us to return a string literal but doesn't mark it const.
|
||||
return const_cast<char*>(status);
|
||||
@@ -973,6 +1029,7 @@ void* ps_create_main_conf(ngx_conf_t* cf) {
|
||||
"" /* hostname, not used */,
|
||||
-1 /* port, not used */);
|
||||
active_driver_factory = cfg_m->driver_factory;
|
||||
active_driver_factory->LoggingInit(ngx_cycle->log, false);
|
||||
cfg_m->driver_factory->Init();
|
||||
ps_set_conf_cleanup_handler(cf, ps_cleanup_main_conf, cfg_m);
|
||||
return cfg_m;
|
||||
@@ -1067,9 +1124,20 @@ char* ps_merge_srv_conf(ngx_conf_t* cf, void* parent, void* child) {
|
||||
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_conf_get_module_main_conf(cf, ngx_pagespeed));
|
||||
cfg_m->driver_factory->set_main_conf(parent_cfg_s->options);
|
||||
cfg_m->driver_factory->SetMainConf(parent_cfg_s->options);
|
||||
cfg_s->server_context = cfg_m->driver_factory->MakeNgxServerContext(
|
||||
"dummy_hostname", dummy_port);
|
||||
|
||||
#if (NGX_HTTP_V2)
|
||||
// Save the variable index of the "http2" variable, so we can use it
|
||||
// at request time to lookup whether that's on. We do this conditionally
|
||||
// since NGINX will complain to the user (at [emerg] level!) if it doesn't
|
||||
// know about it.
|
||||
ngx_str_t name = ngx_string("http2");
|
||||
cfg_s->server_context->set_ngx_http2_variable_index(
|
||||
ngx_http_get_variable_index(cf, &name));
|
||||
#endif
|
||||
|
||||
// The server context sets some options when we call global_options(). So
|
||||
// let it do that, then merge in options we got from the config file.
|
||||
// Once we do that we're done with cfg_s->options.
|
||||
@@ -1254,6 +1322,8 @@ ngx_int_t ps_decline_request(ngx_http_request_t* r) {
|
||||
|
||||
ctx->driver->Cleanup();
|
||||
ctx->driver = NULL;
|
||||
ctx->location_field_set = false;
|
||||
ctx->psol_vary_accept_only = false;
|
||||
|
||||
// re init ctx
|
||||
ctx->html_rewrite = true;
|
||||
@@ -1263,6 +1333,9 @@ ngx_int_t ps_decline_request(ngx_http_request_t* r) {
|
||||
|
||||
r->count++;
|
||||
r->phase_handler++;
|
||||
|
||||
//restore read_event_handler to what it was in ps_async_wait_response
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
ngx_http_core_run_phases(r);
|
||||
ngx_http_run_posted_requests(r->connection);
|
||||
@@ -1274,6 +1347,13 @@ ngx_int_t ps_async_wait_response(ngx_http_request_t* r) {
|
||||
CHECK(ctx != NULL);
|
||||
|
||||
r->count++;
|
||||
// While we wait for PSOL to complete an async operation, there is a chance
|
||||
// that the underlying connection gets closed, or a http/2 RST_STREAM is
|
||||
// received before the async operation completes. In that case we don't want
|
||||
// to continue processing this flow. So we override the requests's read event
|
||||
// handler with one that will make nginx abort request processing and execute
|
||||
// our cleanup handlers instead of resuming request processing.
|
||||
r->read_event_handler = ngx_http_test_reading;
|
||||
r->write_event_handler = ngx_http_request_empty_handler;
|
||||
ps_set_buffered(r, true);
|
||||
// We don't need to add a timer here, as it will be set by nginx.
|
||||
@@ -1560,10 +1640,12 @@ void ps_release_base_fetch(ps_request_ctx_t* ctx) {
|
||||
}
|
||||
|
||||
// TODO(chaizhenhua): merge into NgxBaseFetch ctor
|
||||
void ps_create_base_fetch(ps_request_ctx_t* ctx,
|
||||
RequestContextPtr request_context,
|
||||
RequestHeaders* request_headers,
|
||||
NgxBaseFetchType type) {
|
||||
void ps_create_base_fetch(StringPiece url,
|
||||
ps_request_ctx_t* ctx,
|
||||
RequestContextPtr request_context,
|
||||
RequestHeaders* request_headers,
|
||||
NgxBaseFetchType type,
|
||||
const RewriteOptions* options) {
|
||||
CHECK(ctx->base_fetch == NULL) << "Pre-existing base fetch!";
|
||||
|
||||
ngx_http_request_t* r = ctx->r;
|
||||
@@ -1573,9 +1655,9 @@ void ps_create_base_fetch(ps_request_ctx_t* ctx,
|
||||
// it, and call Done() on the associated parent (Proxy or Resource) fetch. If
|
||||
// we fail before creating the associated fetch then we need to call Done() on
|
||||
// the BaseFetch ourselves.
|
||||
ctx->base_fetch = new NgxBaseFetch(r, cfg_s->server_context,
|
||||
request_context,
|
||||
ctx->preserve_caching_headers, type);
|
||||
ctx->base_fetch = new NgxBaseFetch(url, r, cfg_s->server_context, request_context,
|
||||
ctx->preserve_caching_headers, type,
|
||||
options);
|
||||
ctx->base_fetch->SetRequestHeadersTakingOwnership(request_headers);
|
||||
}
|
||||
|
||||
@@ -1650,23 +1732,29 @@ RequestRouting::Response ps_route_request(ngx_http_request_t* r) {
|
||||
const NgxRewriteOptions* global_options = cfg_s->server_context->config();
|
||||
|
||||
StringPiece path = url.PathSansQuery();
|
||||
if (StringCaseEqual(path, global_options->statistics_path())) {
|
||||
if (StringCaseEqual(path, global_options->statistics_path()) &&
|
||||
global_options->StatisticsAccessAllowed(url)) {
|
||||
return RequestRouting::kStatistics;
|
||||
} else if (StringCaseEqual(path, global_options->global_statistics_path())) {
|
||||
} else if (StringCaseEqual(path, global_options->global_statistics_path()) &&
|
||||
global_options->GlobalStatisticsAccessAllowed(url)) {
|
||||
return RequestRouting::kGlobalStatistics;
|
||||
} else if (StringCaseEqual(path, global_options->console_path())) {
|
||||
} else if (StringCaseEqual(path, global_options->console_path()) &&
|
||||
global_options->ConsoleAccessAllowed(url)) {
|
||||
return RequestRouting::kConsole;
|
||||
} else if (StringCaseEqual(path, global_options->messages_path())) {
|
||||
} else if (StringCaseEqual(path, global_options->messages_path()) &&
|
||||
global_options->MessagesAccessAllowed(url)) {
|
||||
return RequestRouting::kMessages;
|
||||
} else if (
|
||||
// The admin handlers get everything under a path (/path/*) while all the
|
||||
// other handlers only get exact matches (/path). So match all paths
|
||||
// starting with the handler path.
|
||||
!global_options->admin_path().empty() &&
|
||||
StringCaseStartsWith(path, global_options->admin_path())) {
|
||||
StringCaseStartsWith(path, global_options->admin_path()) &&
|
||||
global_options->AdminAccessAllowed(url)) {
|
||||
return RequestRouting::kAdmin;
|
||||
} else if (!global_options->global_admin_path().empty() &&
|
||||
StringCaseStartsWith(path, global_options->global_admin_path())) {
|
||||
StringCaseStartsWith(path, global_options->global_admin_path()) &&
|
||||
global_options->GlobalAdminAccessAllowed(url)) {
|
||||
return RequestRouting::kGlobalAdmin;
|
||||
} else if (global_options->enable_cache_purge() &&
|
||||
!global_options->purge_method().empty() &&
|
||||
@@ -1791,6 +1879,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
ctx->r = r;
|
||||
ctx->html_rewrite = false;
|
||||
ctx->in_place = false;
|
||||
ctx->follow_flushes = options->follow_flushes();
|
||||
ctx->preserve_caching_headers = kDontPreserveHeaders;
|
||||
|
||||
// See build_context_for_request() in mod_instaweb.cc
|
||||
@@ -1817,6 +1906,8 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
|
||||
ctx->recorder = NULL;
|
||||
ctx->url_string = url_string;
|
||||
ctx->location_field_set = false;
|
||||
ctx->psol_vary_accept_only = false;
|
||||
|
||||
// Set up a cleanup handler on the request.
|
||||
ngx_http_cleanup_t* cleanup = ngx_http_cleanup_add(r, 0);
|
||||
@@ -1832,16 +1923,17 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
if (pagespeed_resource) {
|
||||
// TODO(jefftk): Set using_spdy appropriately. See
|
||||
// ProxyInterface::ProxyRequestCallback
|
||||
ps_create_base_fetch(ctx, request_context, request_headers.release(),
|
||||
kPageSpeedResource);
|
||||
ps_create_base_fetch(url.Spec(), ctx, request_context,
|
||||
request_headers.release(), kPageSpeedResource,
|
||||
options);
|
||||
ResourceFetch::Start(
|
||||
url,
|
||||
custom_options.release() /* null if there aren't custom options */,
|
||||
false /* using_spdy */, cfg_s->server_context, ctx->base_fetch);
|
||||
cfg_s->server_context, ctx->base_fetch);
|
||||
return ps_async_wait_response(r);
|
||||
} else if (is_an_admin_handler) {
|
||||
ps_create_base_fetch(ctx, request_context, request_headers.release(),
|
||||
kAdminPage);
|
||||
ps_create_base_fetch(url.Spec(), ctx, request_context,
|
||||
request_headers.release(), kAdminPage, options);
|
||||
QueryParams query_params;
|
||||
query_params.ParseFromUrl(url);
|
||||
|
||||
@@ -1882,11 +1974,40 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
}
|
||||
|
||||
return ps_async_wait_response(r);
|
||||
} else if (!html_rewrite && response_category == RequestRouting::kResource) {
|
||||
bool is_proxy = false;
|
||||
GoogleString mapped_url;
|
||||
GoogleString host_header;
|
||||
|
||||
if (options->domain_lawyer()->MapOriginUrl(
|
||||
url, &mapped_url, &host_header, &is_proxy) && is_proxy) {
|
||||
ps_create_base_fetch(url.Spec(), ctx, request_context,
|
||||
request_headers.release(), kPageSpeedProxy, options);
|
||||
|
||||
RewriteDriver* driver;
|
||||
if (custom_options.get() == NULL) {
|
||||
driver = cfg_s->server_context->NewRewriteDriver(
|
||||
ctx->base_fetch->request_context());
|
||||
} else {
|
||||
driver = cfg_s->server_context->NewCustomRewriteDriver(
|
||||
custom_options.release(), ctx->base_fetch->request_context());
|
||||
}
|
||||
|
||||
driver->SetRequestHeaders(*ctx->base_fetch->request_headers());
|
||||
driver->set_pagespeed_query_params(pagespeed_query_params);
|
||||
driver->set_pagespeed_option_cookies(pagespeed_option_cookies);
|
||||
cfg_s->proxy_fetch_factory->StartNewProxyFetch(
|
||||
mapped_url, ctx->base_fetch, driver, NULL /*property_callback*/,
|
||||
NULL /*original_content_fetch*/);
|
||||
|
||||
return ps_async_wait_response(r);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (html_rewrite) {
|
||||
ps_create_base_fetch(ctx, request_context, request_headers.release(),
|
||||
kHtmlTransform);
|
||||
if (html_rewrite && options->IsAllowed(url.Spec())) {
|
||||
ps_create_base_fetch(url.Spec(), ctx, request_context,
|
||||
request_headers.release(), kHtmlTransform, options);
|
||||
// Do not store driver in request_context, it's not safe.
|
||||
RewriteDriver* driver;
|
||||
|
||||
@@ -1903,11 +2024,6 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
custom_options.release(), ctx->base_fetch->request_context());
|
||||
}
|
||||
|
||||
StringPiece user_agent = ctx->base_fetch->request_headers()->Lookup1(
|
||||
HttpAttributes::kUserAgent);
|
||||
if (!user_agent.empty()) {
|
||||
driver->SetUserAgent(user_agent);
|
||||
}
|
||||
driver->SetRequestHeaders(*ctx->base_fetch->request_headers());
|
||||
driver->set_pagespeed_query_params(pagespeed_query_params);
|
||||
driver->set_pagespeed_option_cookies(pagespeed_option_cookies);
|
||||
@@ -1919,8 +2035,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
url,
|
||||
cfg_s->server_context,
|
||||
options,
|
||||
ctx->base_fetch,
|
||||
false /* requires_blink_cohort (no longer unused) */);
|
||||
ctx->base_fetch);
|
||||
|
||||
// Will call StartParse etc. The rewrite driver will take care of deleting
|
||||
// itself if necessary.
|
||||
@@ -1928,14 +2043,15 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
url_string, ctx->base_fetch, driver,
|
||||
property_callback,
|
||||
NULL /* original_content_fetch */);
|
||||
ctx->proxy_fetch->set_trusted_input(true);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (options->in_place_rewriting_enabled() &&
|
||||
options->enabled() &&
|
||||
options->IsAllowed(url.Spec())) {
|
||||
ps_create_base_fetch(ctx, request_context, request_headers.release(),
|
||||
kIproLookup);
|
||||
ps_create_base_fetch(url.Spec(), ctx, request_context, request_headers.release(),
|
||||
kIproLookup, options);
|
||||
|
||||
// Do not store driver in request_context, it's not safe.
|
||||
RewriteDriver* driver;
|
||||
@@ -1948,13 +2064,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
|
||||
custom_options.release(), ctx->base_fetch->request_context());
|
||||
}
|
||||
|
||||
StringPiece user_agent = ctx->base_fetch->request_headers()->Lookup1(
|
||||
HttpAttributes::kUserAgent);
|
||||
if (!user_agent.empty()) {
|
||||
driver->SetUserAgent(user_agent);
|
||||
}
|
||||
driver->SetRequestHeaders(*ctx->base_fetch->request_headers());
|
||||
|
||||
ctx->driver = driver;
|
||||
|
||||
cfg_s->server_context->message_handler()->Message(
|
||||
@@ -1990,7 +2100,6 @@ void ps_send_to_pagespeed(ngx_http_request_t* r,
|
||||
int last_buf = 0;
|
||||
for (cur = in; cur != NULL; cur = cur->next) {
|
||||
last_buf = cur->buf->last_buf;
|
||||
|
||||
// Buffers are not really the last buffer until they've been through
|
||||
// pagespeed.
|
||||
cur->buf->last_buf = 0;
|
||||
@@ -2015,6 +2124,19 @@ void ps_send_to_pagespeed(ngx_http_request_t* r,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur->buf->flush && ctx->follow_flushes) {
|
||||
// Calling ctx->proxy_fetch->Flush(cfg_s->handler) will be a no-op here,
|
||||
// unless we have follow_flushes or flush_html enabled. Note that PSOL
|
||||
// might aggregate multiple flushes into 1, and actually flush a little bit
|
||||
// later due to html parser state and earlier scheduled operations.
|
||||
// Also, unless we also set the flush flag on the nginx buffers we won't
|
||||
// actually flush.
|
||||
// Note that too many flushes could harm optimization over larger html
|
||||
// fragments as PSOL gets less context to work with, e.g. it can't combine
|
||||
// two css files if a flush happens in between.
|
||||
ctx->proxy_fetch->Flush(cfg_s->handler);
|
||||
}
|
||||
|
||||
// We're done with buffers as we pass them through, so mark them as sent as
|
||||
// we go.
|
||||
cur->buf->pos = cur->buf->last;
|
||||
@@ -2023,9 +2145,6 @@ void ps_send_to_pagespeed(ngx_http_request_t* r,
|
||||
if (last_buf) {
|
||||
ctx->proxy_fetch->Done(true /* success */);
|
||||
ctx->proxy_fetch = NULL; // ProxyFetch deletes itself on Done().
|
||||
} else {
|
||||
// TODO(jefftk): Decide whether Flush() is warranted here.
|
||||
ctx->proxy_fetch->Flush(cfg_s->handler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2115,6 +2234,38 @@ ngx_int_t ps_etag_header_filter(ngx_http_request_t* r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ps_request_ctx_t* ctx = ps_get_request_context(r);
|
||||
#if (NGX_HTTP_GZIP)
|
||||
if (ctx && ctx->psol_vary_accept_only) {
|
||||
r->gzip_vary = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ctx && ctx->recorder) {
|
||||
ps_srv_conf_t* cfg_s = ps_get_srv_config(r);
|
||||
int s_maxage_sec =
|
||||
cfg_s->server_context->global_options()->EffectiveInPlaceSMaxAgeSec();
|
||||
if (s_maxage_sec != -1) {
|
||||
GoogleString existing_cache_control;
|
||||
bool cache_control_present = ps_get_cache_control(
|
||||
r, &existing_cache_control);
|
||||
GoogleString updated_cache_control;
|
||||
if (ResponseHeaders::ApplySMaxAge(s_maxage_sec,
|
||||
existing_cache_control,
|
||||
&updated_cache_control)) {
|
||||
// We're modifing the cache control header; save a copy first.
|
||||
// NULL indicates that the header was not present.
|
||||
ctx->recorder->SaveCacheControl(
|
||||
cache_control_present ? existing_cache_control.c_str() : NULL);
|
||||
|
||||
// Replace the cache-control with our new s-maxage-including one.
|
||||
ps_set_cache_control(r, string_piece_to_pool_string(
|
||||
r->pool, updated_cache_control));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_ef_next_header_filter(r);
|
||||
}
|
||||
|
||||
@@ -2198,6 +2349,8 @@ ngx_int_t ps_html_rewrite_header_filter(ngx_http_request_t* r) {
|
||||
}
|
||||
|
||||
ps_strip_html_headers(r);
|
||||
// See https://github.com/pagespeed/ngx_pagespeed/issues/819
|
||||
ctx->location_field_set = r->headers_out.location != NULL;
|
||||
|
||||
// TODO(jefftk): is this thread safe?
|
||||
copy_response_headers_from_ngx(r, ctx->base_fetch->response_headers());
|
||||
@@ -2340,6 +2493,7 @@ ngx_int_t ps_in_place_check_header_filter(ngx_http_request_t* r) {
|
||||
cache_url.c_str());
|
||||
const SystemRewriteOptions* options = SystemRewriteOptions::DynamicCast(
|
||||
ctx->driver->options());
|
||||
|
||||
RequestContextPtr request_context(
|
||||
cfg_s->server_context->NewRequestContext(r));
|
||||
request_context->set_options(options->ComputeHttpOptions());
|
||||
@@ -2359,7 +2513,7 @@ ngx_int_t ps_in_place_check_header_filter(ngx_http_request_t* r) {
|
||||
server_context->http_cache(),
|
||||
server_context->statistics(),
|
||||
message_handler);
|
||||
// set in memory flag for in place_body_filter
|
||||
// set in memory flag for in_place_body_filter
|
||||
r->filter_need_in_memory = 1;
|
||||
|
||||
// We don't have the response headers at all yet because we haven't yet gone
|
||||
@@ -2436,14 +2590,14 @@ ngx_int_t send_out_headers_and_body(
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Send the body.
|
||||
ngx_chain_t* out;
|
||||
rc = string_piece_to_buffer_chain(
|
||||
r->pool, output, &out, true /* send_last_buf */);
|
||||
r->pool, output, &out, true /* send_last_buf */, false);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@@ -2874,7 +3028,7 @@ ngx_int_t ps_preaccess_handler(ngx_http_request_t* r) {
|
||||
ngx_int_t ps_etag_filter_init(ngx_conf_t* cf) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_conf_get_module_main_conf(cf, ngx_pagespeed));
|
||||
if (cfg_m->driver_factory != NULL) {
|
||||
if (cfg_m != NULL && cfg_m->driver_factory != NULL) {
|
||||
ngx_http_ef_next_header_filter = ngx_http_top_header_filter;
|
||||
ngx_http_top_header_filter = ps_etag_header_filter;
|
||||
}
|
||||
@@ -2956,6 +3110,11 @@ ngx_int_t ps_init_module(ngx_cycle_t* cycle) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_pagespeed));
|
||||
|
||||
// See https://github.com/pagespeed/ngx_pagespeed/issues/1220
|
||||
if (cfg_m == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_http_core_main_conf_t* cmcf = static_cast<ngx_http_core_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module));
|
||||
ngx_http_core_srv_conf_t** cscfp = static_cast<ngx_http_core_srv_conf_t**>(
|
||||
@@ -3009,7 +3168,7 @@ ngx_int_t ps_init_module(ngx_cycle_t* cycle) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cfg_m->driver_factory->LoggingInit(cycle->log);
|
||||
cfg_m->driver_factory->LoggingInit(cycle->log, true);
|
||||
cfg_m->driver_factory->RootInit();
|
||||
} else {
|
||||
delete cfg_m->driver_factory;
|
||||
@@ -3023,7 +3182,9 @@ void ps_exit_child_process(ngx_cycle_t* cycle) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_pagespeed));
|
||||
NgxBaseFetch::Terminate();
|
||||
cfg_m->driver_factory->ShutDown();
|
||||
if (cfg_m != NULL && cfg_m->driver_factory != NULL) {
|
||||
cfg_m->driver_factory->ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
// Called when nginx forks worker processes. No threads should be started
|
||||
@@ -3031,7 +3192,7 @@ void ps_exit_child_process(ngx_cycle_t* cycle) {
|
||||
ngx_int_t ps_init_child_process(ngx_cycle_t* cycle) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_pagespeed));
|
||||
if (cfg_m->driver_factory == NULL) {
|
||||
if (cfg_m == NULL || cfg_m->driver_factory == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -3041,7 +3202,7 @@ ngx_int_t ps_init_child_process(ngx_cycle_t* cycle) {
|
||||
|
||||
// ChildInit() will initialise all ServerContexts, which we need to
|
||||
// create ProxyFetchFactories below
|
||||
cfg_m->driver_factory->LoggingInit(cycle->log);
|
||||
cfg_m->driver_factory->LoggingInit(cycle->log, true);
|
||||
cfg_m->driver_factory->ChildInit();
|
||||
|
||||
ngx_http_core_main_conf_t* cmcf = static_cast<ngx_http_core_main_conf_t*>(
|
||||
|
||||
+8
-1
@@ -52,7 +52,7 @@ class InPlaceResourceRecorder;
|
||||
// NGX_DECLINED immediately unless send_last_buf.
|
||||
ngx_int_t string_piece_to_buffer_chain(
|
||||
ngx_pool_t* pool, StringPiece sp,
|
||||
ngx_chain_t** link_ptr, bool send_last_buf);
|
||||
ngx_chain_t** link_ptr, bool send_last_buf, bool send_flush);
|
||||
|
||||
StringPiece str_to_string_piece(ngx_str_t s);
|
||||
|
||||
@@ -103,6 +103,13 @@ typedef struct {
|
||||
// We need to remember the URL here as well since we may modify what NGX
|
||||
// gets by stripping our special query params and honoring X-Forwarded-Proto.
|
||||
GoogleString url_string;
|
||||
|
||||
// We need to remember if the upstream had headers_out->location set, because
|
||||
// we should mirror that when we write it back. nginx may absolutify
|
||||
// Location: headers that start with '/' without regarding X-Forwarded-Proto.
|
||||
bool location_field_set;
|
||||
bool psol_vary_accept_only;
|
||||
bool follow_flushes;
|
||||
} ps_request_ctx_t;
|
||||
|
||||
ps_request_ctx_t* ps_get_request_context(ngx_http_request_t* r);
|
||||
|
||||
@@ -69,7 +69,6 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
|
||||
SystemThreadSystem* system_thread_system, StringPiece hostname, int port)
|
||||
: SystemRewriteDriverFactory(process_context, system_thread_system,
|
||||
NULL /* default shared memory runtime */, hostname, port),
|
||||
main_conf_(NULL),
|
||||
threads_started_(false),
|
||||
ngx_message_handler_(
|
||||
new NgxMessageHandler(timer(), thread_system()->NewMutex())),
|
||||
@@ -83,7 +82,7 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
|
||||
ngx_shared_circular_buffer_(NULL),
|
||||
hostname_(hostname.as_string()),
|
||||
port_(port),
|
||||
process_script_variables_(false),
|
||||
process_script_variables_mode_(ProcessScriptVariablesMode::kOff),
|
||||
process_script_variables_set_(false),
|
||||
shut_down_(false) {
|
||||
InitializeDefaultOptions();
|
||||
@@ -148,10 +147,19 @@ NamedLockManager* NgxRewriteDriverFactory::DefaultLockManager() {
|
||||
|
||||
RewriteOptions* NgxRewriteDriverFactory::NewRewriteOptions() {
|
||||
NgxRewriteOptions* options = new NgxRewriteOptions(thread_system());
|
||||
// TODO(jefftk): figure out why using SetDefaultRewriteLevel like
|
||||
// mod_pagespeed does in mod_instaweb.cc:create_dir_config() isn't enough here
|
||||
// -- if you use that instead then ngx_pagespeed doesn't actually end up
|
||||
// defaulting CoreFilters.
|
||||
// See: https://github.com/pagespeed/ngx_pagespeed/issues/1190
|
||||
options->SetRewriteLevel(RewriteOptions::kCoreFilters);
|
||||
return options;
|
||||
}
|
||||
|
||||
RewriteOptions* NgxRewriteDriverFactory::NewRewriteOptionsForQuery() {
|
||||
return new NgxRewriteOptions(thread_system());
|
||||
}
|
||||
|
||||
bool NgxRewriteDriverFactory::CheckResolver() {
|
||||
if (use_native_fetcher_ && resolver_ == NULL) {
|
||||
return false;
|
||||
@@ -208,10 +216,19 @@ void NgxRewriteDriverFactory::StartThreads() {
|
||||
threads_started_ = true;
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::LoggingInit(ngx_log_t* log) {
|
||||
void NgxRewriteDriverFactory::SetMainConf(NgxRewriteOptions* main_options) {
|
||||
// Propagate process-scope options from the copy we had during nginx option
|
||||
// parsing to our own.
|
||||
if (main_options != NULL) {
|
||||
default_options()->MergeOnlyProcessScopeOptions(*main_options);
|
||||
}
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::LoggingInit(
|
||||
ngx_log_t* log, bool may_install_crash_handler) {
|
||||
log_ = log;
|
||||
net_instaweb::log_message_handler::Install(log);
|
||||
if (install_crash_handler()) {
|
||||
if (may_install_crash_handler && install_crash_handler()) {
|
||||
NgxMessageHandler::InstallCrashHandler(log);
|
||||
}
|
||||
ngx_message_handler_->set_log(log);
|
||||
@@ -249,4 +266,23 @@ void NgxRewriteDriverFactory::InitStats(Statistics* statistics) {
|
||||
InPlaceResourceRecorder::InitStats(statistics);
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::PrepareForkedProcess(const char* name) {
|
||||
ngx_pid = ngx_getpid(); // Needed for logging to have the right PIDs.
|
||||
SystemRewriteDriverFactory::PrepareForkedProcess(name);
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::NameProcess(const char* name) {
|
||||
SystemRewriteDriverFactory::NameProcess(name);
|
||||
|
||||
// Superclass set status with prctl. Nginx has a helper function for setting
|
||||
// argv[0] as well, so let's use that. We'll show up as:
|
||||
//
|
||||
// nginx: pagespeed $name
|
||||
|
||||
char name_for_setproctitle[32];
|
||||
snprintf(name_for_setproctitle, sizeof(name_for_setproctitle),
|
||||
"pagespeed %s", name);
|
||||
ngx_setproctitle(name_for_setproctitle);
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
@@ -48,6 +48,12 @@ class SlowWorker;
|
||||
class Statistics;
|
||||
class SystemThreadSystem;
|
||||
|
||||
enum ProcessScriptVariablesMode {
|
||||
kOff,
|
||||
kLegacyRestricted,
|
||||
kAll
|
||||
};
|
||||
|
||||
class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
|
||||
public:
|
||||
// We take ownership of the thread system.
|
||||
@@ -63,8 +69,9 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
|
||||
virtual Timer* DefaultTimer();
|
||||
virtual NamedLockManager* DefaultLockManager();
|
||||
// Create a new RewriteOptions. In this implementation it will be an
|
||||
// NgxRewriteOptions.
|
||||
// NgxRewriteOptions, and it will have CoreFilters explicitly set.
|
||||
virtual RewriteOptions* NewRewriteOptions();
|
||||
virtual RewriteOptions* NewRewriteOptionsForQuery();
|
||||
virtual ServerContext* NewDecodingServerContext();
|
||||
// Check resolver configured or not.
|
||||
bool CheckResolver();
|
||||
@@ -90,7 +97,7 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
|
||||
InitStats(statistics);
|
||||
}
|
||||
|
||||
void set_main_conf(NgxRewriteOptions* main_conf) { main_conf_ = main_conf; }
|
||||
void SetMainConf(NgxRewriteOptions* main_conf);
|
||||
|
||||
void set_resolver(ngx_resolver_t* resolver) {
|
||||
resolver_ = resolver;
|
||||
@@ -111,32 +118,32 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
|
||||
void set_native_fetcher_max_keepalive_requests(int x) {
|
||||
native_fetcher_max_keepalive_requests_ = x;
|
||||
}
|
||||
bool process_script_variables() {
|
||||
return process_script_variables_;
|
||||
ProcessScriptVariablesMode process_script_variables() {
|
||||
return process_script_variables_mode_;
|
||||
}
|
||||
|
||||
void LoggingInit(ngx_log_t* log);
|
||||
void LoggingInit(ngx_log_t* log, bool may_install_crash_handler);
|
||||
|
||||
virtual void ShutDownMessageHandlers();
|
||||
|
||||
virtual void SetCircularBuffer(SharedCircularBuffer* buffer);
|
||||
|
||||
bool SetProcessScriptVariables(bool process_script_variables) {
|
||||
bool SetProcessScriptVariables(ProcessScriptVariablesMode mode) {
|
||||
if (!process_script_variables_set_) {
|
||||
process_script_variables_ = process_script_variables;
|
||||
process_script_variables_mode_ = mode;
|
||||
process_script_variables_set_ = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void PrepareForkedProcess(const char* name);
|
||||
|
||||
virtual void NameProcess(const char* name);
|
||||
|
||||
private:
|
||||
Timer* timer_;
|
||||
|
||||
// main_conf will have only options set in the main block. It may be NULL,
|
||||
// and we do not take ownership.
|
||||
NgxRewriteOptions* main_conf_;
|
||||
|
||||
bool threads_started_;
|
||||
NgxMessageHandler* ngx_message_handler_;
|
||||
NgxMessageHandler* ngx_html_parse_message_handler_;
|
||||
@@ -157,7 +164,7 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
|
||||
|
||||
GoogleString hostname_;
|
||||
int port_;
|
||||
bool process_script_variables_;
|
||||
ProcessScriptVariablesMode process_script_variables_mode_;
|
||||
bool process_script_variables_set_;
|
||||
bool shut_down_;
|
||||
|
||||
|
||||
+59
-30
@@ -112,7 +112,7 @@ void NgxRewriteOptions::AddProperties() {
|
||||
false);
|
||||
add_ngx_option(
|
||||
"", &NgxRewriteOptions::global_statistics_path_, "ngsp",
|
||||
kGlobalStatisticsPath, kProcessScope,
|
||||
kGlobalStatisticsPath, kProcessScopeStrict,
|
||||
"Set the global statistics path. Ex: /ngx_pagespeed_global_statistics",
|
||||
false);
|
||||
add_ngx_option(
|
||||
@@ -127,7 +127,8 @@ void NgxRewriteOptions::AddProperties() {
|
||||
kServerScope, "Set the admin path. Ex: /pagespeed_admin", false);
|
||||
add_ngx_option(
|
||||
"", &NgxRewriteOptions::global_admin_path_, "ngap", kGlobalAdminPath,
|
||||
kProcessScope, "Set the global admin path. Ex: /pagespeed_global_admin",
|
||||
kProcessScopeStrict,
|
||||
"Set the global admin path. Ex: /pagespeed_global_admin",
|
||||
false);
|
||||
|
||||
MergeSubclassProperties(ngx_properties_);
|
||||
@@ -180,10 +181,10 @@ RewriteOptions::OptionScope NgxRewriteOptions::GetOptionScope(
|
||||
it != all_options().end(); ++it) {
|
||||
RewriteOptions::OptionBase* option = *it;
|
||||
if (option->option_name() == option_name) {
|
||||
// We treat kProcessScope as kProcessScopeStrict, failing to start if an
|
||||
// option is out of place.
|
||||
return option->scope() == kProcessScope ? kProcessScopeStrict
|
||||
: option->scope();
|
||||
// We treat kLegacyProcessScope as kProcessScopeStrict, failing to start
|
||||
// if an option is out of place.
|
||||
return option->scope() == kLegacyProcessScope ? kProcessScopeStrict
|
||||
: option->scope();
|
||||
}
|
||||
}
|
||||
return kDirectoryScope;
|
||||
@@ -258,7 +259,8 @@ const char* ps_error_string_for_option(
|
||||
const char* NgxRewriteOptions::ParseAndSetOptions(
|
||||
StringPiece* args, int n_args, ngx_pool_t* pool, MessageHandler* handler,
|
||||
NgxRewriteDriverFactory* driver_factory,
|
||||
RewriteOptions::OptionScope scope, ngx_conf_t* cf, bool compile_scripts) {
|
||||
RewriteOptions::OptionScope scope, ngx_conf_t* cf,
|
||||
ProcessScriptVariablesMode script_mode) {
|
||||
CHECK_GE(n_args, 1);
|
||||
|
||||
StringPiece directive = args[0];
|
||||
@@ -274,15 +276,43 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
|
||||
pool, directive, "cannot be set at this scope.");
|
||||
}
|
||||
|
||||
bool compile_scripts = false;
|
||||
|
||||
if (script_mode != ProcessScriptVariablesMode::kOff) {
|
||||
// In the old mode we only allowed a few, so restrict to those.
|
||||
compile_scripts =
|
||||
StringCaseStartsWith(directive, "LoadFromFile") ||
|
||||
StringCaseEqual(directive, "EnableFilters") ||
|
||||
StringCaseEqual(directive, "DisableFilters") ||
|
||||
StringCaseEqual(directive, "DownstreamCachePurgeLocationPrefix") ||
|
||||
StringCaseEqual(directive, "DownstreamCachePurgeMethod") ||
|
||||
StringCaseEqual(directive,
|
||||
"DownstreamCacheRewrittenPercentageThreshold") ||
|
||||
StringCaseEqual(directive, "ShardDomain");
|
||||
// In the new behaviour we also allow scripting of query- and directory-
|
||||
// scoped options.
|
||||
compile_scripts |=
|
||||
script_mode == ProcessScriptVariablesMode::kAll &&
|
||||
(GetOptionScope(directive) <= RewriteOptions::kDirectoryScope ||
|
||||
(StringCaseEqual(directive, "Allow") ||
|
||||
StringCaseEqual(directive, "BlockingRewriteRefererUrls") ||
|
||||
StringCaseEqual(directive, "Disallow") ||
|
||||
StringCaseEqual(directive, "DistributableFilters") ||
|
||||
StringCaseEqual(directive, "Domain") ||
|
||||
StringCaseEqual(directive, "ExperimentVariable") ||
|
||||
StringCaseEqual(directive, "ExperimentSpec") ||
|
||||
StringCaseEqual(directive, "ForbidFilters") ||
|
||||
StringCaseEqual(directive, "RetainComment") ||
|
||||
StringCaseEqual(directive, "CustomFetchHeader") ||
|
||||
StringCaseEqual(directive, "MapOriginDomain") ||
|
||||
StringCaseEqual(directive, "MapProxyDomain") ||
|
||||
StringCaseEqual(directive, "MapRewriteDomain") ||
|
||||
StringCaseEqual(directive, "UrlValuedAttribute") ||
|
||||
StringCaseEqual(directive, "Library")));
|
||||
}
|
||||
|
||||
ScriptLine* script_line;
|
||||
script_line = NULL;
|
||||
// Note that LoadFromFile should not be scriptable on wildcard hosts,
|
||||
// as browsers might be able to manipulate its natural use-case: $http_host.
|
||||
if (!StringCaseStartsWith(directive, "LoadFromFile") &&
|
||||
!StringCaseEqual(directive, "EnableFilters") &&
|
||||
!StringCaseEqual(directive, "DisableFilters")) {
|
||||
compile_scripts = false;
|
||||
}
|
||||
|
||||
if (n_args == 1 && StringCaseEqual(directive, "ClearInheritedScripts")) {
|
||||
clear_inherited_scripts_ = true;
|
||||
@@ -358,24 +388,23 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
|
||||
}
|
||||
} else if (StringCaseEqual("ProcessScriptVariables", args[0])) {
|
||||
if (scope == RewriteOptions::kProcessScopeStrict) {
|
||||
if (StringCaseEqual(arg, "on")) {
|
||||
if (driver_factory->SetProcessScriptVariables(true)) {
|
||||
result = RewriteOptions::kOptionOk;
|
||||
} else {
|
||||
return const_cast<char*>(
|
||||
"pagespeed ProcessScriptVariables: can only be set once");
|
||||
}
|
||||
ProcessScriptVariablesMode mode;
|
||||
if (StringCaseEqual(arg, "all")) {
|
||||
mode = ProcessScriptVariablesMode::kAll;
|
||||
} else if (StringCaseEqual(arg, "on")) {
|
||||
mode = ProcessScriptVariablesMode::kLegacyRestricted;
|
||||
} else if (StringCaseEqual(arg, "off")) {
|
||||
if (driver_factory->SetProcessScriptVariables(false)) {
|
||||
result = RewriteOptions::kOptionOk;
|
||||
} else {
|
||||
return const_cast<char*>(
|
||||
"pagespeed ProcessScriptVariables: can only be set once");
|
||||
}
|
||||
mode = ProcessScriptVariablesMode::kOff;
|
||||
} else {
|
||||
return const_cast<char*>(
|
||||
"pagespeed ProcessScriptVariables: invalid value");
|
||||
}
|
||||
if (driver_factory->SetProcessScriptVariables(mode)) {
|
||||
result = RewriteOptions::kOptionOk;
|
||||
} else {
|
||||
return const_cast<char*>(
|
||||
"pagespeed ProcessScriptVariables: can only be set once");
|
||||
}
|
||||
} else {
|
||||
return const_cast<char*>(
|
||||
"ProcessScriptVariables is only allowed at the top level");
|
||||
@@ -386,7 +415,7 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
|
||||
result = driver_factory->ParseAndSetOption1(
|
||||
directive,
|
||||
arg,
|
||||
scope >= RewriteOptions::kProcessScope,
|
||||
scope >= RewriteOptions::kLegacyProcessScope,
|
||||
&msg,
|
||||
handler);
|
||||
}
|
||||
@@ -399,7 +428,7 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
|
||||
directive,
|
||||
args[1],
|
||||
args[2],
|
||||
scope >= RewriteOptions::kProcessScope,
|
||||
scope >= RewriteOptions::kLegacyProcessScope,
|
||||
&msg,
|
||||
handler);
|
||||
}
|
||||
@@ -471,7 +500,7 @@ bool NgxRewriteOptions::ExecuteScriptVariables(
|
||||
|
||||
const char* status = ParseAndSetOptions(args, script_line->n_args(),
|
||||
r->pool, handler, driver_factory, script_line->scope(), NULL /*cf*/,
|
||||
false /*compile scripts*/);
|
||||
ProcessScriptVariablesMode::kOff);
|
||||
|
||||
if (status != NULL) {
|
||||
script_error = true;
|
||||
|
||||
@@ -29,6 +29,8 @@ extern "C" {
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ngx_rewrite_driver_factory.h"
|
||||
|
||||
#include "net/instaweb/rewriter/public/rewrite_options.h"
|
||||
#include "pagespeed/kernel/base/message_handler.h"
|
||||
#include "pagespeed/kernel/base/ref_counted_ptr.h"
|
||||
@@ -131,7 +133,7 @@ class NgxRewriteOptions : public SystemRewriteOptions {
|
||||
const char* ParseAndSetOptions(
|
||||
StringPiece* args, int n_args, ngx_pool_t* pool, MessageHandler* handler,
|
||||
NgxRewriteDriverFactory* driver_factory, OptionScope scope,
|
||||
ngx_conf_t* cf, bool compile_scripts);
|
||||
ngx_conf_t* cf, ProcessScriptVariablesMode script_mode);
|
||||
bool ExecuteScriptVariables(
|
||||
ngx_http_request_t* r, MessageHandler* handler,
|
||||
NgxRewriteDriverFactory* driver_factory);
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace net_instaweb {
|
||||
|
||||
NgxServerContext::NgxServerContext(
|
||||
NgxRewriteDriverFactory* factory, StringPiece hostname, int port)
|
||||
: SystemServerContext(factory, hostname, port) {
|
||||
: SystemServerContext(factory, hostname, port),
|
||||
ngx_http2_variable_index_(NGX_ERROR) {
|
||||
}
|
||||
|
||||
NgxServerContext::~NgxServerContext() { }
|
||||
@@ -70,11 +71,23 @@ SystemRequestContext* NgxServerContext::NewRequestContext(
|
||||
local_ip.len = 0;
|
||||
}
|
||||
|
||||
return new SystemRequestContext(thread_system()->NewMutex(),
|
||||
timer(),
|
||||
ps_determine_host(r),
|
||||
local_port,
|
||||
str_to_string_piece(local_ip));
|
||||
SystemRequestContext* ctx = new SystemRequestContext(
|
||||
thread_system()->NewMutex(), timer(),
|
||||
ps_determine_host(r), local_port, str_to_string_piece(local_ip));
|
||||
|
||||
// See if http2 is in use.
|
||||
if (ngx_http2_variable_index_ >= 0) {
|
||||
ngx_http_variable_value_t* val =
|
||||
ngx_http_get_indexed_variable(r, ngx_http2_variable_index_);
|
||||
if (val != NULL && val->valid) {
|
||||
StringPiece str_val(reinterpret_cast<char*>(val->data), val->len);
|
||||
if (str_val == "h2" || str_val == "h2c") {
|
||||
ctx->set_using_http2(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
GoogleString NgxServerContext::FormatOption(StringPiece option_name,
|
||||
|
||||
@@ -40,8 +40,9 @@ class NgxServerContext : public SystemServerContext {
|
||||
NgxRewriteDriverFactory* factory, StringPiece hostname, int port);
|
||||
virtual ~NgxServerContext();
|
||||
|
||||
// We expect to use ProxyFetch with HTML.
|
||||
virtual bool ProxiesHtml() const { return true; }
|
||||
// We don't allow ProxyFetch to fetch HTML via MapProxyDomain. We will call
|
||||
// set_trusted_input() on any ProxyFetches we use to transform internal HTML.
|
||||
virtual bool ProxiesHtml() const { return false; }
|
||||
|
||||
// Call only when you need an NgxRewriteOptions. If you don't need
|
||||
// nginx-specific behavior, call global_options() instead which doesn't
|
||||
@@ -57,8 +58,18 @@ class NgxServerContext : public SystemServerContext {
|
||||
|
||||
virtual GoogleString FormatOption(StringPiece option_name, StringPiece args);
|
||||
|
||||
void set_ngx_http2_variable_index(ngx_int_t idx) {
|
||||
ngx_http2_variable_index_ = idx;
|
||||
}
|
||||
|
||||
ngx_int_t ngx_http2_variable_index() const {
|
||||
return ngx_http2_variable_index_;
|
||||
}
|
||||
|
||||
private:
|
||||
NgxRewriteDriverFactory* ngx_factory_;
|
||||
// what index the "http2" var is, or NGX_ERROR.
|
||||
ngx_int_t ngx_http2_variable_index_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NgxServerContext);
|
||||
};
|
||||
|
||||
+214
-46
@@ -31,21 +31,38 @@
|
||||
: ${NATIVE_FETCHER:?"Set NATIVE_FETCHER to off or on"}
|
||||
: ${PRIMARY_PORT:?"Set PRIMARY_PORT"}
|
||||
: ${SECONDARY_PORT:?"Set SECONDARY_PORT"}
|
||||
: ${RCPORT1:?"Set RCPORT1"}
|
||||
: ${RCPORT2:?"Set RCPORT2"}
|
||||
: ${RCPORT2:?"Set RCPORT3"}
|
||||
: ${RCPORT4:?"Set RCPORT4"}
|
||||
: ${RCPORT5:?"Set RCPORT5"}
|
||||
: ${RCPORT6:?"Set RCPORT6"}
|
||||
: ${RCPORT7:?"Set RCPORT7"}
|
||||
: ${CONTROLLER_PORT:?"Set CONTROLLER_PORT"}
|
||||
: ${RCPORT:?"Set RCPORT"}
|
||||
: ${MOD_PAGESPEED_DIR:?"Set MOD_PAGESPEED_DIR"}
|
||||
: ${NGINX_EXECUTABLE:?"Set NGINX_EXECUTABLE"}
|
||||
: ${PAGESPEED_TEST_HOST:?"Set PAGESPEED_TEST_HOST"}
|
||||
POSITION_AUX="${POSITION_AUX:-unset}"
|
||||
RUN_CONTROLLER_TEST="${RUN_CONTROLLER_TEST:-off}"
|
||||
|
||||
PRIMARY_HOSTNAME="localhost:$PRIMARY_PORT"
|
||||
SECONDARY_HOSTNAME="localhost:$SECONDARY_PORT"
|
||||
|
||||
SERVER_ROOT="$MOD_PAGESPEED_DIR/src/install/"
|
||||
this_dir="$( cd $(dirname "$0") && pwd)"
|
||||
echo this_dir=$this_dir
|
||||
TEST_TMP="$this_dir/tmp"
|
||||
rm -rf "$TEST_TMP"
|
||||
mkdir -p "$TEST_TMP"
|
||||
echo TEST_TMP=$TEST_TMP
|
||||
|
||||
if [ -d "$MOD_PAGESPEED_DIR/src" ]; then
|
||||
MOD_PAGESPEED_DIR+="/src"
|
||||
fi
|
||||
|
||||
APACHE_DOC_SRC="$MOD_PAGESPEED_DIR/install/"
|
||||
SERVER_ROOT="$TEST_TMP/root"
|
||||
echo SERVER_ROOT=$SERVER_ROOT
|
||||
rm -rf "$SERVER_ROOT"
|
||||
mkdir -p "$SERVER_ROOT"
|
||||
export APACHE_DOC_ROOT="$SERVER_ROOT"
|
||||
|
||||
mkdir -p "$APACHE_DOC_ROOT"
|
||||
make -f "$APACHE_DOC_SRC/Makefile.tests" setup_doc_root \
|
||||
INSTALL_DATA_DIR="$APACHE_DOC_SRC"
|
||||
|
||||
# We need check and check_not before we source SYSTEM_TEST_FILE that provides
|
||||
# them.
|
||||
@@ -135,17 +152,19 @@ function fire_ab_load() {
|
||||
sleep 2
|
||||
}
|
||||
|
||||
this_dir="$( cd $(dirname "$0") && pwd)"
|
||||
|
||||
# stop nginx/valgrind
|
||||
killall -s KILL nginx
|
||||
# TODO(oschaaf): Fix waiting for valgrind on 32 bits systems.
|
||||
killall -s KILL memcheck-amd64-
|
||||
while pgrep nginx > /dev/null; do sleep 1; done
|
||||
while pgrep memcheck > /dev/null; do sleep 1; done
|
||||
killall -s KILL memcheck-x86-
|
||||
SECONDS=0
|
||||
while pgrep -x nginx >/dev/null || pgrep memcheck >/dev/null;do
|
||||
if [ $SECONDS -gt 20 ]; then
|
||||
echo "Old processes won't die" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
TEST_TMP="$this_dir/tmp"
|
||||
rm -r "$TEST_TMP"
|
||||
check_simple mkdir -p "$TEST_TMP"
|
||||
PROXY_CACHE="$TEST_TMP/proxycache"
|
||||
TMP_PROXY_CACHE="$TEST_TMP/tmpproxycache"
|
||||
@@ -175,6 +194,12 @@ else
|
||||
RESOLVER=""
|
||||
fi
|
||||
|
||||
if [ "$RUN_CONTROLLER_TEST" = "on" ]; then
|
||||
CONTROLLER="pagespeed ExperimentalCentralControllerPort $CONTROLLER_PORT;"
|
||||
else
|
||||
CONTROLLER=""
|
||||
fi
|
||||
|
||||
# set up the config file for the test
|
||||
PAGESPEED_CONF="$TEST_TMP/pagespeed_test.conf"
|
||||
PAGESPEED_CONF_TEMPLATE="$this_dir/pagespeed_test.conf.template"
|
||||
@@ -199,15 +224,11 @@ cat $PAGESPEED_CONF_TEMPLATE \
|
||||
| sed 's#@@SERVER_ROOT@@#'"$SERVER_ROOT"'#' \
|
||||
| sed 's#@@PRIMARY_PORT@@#'"$PRIMARY_PORT"'#' \
|
||||
| sed 's#@@SECONDARY_PORT@@#'"$SECONDARY_PORT"'#' \
|
||||
| sed 's#@@CONTROLLER@@#'"$CONTROLLER"'#' \
|
||||
| sed 's#@@NATIVE_FETCHER@@#'"$NATIVE_FETCHER"'#' \
|
||||
| sed 's#@@RESOLVER@@#'"$RESOLVER"'#' \
|
||||
| sed 's#@@RCPORT1@@#'"$RCPORT1"'#' \
|
||||
| sed 's#@@RCPORT2@@#'"$RCPORT2"'#' \
|
||||
| sed 's#@@RCPORT3@@#'"$RCPORT3"'#' \
|
||||
| sed 's#@@RCPORT4@@#'"$RCPORT4"'#' \
|
||||
| sed 's#@@RCPORT5@@#'"$RCPORT5"'#' \
|
||||
| sed 's#@@RCPORT6@@#'"$RCPORT6"'#' \
|
||||
| sed 's#@@RCPORT7@@#'"$RCPORT7"'#' \
|
||||
| sed 's#@@RCPORT@@#'"$RCPORT"'#' \
|
||||
| sed 's#@@PAGESPEED_TEST_HOST@@#'"$PAGESPEED_TEST_HOST"'#' \
|
||||
>> $PAGESPEED_CONF
|
||||
# make sure we substituted all the variables
|
||||
check_not_simple grep @@ $PAGESPEED_CONF
|
||||
@@ -218,7 +239,7 @@ if $USE_VALGRIND; then
|
||||
--show-possibly-lost=no --log-file=$TEST_TMP/valgrind.log \
|
||||
--suppressions="$this_dir/valgrind.sup" \
|
||||
$NGINX_EXECUTABLE -c $PAGESPEED_CONF) & VALGRIND_PID=$!
|
||||
trap "echo 'terminating valgrind!' && kill -s sigterm $VALGRIND_PID" EXIT
|
||||
trap "echo 'terminating valgrind!' && kill -s TERM $VALGRIND_PID" EXIT
|
||||
echo "Wait until nginx is ready to accept connections"
|
||||
while ! curl -I "http://$PRIMARY_HOSTNAME/mod_pagespeed_example/" 2>/dev/null; do
|
||||
sleep 0.1;
|
||||
@@ -273,7 +294,7 @@ else
|
||||
if $USE_VALGRIND; then
|
||||
# Clear valgrind trap
|
||||
trap - EXIT
|
||||
echo "To end valgrind, run 'kill -s quit $VALGRIND_PID'"
|
||||
echo "To end valgrind, run 'kill -s TERM $VALGRIND_PID'"
|
||||
fi
|
||||
echo "Not running tests; commence manual testing"
|
||||
exit 4
|
||||
@@ -287,8 +308,16 @@ CACHE_PURGE_METHODS="PURGE GET"
|
||||
|
||||
SERVER_NAME=nginx
|
||||
|
||||
# TODO(cheesy): add an nginx controller test variant. Actually requires some
|
||||
# thought as we don't currently have a multi-phase test flow in ngx_pagespeeed,
|
||||
# as far as I can tell, and we really have to update the config and restart
|
||||
# since the controller is a global setting.
|
||||
RUN_CONTROLLER_TEST=${RUN_CONTROLLER_TEST:-off}
|
||||
|
||||
# run generic system tests
|
||||
SYSTEM_TEST_FILE="$MOD_PAGESPEED_DIR/src/pagespeed/system/system_test.sh"
|
||||
PAGESPEED_DIR="$MOD_PAGESPEED_DIR/pagespeed"
|
||||
SYSTEM_TEST_FILE="$PAGESPEED_DIR/system/system_test.sh"
|
||||
REMOTE_CONFIG_TEST_FILE="$PAGESPEED_DIR/system/remote_config_test.sh"
|
||||
|
||||
if [ ! -e "$SYSTEM_TEST_FILE" ] ; then
|
||||
echo "Not finding $SYSTEM_TEST_FILE -- is mod_pagespeed not in a parallel"
|
||||
@@ -298,11 +327,17 @@ fi
|
||||
|
||||
PSA_JS_LIBRARY_URL_PREFIX="pagespeed_custom_static"
|
||||
BEACON_HANDLER="ngx_pagespeed_beacon"
|
||||
STATISTICS_URL=http://$PRIMARY_HOSTNAME/ngx_pagespeed_statistics
|
||||
STATISTICS_HANDLER="ngx_pagespeed_statistics"
|
||||
GLOBAL_STATISTICS_HANDLER="ngx_pagespeed_global_statistics"
|
||||
MESSAGES_HANDLER="ngx_pagespeed_message"
|
||||
STATISTICS_URL=http://$PRIMARY_HOSTNAME/$STATISTICS_HANDLER
|
||||
GLOBAL_STATISTICS_URL=http://$PRIMARY_HOSTNAME/$GLOBAL_STATISTICS_HANDLER
|
||||
|
||||
# An expected failure can be indicated like: "~In-place resource optimization~"
|
||||
PAGESPEED_EXPECTED_FAILURES="
|
||||
~Cache purging with PageSpeed off in vhost, but on in directory.~
|
||||
~2-pass ipro with long ModPagespeedInPlaceRewriteDeadline~
|
||||
~3-pass ipro with short ModPagespeedInPlaceRewriteDeadline~
|
||||
"
|
||||
|
||||
if [ "$POSITION_AUX" = "true" ] ; then
|
||||
@@ -317,15 +352,14 @@ fi
|
||||
#
|
||||
# TODO(sligicki): When the prioritize critical css race condition is fixed, the
|
||||
# two prioritize_critical_css tests no longer need to be listed here.
|
||||
# TODO(oschaaf): Now that we wait after we send a SIGHUP for the new worker
|
||||
# process to handle requests, check if we can remove more from the expected
|
||||
# TODO(oschaaf): Now that we wait after we send a SIGHUP for the new worker
|
||||
# process to handle requests, check if we can remove more from the expected
|
||||
# failures here under valgrind.
|
||||
if $USE_VALGRIND; then
|
||||
PAGESPEED_EXPECTED_FAILURES+="
|
||||
~combine_css Maximum size of combined CSS.~
|
||||
~prioritize_critical_css~
|
||||
~prioritize_critical_css Able to read POST data from temp file.~
|
||||
~IPRO flow uses cache as expected.~
|
||||
~IPRO flow doesn't copy uncacheable resources multiple times.~
|
||||
~inline_unauthorized_resources allows unauthorized css selectors~
|
||||
"
|
||||
@@ -335,6 +369,7 @@ fi
|
||||
# wants different ones than we want, so we need to reset our positional args.
|
||||
set -- "$PRIMARY_HOSTNAME"
|
||||
source $SYSTEM_TEST_FILE
|
||||
source $REMOTE_CONFIG_TEST_FILE
|
||||
|
||||
# nginx-specific system tests
|
||||
|
||||
@@ -509,6 +544,17 @@ check $WGET_DUMP -O $FETCHED $HEADERS $URL
|
||||
# When enabled, we respect X-Forwarded-Proto and thus list base as https.
|
||||
check fgrep -q '<base href="https://' $FETCHED
|
||||
|
||||
start_test Relative redirects starting with a forward slash survive.
|
||||
URL=http://xfp.example.com/redirect
|
||||
# wget seems a bit hairy here, when it comes to handling (relative) redirects.
|
||||
# I could not get this test going with wget, and that is why curl is used here.
|
||||
# TODO(oschaaf): debug wget some more and swap out curl here.
|
||||
OUT=$(curl -v --proxy $SECONDARY_HOSTNAME $URL 2>&1)
|
||||
check_from "$OUT" egrep -q '301 Moved Permanently'
|
||||
# The important part is that we don't end up with an absolute location here.
|
||||
check_from "$OUT" grep -q 'Location: /mod_pagespeed_example'
|
||||
check_not_from "$OUT" grep -q 'Location: http'
|
||||
|
||||
# Test that loopback route fetcher works with vhosts not listening on
|
||||
# 127.0.0.1
|
||||
start_test IP choice for loopback fetches.
|
||||
@@ -534,7 +580,7 @@ fetch_until "$URL" "fgrep -c .pagespeed." 1 --header=Host:www.google.com
|
||||
|
||||
# If this accepts the Host header and fetches from google.com it will fail with
|
||||
# a 404. Instead it should use a loopback fetch and succeed.
|
||||
URL="$HOSTNAME/mod_pagespeed_example/.pagespeed.ce.8CfGBvwDhH.css"
|
||||
URL="$HOSTNAME/mod_pagespeed_example/styles/big.css.pagespeed.ce.8CfGBvwDhH.css"
|
||||
check wget -O /dev/null --header=Host:www.google.com "$URL"
|
||||
|
||||
start_test statistics load
|
||||
@@ -560,30 +606,93 @@ check test $(scrape_stat image_rewrite_total_original_bytes) -ge 10000
|
||||
# happens both before and after.
|
||||
start_test "Reload config"
|
||||
|
||||
function find_exactly_once {
|
||||
test $(grep -c "$1") -eq 1
|
||||
}
|
||||
|
||||
if [ "$RUN_CONTROLLER_TEST" = "on" ]; then
|
||||
function check_process_names() {
|
||||
if ! $USE_VALGRIND; then
|
||||
# There should be one babysitter and controller running. Under valgrind
|
||||
# process labels are confused, so skip the check then.
|
||||
|
||||
running=$(ps auxww | grep 'ngin[x]')
|
||||
check_from "$running" find_exactly_once "nginx: pagespeed babysitter"
|
||||
check_from "$running" find_exactly_once "nginx: pagespeed controller"
|
||||
fi
|
||||
}
|
||||
check_process_names
|
||||
fi
|
||||
|
||||
# Fire up some heavy load if ab is available to test a stressed reload.
|
||||
# TODO(oschaaf): make sure we wait for the new worker to get ready to accept
|
||||
# TODO(oschaaf): make sure we wait for the new worker to get ready to accept
|
||||
# requests.
|
||||
fire_ab_load
|
||||
|
||||
check wget $EXAMPLE_ROOT/styles/W.rewrite_css_images.css.pagespeed.cf.Hash.css \
|
||||
-O /dev/null
|
||||
URL="$EXAMPLE_ROOT/styles/W.rewrite_css_images.css.pagespeed.cf.Hash.css"
|
||||
check wget "$URL" -O /dev/null
|
||||
check_simple "$NGINX_EXECUTABLE" -s reload -c "$PAGESPEED_CONF"
|
||||
|
||||
# Wait for the new worker process with the new configuration to get ready, or
|
||||
# else the sudden reset of the shared mem statistics/cache might catch upcoming
|
||||
# tests unaware.
|
||||
while [ $(scrape_stat image_rewrite_total_original_bytes) -gt 0 ]
|
||||
do
|
||||
function wait_for_new_worker() {
|
||||
while [ $(scrape_stat image_rewrite_total_original_bytes) -gt 0 ]; do
|
||||
echo "Waiting for new worker to get ready..."
|
||||
sleep .1
|
||||
done
|
||||
|
||||
check wget $EXAMPLE_ROOT/styles/W.rewrite_css_images.css.pagespeed.cf.Hash.css \
|
||||
-O /dev/null
|
||||
done
|
||||
}
|
||||
wait_for_new_worker
|
||||
check wget "$URL" -O /dev/null
|
||||
if [ "$AB_PID" != "0" ]; then
|
||||
echo "Kill ab (pid: $AB_PID)"
|
||||
kill -s KILL $AB_PID &>/dev/null || true
|
||||
fi
|
||||
|
||||
# There should still be just one babysitter and controller running.
|
||||
if [ "$RUN_CONTROLLER_TEST" = "on" ]; then
|
||||
check_process_names
|
||||
|
||||
check grep "Writing a byte to a pipe to tell the old controller to exit." \
|
||||
$ERROR_LOG
|
||||
check grep "Root process is starting a new controller; shutting down." \
|
||||
$ERROR_LOG
|
||||
fi
|
||||
|
||||
start_test "Shared memory checkpointing"
|
||||
|
||||
# We do two tests here:
|
||||
# 1. Metadata cache: check that an IPRO'd image is still fully optimized after a
|
||||
# restart.
|
||||
# 2. Property cache: prioritize critical CSS persists beacon results across
|
||||
# restarts.
|
||||
|
||||
IPRO_URL="$EXAMPLE_ROOT/images/Cuppa.png"
|
||||
|
||||
# Checkpoint beacon results to disk if we haven't already.
|
||||
check wget "$IPRO_URL" -O /dev/null
|
||||
test_prioritize_critical_css
|
||||
sleep 2
|
||||
check wget "$IPRO_URL" -O /dev/null
|
||||
test_prioritize_critical_css
|
||||
|
||||
# Reload nginx again.
|
||||
check_simple "$NGINX_EXECUTABLE" -s reload -c "$PAGESPEED_CONF"
|
||||
wait_for_new_worker
|
||||
|
||||
# The image should be fully optimized.
|
||||
OUT=$($CURL -sS -D- -o/dev/null "$IPRO_URL")
|
||||
check_from "$OUT" grep ^X-Original-Content-Length:
|
||||
check_from "$OUT" grep ^Content-Length:
|
||||
content_length=$(echo "$OUT" | grep ^Content-Length: | grep -o [0-9]*)
|
||||
original_content_length=$(echo "$OUT" | grep ^X-Original-Content-Length: \
|
||||
| grep -o [0-9]*)
|
||||
check [ "$original_content_length" -gt "$content_length" ]
|
||||
|
||||
# The beacon responses are stored in the metadata cache, so this can only pass
|
||||
# if we persisted the metadata across restarts.
|
||||
test_prioritize_critical_css_final
|
||||
|
||||
# This is dependent upon having a beacon handler.
|
||||
test_filter add_instrumentation beacons load.
|
||||
|
||||
@@ -628,14 +737,14 @@ check touch "$SECONDARY_CACHE/cache.flush"
|
||||
check touch "$IPRO_CACHE/cache.flush"
|
||||
sleep 1
|
||||
|
||||
CACHE_TESTING_DIR="$SERVER_ROOT/mod_pagespeed_test/cache_flush/"
|
||||
CACHE_TESTING_DIR="$SERVER_ROOT/cache_flush/"
|
||||
CACHE_TESTING_TMPDIR="$CACHE_TESTING_DIR/$$"
|
||||
mkdir "$CACHE_TESTING_TMPDIR"
|
||||
cp "$CACHE_TESTING_DIR/cache_flush_test.html" "$CACHE_TESTING_TMPDIR/"
|
||||
CSS_FILE="$CACHE_TESTING_TMPDIR/update.css"
|
||||
echo ".class myclass { color: $COLOR0; }" > "$CSS_FILE"
|
||||
|
||||
URL_PATH="mod_pagespeed_test/cache_flush/$$/cache_flush_test.html"
|
||||
URL_PATH="cache_flush/$$/cache_flush_test.html"
|
||||
|
||||
URL="$SECONDARY_HOSTNAME/$URL_PATH"
|
||||
CACHE_A="--header=Host:cache_a.example.com"
|
||||
@@ -1079,7 +1188,7 @@ OUT=$($WGET_DUMP --header=Host:response-header-disable.example.com $URL)
|
||||
check_not_from "$OUT" egrep -qi 'addInstrumentationInit'
|
||||
|
||||
# TODO(jmaessen, jefftk): Port proxying tests, which rely on pointing a
|
||||
# MapProxyDomain construct at a static server. Perhaps localhost:8050 will
|
||||
# MapProxyDomain construct at a static server. Perhaps $HOSTNAME will
|
||||
# serve, but the tests need to use different urls then. For mod_pagespeed these
|
||||
# tests immediately precede the "scrape_secondary_stat" definition in
|
||||
# system_test.sh.
|
||||
@@ -1148,6 +1257,19 @@ HEADERS="--header=Host:script-filters.example.com"
|
||||
OUT=$($WGET_DUMP -S $HEADERS $URL 2>&1)
|
||||
check_not_from "$OUT" fgrep -qi 'addInstrumentationInit'
|
||||
|
||||
start_test Test that we can modify domain sharding via script variables.
|
||||
URL="http://$SECONDARY_HOSTNAME/mod_pagespeed_example/rewrite_images.html"
|
||||
HEADERS="--header=Host:script-filters.example.com"
|
||||
OUT=$($WGET_DUMP -S $HEADERS $URL 2>&1)
|
||||
check_from "$OUT" fgrep "http://cdn1.example.com"
|
||||
check_from "$OUT" fgrep "http://cdn2.example.com"
|
||||
|
||||
URL="http://$SECONDARY_HOSTNAME/mod_pagespeed_example/rewrite_images.html"
|
||||
HEADERS="--header=Host:script-filters.example.com --header=X-Script:1"
|
||||
OUT=$($WGET_DUMP -S $HEADERS $URL 2>&1)
|
||||
check_not_from "$OUT" fgrep "http://cdn1.example.com"
|
||||
check_not_from "$OUT" fgrep "http://cdn2.example.com"
|
||||
|
||||
if [ "$NATIVE_FETCHER" != "on" ]; then
|
||||
start_test Test that we can rewrite an HTTPS resource.
|
||||
fetch_until $TEST_ROOT/https_fetch/https_fetch.html \
|
||||
@@ -1210,13 +1332,48 @@ check_from "$OUT" fgrep -qi '404'
|
||||
MATCHES=$(echo "$OUT" | grep -c "Cache-Control: override") || true
|
||||
check [ $MATCHES -eq 1 ]
|
||||
|
||||
start_test Custom 404 does not crash.
|
||||
URL=http://custom404.example.com/mod_pagespeed_test/
|
||||
URL+=A.doesnotexist.css.pagespeed.cf.0.css
|
||||
# The 404 response makes wget exit with an error code, which we ignore.
|
||||
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1) || true
|
||||
# We ignored the exit code, check if we got a 404 response.
|
||||
check_from "$OUT" fgrep -qi '404'
|
||||
|
||||
start_test Single Vary: Accept-Encoding header in IPRO flow
|
||||
URL=http://psol-vary.example.com/mod_pagespeed_example/styles/index_style.css
|
||||
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
|
||||
# First hit will be recorded and passed on untouched
|
||||
MATCHES=$(echo "$OUT" | grep -c "Vary: Accept-Encoding") || true
|
||||
check [ $MATCHES -eq 1 ]
|
||||
|
||||
# Fetch until we get a fully optimized response
|
||||
http_proxy=$SECONDARY_HOSTNAME \
|
||||
fetch_until $URL "fgrep -c W/\"PSA" 1 --save-headers
|
||||
|
||||
# Test the optimized response.
|
||||
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
|
||||
MATCHES=$(echo "$OUT" | grep -c "Vary: Accept-Encoding") || true
|
||||
check [ $MATCHES -eq 1 ]
|
||||
|
||||
start_test Follow flushes can be turned off.
|
||||
echo "Check that FollowFlushes off outputs a single chunk"
|
||||
check_flushing noflush 5.4 1
|
||||
|
||||
start_test Special responses from php are handled OK.
|
||||
URL="http://special-response.example.com/A.foo.css.pagespeed.cf.0.css"
|
||||
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -S --content-on-error $URL 2>&1) || true
|
||||
check_from "$OUT" fgrep -qi '404'
|
||||
check_from "$OUT" fgrep -q "PHP with a call to flush"
|
||||
|
||||
start_test Shutting down.
|
||||
|
||||
# Fire up some heavy load if ab is available to test a stressed shutdown
|
||||
fire_ab_load
|
||||
|
||||
if $USE_VALGRIND; then
|
||||
kill -s quit $VALGRIND_PID
|
||||
# SIGQUIT requests a graceful shutdown.
|
||||
kill -s QUIT $VALGRIND_PID
|
||||
while pgrep memcheck > /dev/null; do sleep 1; done
|
||||
# Clear the previously set trap, we don't need it anymore.
|
||||
trap - EXIT
|
||||
@@ -1225,12 +1382,12 @@ if $USE_VALGRIND; then
|
||||
check_not [ -s "$TEST_TMP/valgrind.log" ]
|
||||
else
|
||||
check_simple "$NGINX_EXECUTABLE" -s quit -c "$PAGESPEED_CONF"
|
||||
while pgrep nginx > /dev/null; do sleep 1; done
|
||||
while pgrep -x nginx > /dev/null; do sleep 1; done
|
||||
fi
|
||||
|
||||
if [ "$AB_PID" != "0" ]; then
|
||||
echo "Kill ab (pid: $AB_PID)"
|
||||
killall -s KILL $AB_PID &>/dev/null || true
|
||||
kill -s KILL $AB_PID &>/dev/null || true
|
||||
fi
|
||||
|
||||
start_test Logged output looks healthy.
|
||||
@@ -1257,6 +1414,8 @@ OUT=$(cat "$ERROR_LOG" \
|
||||
| grep -v "\\[warn\\].*Resource based on.*ngx_pagespeed_statistics.*" \
|
||||
| grep -v "\\[warn\\].*Canceling 1 functions on sequence Shutdown.*" \
|
||||
| grep -v "\\[warn\\].*using uninitialized.*" \
|
||||
| grep -v "\\[warn\\].*Controller process .* exited with wait status 9" \
|
||||
| grep -v "\\[warn\\].*Controller process .* exited with wait status 15" \
|
||||
| grep -v "\\[error\\].*BadName*" \
|
||||
| grep -v "\\[error\\].*/mod_pagespeed/bad*" \
|
||||
| grep -v "\\[error\\].*doesnotexist.css.*" \
|
||||
@@ -1265,7 +1424,7 @@ OUT=$(cat "$ERROR_LOG" \
|
||||
| grep -v "\\[error\\].*forbidden.example.com*" \
|
||||
| grep -v "\\[error\\].*custom-paths.example.com*" \
|
||||
| grep -v "\\[error\\].*bogus_format*" \
|
||||
| grep -v "\\[error\\].*src/install/foo*" \
|
||||
| grep -v "\\[error\\].*/install/foo*" \
|
||||
| grep -v "\\[error\\].*recv() failed*" \
|
||||
| grep -v "\\[error\\].*send() failed*" \
|
||||
| grep -v "\\[error\\].*Invalid url requested: js_defer.js.*" \
|
||||
@@ -1279,9 +1438,18 @@ OUT=$(cat "$ERROR_LOG" \
|
||||
| grep -v "\\[error\\].*Could not create directories*" \
|
||||
| grep -v "\\[error\\].*opening temp file: No such file or directory.*" \
|
||||
| grep -v "\\[error\\].*remote\.cfg.*" \
|
||||
| grep -v "\\[error\\].*Slow read operation on file.*" \
|
||||
| grep -v "\\[error\\].*Slow ReadFile operation on file.*" \
|
||||
| grep -v "\\[error\\].*Slow write operation on file.*" \
|
||||
| grep -v "\\[warn\\].*remote\.cfg.*" \
|
||||
| grep -v "\\[warn\\].*end token not received.*" \
|
||||
| grep -v "\\[warn\\].*failed to hook next event.*" \
|
||||
| grep -v "\\[warn\\].*Fetch timed out:.*" \
|
||||
| grep -v "\\[warn\\].*Controller process .* exited with status code.*" \
|
||||
| grep -v "\\[warn\\].*Rewrite.*failed.*.pagespeed....0.foo.*" \
|
||||
| grep -v "\\[warn\\].*A.blue.css.*but cannot access the original.*" \
|
||||
| grep -v "\\[warn\\].*Adding function to sequence.*" \
|
||||
| grep -v "\\[warn\\].*special-response.*foo.css.*but cannot access the original.*" \
|
||||
|| true)
|
||||
|
||||
check [ -z "$OUT" ]
|
||||
|
||||
@@ -24,10 +24,13 @@ http {
|
||||
'"$http_user_agent"';
|
||||
access_log "@@ACCESS_LOG@@" cache;
|
||||
|
||||
# Don't put entries in the error log for 403s and 404s.
|
||||
log_not_found off;
|
||||
|
||||
proxy_cache_path "@@PROXY_CACHE@@" levels=1:2 keys_zone=htmlcache:60m inactive=90m max_size=50m;
|
||||
proxy_temp_path "@@TMP_PROXY_CACHE@@";
|
||||
|
||||
pagespeed ProcessScriptVariables on;
|
||||
pagespeed ProcessScriptVariables all;
|
||||
pagespeed StatisticsPath /ngx_pagespeed_statistics;
|
||||
pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics;
|
||||
pagespeed ConsolePath /pagespeed_console;
|
||||
@@ -60,6 +63,12 @@ http {
|
||||
pagespeed CreateSharedMemoryMetadataCache "@@SHM_CACHE@@" 8192;
|
||||
pagespeed BlockingRewriteKey psatest;
|
||||
|
||||
# We need to checkpoint more frequently than usual so that our checkpointing
|
||||
# test will definitly have seen one of these intervals and so not be flaky.
|
||||
# This needs to have a 1s interval because the checkpointing test has a 2s
|
||||
# sleep.
|
||||
pagespeed ShmMetadataCacheCheckpointIntervalSec 1;
|
||||
|
||||
# CriticalImagesBeaconEnabled is now on by default, but we disable in testing.
|
||||
# With this option enabled, the inline image system test will currently fail.
|
||||
# When critical image beaconing is enabled, only critical images are inlined.
|
||||
@@ -76,6 +85,9 @@ http {
|
||||
pagespeed StatisticsLogging on;
|
||||
pagespeed LogDir "@@TEST_TMP@@/logdir";
|
||||
|
||||
# Expanded to CentralControllerPort directive when RUN_CONTROLLER_TEST=on
|
||||
@@CONTROLLER@@
|
||||
|
||||
server {
|
||||
# Sets up a logical home-page server on
|
||||
# max-cacheable-content-length.example.com. This server is only used to
|
||||
@@ -92,6 +104,34 @@ http {
|
||||
pagespeed MaxCacheableContentLength 85;
|
||||
}
|
||||
|
||||
# Test how load from file handles maximum sizes.
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name lff-large-files.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed MaxCacheableContentLength 4096;
|
||||
pagespeed LoadFromFile
|
||||
"http://lff-large-files.example.com/"
|
||||
"@@SERVER_ROOT@@/";
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name lff-large-files-no-fallback.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed MaxCacheableContentLength 4096;
|
||||
# http://lff-large-files-no-fallback.example.com/foo.css won't load, because
|
||||
# we've configured a LoadFromFile pattern that doesn't match the path the
|
||||
# webserver would take.
|
||||
pagespeed LoadFromFile
|
||||
"http://lff-large-files-no-fallback.example.com/"
|
||||
"@@SERVER_ROOT@@/mod_pagespeed_example/styles/";
|
||||
}
|
||||
|
||||
pagespeed UseNativeFetcher "@@NATIVE_FETCHER@@";
|
||||
@@RESOLVER@@
|
||||
|
||||
@@ -134,7 +174,7 @@ http {
|
||||
# inline_images (ii), defer_javascript (dj), webp (jw) and lossless_webp
|
||||
# (ws).
|
||||
if ($http_user_agent ~*
|
||||
"Chrome/[2][3-9]+\.|Chrome/[[3-9][0-9]+\.|Chrome/[0-9]{3,}\.") {
|
||||
"Chrome/[2][3-9]+\.|Chrome/[3-9][0-9]+\.|Chrome/[0-9]{3,}\.") {
|
||||
set $ps_capability_list "ll,ii,dj,jw,ws:";
|
||||
}
|
||||
# Cache-fragment 3: This fragment contains (a) Desktop User-Agents that
|
||||
@@ -192,7 +232,7 @@ http {
|
||||
|
||||
# Block 6: Location block with proxy_cache directives.
|
||||
location /mod_pagespeed_test/cachable_rewritten_html/ {
|
||||
# 1: Upstream PageSpeed server is running at localhost:8050.
|
||||
# 1: Upstream PageSpeed server is running at localhost:@@PRIMARY_PORT@@.
|
||||
proxy_pass http://localhost:@@PRIMARY_PORT@@;
|
||||
# 2: Use htmlcache as the zone for caching.
|
||||
proxy_cache htmlcache;
|
||||
@@ -283,12 +323,31 @@ http {
|
||||
|
||||
pagespeed RunExperiment on;
|
||||
pagespeed AnalyticsID "123-45-6734";
|
||||
pagespeed UseAnalyticsJs false;
|
||||
pagespeed ExperimentVariable 2;
|
||||
pagespeed ExperimentSpec
|
||||
"id=7;enable=recompress_images;disable=convert_jpeg_to_progressive;percent=50";
|
||||
pagespeed ExperimentSpec "id=2;enable=recompress_images;percent=50";
|
||||
pagespeed ExperimentSpec "id=3;default;percent=0";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name contentexperiment.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed InPlaceResourceOptimization off;
|
||||
|
||||
pagespeed RunExperiment on;
|
||||
pagespeed AnalyticsID "123-45-6734";
|
||||
pagespeed UseAnalyticsJs false;
|
||||
pagespeed ExperimentVariable 2;
|
||||
pagespeed ExperimentSpec
|
||||
"id=7;enable=recompress_images;disable=convert_jpeg_to_progressive;percent=50;options=ContentExperimentID=ID:H1BpS2TCRFmJzZgjwyeBHQ,ContentExperimentVariantID=111";
|
||||
pagespeed ExperimentSpec
|
||||
"id=2;enable=recompress_images;percent=50;options=ContentExperimentID=ID:H1BpS2TCRFmJzZgjwyeBHQ,ContentExperimentVariantID=222";
|
||||
pagespeed ExperimentSpec
|
||||
"id=3;default;percent=0;options=ContentExperimentID=123,ContentExperimentVariantID=333";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
@@ -313,6 +372,29 @@ http {
|
||||
"id=1;percent=100;matches_device_type=mobile;enable=recompress_images";
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name experiment.ajax.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel CoreFilters;
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed JsInlineMaxBytes 1;
|
||||
pagespeed RunExperiment on;
|
||||
pagespeed UseAnalyticsJs false;
|
||||
pagespeed ExperimentSpec "id=1;percent=100;level=CoreFilters;enable=collapse_whitespace;options=JsInlineMaxBytes=1";
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name ajax.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel CoreFilters;
|
||||
pagespeed EnableFilters add_instrumentation;
|
||||
pagespeed JsInlineMaxBytes 1;
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
@@ -542,6 +624,10 @@ http {
|
||||
pagespeed UrlValuedAttribute img alt-src Image;
|
||||
pagespeed UrlValuedAttribute video alt-a Image;
|
||||
pagespeed UrlValuedAttribute video alt-b Image;
|
||||
pagespeed UrlValuedAttribute link data-stylesheet Stylesheet;
|
||||
pagespeed UrlValuedAttribute span data-stylesheet-a Stylesheet;
|
||||
pagespeed UrlValuedAttribute span data-stylesheet-b Stylesheet;
|
||||
pagespeed UrlValuedAttribute span data-stylesheet-c Stylesheet;
|
||||
|
||||
# Also test that we can redefine spec-defined attributes.
|
||||
pagespeed UrlValuedAttribute blockquote cite Image;
|
||||
@@ -599,8 +685,23 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name xfp.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed RespectXForwardedProto on;
|
||||
|
||||
location /redirecting_origin {
|
||||
pagespeed off;
|
||||
# Hack: we clear the response headers using headers_more.
|
||||
# If we don't, nginx will add an extra empty Location: headers here.
|
||||
# It is kind of hard to get nginx to generate a relative location header
|
||||
# that starts with "/".
|
||||
more_clear_headers 'Location';
|
||||
add_header Location /mod_pagespeed_example;
|
||||
return 301;
|
||||
}
|
||||
location /redirect {
|
||||
proxy_method GET;
|
||||
proxy_pass http://127.0.0.1:@@SECONDARY_PORT@@/redirecting_origin;
|
||||
proxy_set_header "Host" "xfp.example.com";
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -666,7 +767,44 @@ http {
|
||||
pagespeed EnableFilters rewrite_images,rewrite_css;
|
||||
pagespeed EnableFilters convert_to_webp_lossless;
|
||||
pagespeed EnableFilters in_place_optimize_for_browser;
|
||||
pagespeed JpegRecompressionQuality 75;
|
||||
pagespeed WebpRecompressionQuality 70;
|
||||
pagespeed InPlaceResourceOptimization on;
|
||||
pagespeed AllowVaryOn "Accept";
|
||||
pagespeed FileCachePath "@@IPRO_CACHE@@";
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name ipro-for-browser-vary-on-auto.example.com;
|
||||
root "@@SERVER_ROOT@@/mod_pagespeed_example";
|
||||
pagespeed EnableFilters rewrite_images,rewrite_css;
|
||||
pagespeed EnableFilters convert_to_webp_animated;
|
||||
pagespeed EnableFilters convert_to_webp_lossless;
|
||||
pagespeed EnableFilters in_place_optimize_for_browser;
|
||||
pagespeed InPlaceResourceOptimization on;
|
||||
# pagespeed AllowVaryOn "Accept"; # Default is "Auto".
|
||||
pagespeed ImageRecompressionQuality 90;
|
||||
pagespeed JpegRecompressionQuality 75;
|
||||
pagespeed JpegRecompressionQualityForSmallScreens 55;
|
||||
pagespeed JpegQualityForSaveData 35;
|
||||
pagespeed WebpRecompressionQuality 70;
|
||||
pagespeed WebpRecompressionQualityForSmallScreens 50;
|
||||
pagespeed WebpQualityForSaveData 30;
|
||||
pagespeed WebpAnimatedRecompressionQuality 60;
|
||||
pagespeed FileCachePath "@@IPRO_CACHE@@";
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name ipro-for-browser-vary-on-none.example.com;
|
||||
root "@@SERVER_ROOT@@/mod_pagespeed_example";
|
||||
pagespeed EnableFilters rewrite_images,in_place_optimize_for_browser;
|
||||
pagespeed InPlaceResourceOptimization on;
|
||||
pagespeed AllowVaryOn "None";
|
||||
pagespeed ImageRecompressionQuality 75;
|
||||
pagespeed FileCachePath "@@IPRO_CACHE@@";
|
||||
}
|
||||
|
||||
@@ -734,7 +872,7 @@ http {
|
||||
server_name www.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@;
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@/;
|
||||
pagespeed MapRewriteDomain cdn.example.com origin.example.com;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters rewrite_css,rewrite_images;
|
||||
@@ -748,7 +886,7 @@ http {
|
||||
server_name origin.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@;
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@/;
|
||||
pagespeed MapRewriteDomain cdn.example.com origin.example.com;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters rewrite_css,rewrite_images;
|
||||
@@ -762,7 +900,7 @@ http {
|
||||
server_name cdn.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@;
|
||||
pagespeed LoadFromFile http://cdn.example.com @@SERVER_ROOT@@/;
|
||||
pagespeed MapRewriteDomain cdn.example.com origin.example.com;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters rewrite_css,rewrite_images;
|
||||
@@ -816,6 +954,13 @@ http {
|
||||
pagespeed ConsolePath /custom_pagespeed_console;
|
||||
pagespeed MessagesPath /custom_pagespeed_message;
|
||||
pagespeed AdminPath /custom_pagespeed_admin;
|
||||
|
||||
pagespeed StatisticsDomains Allow *;
|
||||
pagespeed GlobalStatisticsDomains Allow *;
|
||||
pagespeed MessagesDomains Allow *;
|
||||
pagespeed ConsoleDomains Allow *;
|
||||
pagespeed AdminDomains Allow *;
|
||||
pagespeed GlobalAdminDomains Allow *;
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -823,6 +968,13 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name inherit-paths.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed StatisticsDomains Allow *;
|
||||
pagespeed GlobalStatisticsDomains Allow *;
|
||||
pagespeed MessagesDomains Allow *;
|
||||
pagespeed ConsoleDomains Allow *;
|
||||
pagespeed AdminDomains Allow *;
|
||||
pagespeed GlobalAdminDomains Allow *;
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -916,6 +1068,14 @@ http {
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name custom404.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
error_page 404 /404.html;
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
@@ -1084,7 +1244,7 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT1@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/standard";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
@@ -1092,7 +1252,8 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-partially-invalid.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT2@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl
|
||||
"http://127.0.0.1:@@RCPORT@@/partly-invalid";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
@@ -1100,7 +1261,7 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-invalid.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT3@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/invalid";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
@@ -1108,7 +1269,7 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-failed-fetch.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT5@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/fail-future";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
@@ -1116,7 +1277,7 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-slow-fetch.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT6@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/timeout";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
@@ -1124,9 +1285,79 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-experiment.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT7@@/remote.cfg";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/experiment";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-slightly-slow-fetch.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl
|
||||
"http://127.0.0.1:@@RCPORT@@/slightly-slow";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-slightly-slow-expired-fetch.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/slow-expired";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-forbidden.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT@@/forbidden";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name remote-config-initially-forbidden.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed RemoteConfigurationUrl
|
||||
"http://127.0.0.1:@@RCPORT@@/forbidden-once";
|
||||
pagespeed RemoteConfigurationTimeoutMs 1500;
|
||||
}
|
||||
|
||||
# Test that pagespeed is disabled when sendfile headers are present.
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name uses-sendfile.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed EnableFilters inline_javascript,rewrite_javascript;
|
||||
add_header 'X-Sendfile' 'blablabla';
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name doesnt-sendfile.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed EnableFilters inline_javascript,rewrite_javascript;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name uses-xaccelredirect.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed EnableFilters inline_javascript,rewrite_javascript;
|
||||
add_header 'X-Accel-Redirect' 'blablabla';
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name map-static-domain.example.com;
|
||||
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
|
||||
pagespeed MapRewriteDomain http://static-cdn.example.com
|
||||
http://map-static-domain.example.com;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters defer_javascript,rewrite_domains;
|
||||
}
|
||||
|
||||
# Proxy + IPRO a gzip'd file for testing Issue 896.
|
||||
server {
|
||||
@@ -1145,6 +1376,44 @@ http {
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name compressedcache.example.com;
|
||||
pagespeed on;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed EnableFilters rewrite_css;
|
||||
pagespeed HttpCacheCompressionLevel 9;
|
||||
location ~ \.php$ {
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_buffering off;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name uncompressedcache.example.com;
|
||||
pagespeed on;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed EnableFilters rewrite_css;
|
||||
pagespeed HttpCacheCompressionLevel 0;
|
||||
location ~ \.php$ {
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_buffering off;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
@@ -1207,7 +1476,7 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name proxy-post-origin.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
root "@@SERVER_ROOT@@";
|
||||
root "@@SERVER_ROOT@@/";
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -1225,13 +1494,17 @@ http {
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name script-filters.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
root "@@SERVER_ROOT@@";
|
||||
root "@@SERVER_ROOT@@/";
|
||||
set $filters "";
|
||||
set $domain_shards "cdn1.example.com,cdn2.example.com";
|
||||
if ($http_X_Script) {
|
||||
set $filters "add_instrumentation";
|
||||
set $domain_shards "";
|
||||
}
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters rewrite_domains;
|
||||
pagespeed EnableFilters $filters;
|
||||
pagespeed ShardDomain script-filters.example.com "$domain_shards";
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -1243,7 +1516,7 @@ http {
|
||||
pagespeed EnableCachePurge on;
|
||||
|
||||
pagespeed PurgeMethod PURGE;
|
||||
root "@@SERVER_ROOT@@/mod_pagespeed_test/purge";
|
||||
root "@@SERVER_ROOT@@/purge";
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@_purge";
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
@@ -1259,7 +1532,7 @@ http {
|
||||
pagespeed EnableCachePurge on;
|
||||
|
||||
pagespeed PurgeMethod PURGE;
|
||||
root "@@SERVER_ROOT@@/mod_pagespeed_test/purge";
|
||||
root "@@SERVER_ROOT@@/purge";
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@_dir_on";
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
@@ -1277,7 +1550,7 @@ http {
|
||||
pagespeed InPlaceResourceOptimization off;
|
||||
pagespeed off;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
root "@@SERVER_ROOT@@";
|
||||
root "@@SERVER_ROOT@@/";
|
||||
location /mod_pagespeed_test/nostore {
|
||||
add_header "Cache-Control" "max-age=12345";
|
||||
add_header "Cache-Control" "public, no-store";
|
||||
@@ -1292,7 +1565,7 @@ http {
|
||||
pagespeed InPlaceResourceOptimization off;
|
||||
pagespeed off;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
root "@@SERVER_ROOT@@";
|
||||
root "@@SERVER_ROOT@@/";
|
||||
location / {
|
||||
add_header "PageSpeedFilters" "add_instrumentation";
|
||||
}
|
||||
@@ -1305,12 +1578,177 @@ http {
|
||||
pagespeed InPlaceResourceOptimization off;
|
||||
pagespeed off;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
root "@@SERVER_ROOT@@";
|
||||
root "@@SERVER_ROOT@@/";
|
||||
location / {
|
||||
add_header "PageSpeed" "off";
|
||||
}
|
||||
}
|
||||
|
||||
pagespeed MessagesDomains Allow messages-allowed.example.com;
|
||||
pagespeed MessagesDomains Allow cleared-inherited.example.com;
|
||||
pagespeed MessagesDomains Allow cleared-inherited-reallowed.example.com;
|
||||
pagespeed MessagesDomains Allow more-messages-allowed.example.com;
|
||||
pagespeed MessagesDomains Allow anything-*-wildcard.example.com;
|
||||
pagespeed MessagesDomains Allow localhost;
|
||||
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name messages-allowed.example.com
|
||||
messages-not-allowed.example.com
|
||||
more-messages-allowed.example.com
|
||||
anything-a-wildcard.example.com
|
||||
anything-b-wildcard.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name messages-still-not-allowed.example.com
|
||||
but-this-message-allowed.example.com
|
||||
and-this-one.example.com;
|
||||
pagespeed MessagesDomains Allow but-this-message-allowed.example.com;
|
||||
pagespeed MessagesDomains Allow and-this-one.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name cleared-inherited.example.com
|
||||
cleared-inherited-reallowed.example.com
|
||||
messages-allowed-at-vhost.example.com
|
||||
messages-not-allowed-at-vhost.example.com
|
||||
anything-c-wildcard.example.com;
|
||||
pagespeed MessagesDomains Disallow *;
|
||||
pagespeed MessagesDomains Allow cleared-inherited-reallowed.example.com;
|
||||
pagespeed MessagesDomains Allow messages-allowed-at-vhost.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name cleared-inherited-unlisted.example.com;
|
||||
pagespeed MessagesDomains Allow *;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
server_name nothing-allowed.example.com;
|
||||
pagespeed MessagesDomains Disallow *;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
server_name nothing-explicitly-allowed.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name everything-explicitly-allowed.example.com
|
||||
everything-explicitly-allowed-but-aliased.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
|
||||
pagespeed StatisticsDomains Allow everything-explicitly-allowed.example.com;
|
||||
pagespeed GlobalStatisticsDomains
|
||||
Allow everything-explicitly-allowed.example.com;
|
||||
pagespeed MessagesDomains Allow everything-explicitly-allowed.example.com;
|
||||
pagespeed ConsoleDomains Allow everything-explicitly-allowed.example.com;
|
||||
pagespeed AdminDomains Allow everything-explicitly-allowed.example.com;
|
||||
pagespeed GlobalAdminDomains
|
||||
Allow everything-explicitly-allowed.example.com;
|
||||
}
|
||||
server {
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name psol-vary.example.com;
|
||||
pagespeed on;
|
||||
pagespeed InPlaceResourceOptimization on;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
}
|
||||
server {
|
||||
pagespeed on;
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name flush.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed RewriteDeadlinePerFlushMs 1;
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_buffering off;
|
||||
}
|
||||
}
|
||||
server {
|
||||
pagespeed on;
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name noflush.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed RewriteDeadlinePerFlushMs 1;
|
||||
pagespeed FollowFlushes off;
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_buffering off;
|
||||
}
|
||||
}
|
||||
server {
|
||||
pagespeed on;
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name special-response.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
error_page 404 /mod_pagespeed_test/php_withflush.php;
|
||||
location ~ \.php$ {
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
}
|
||||
}
|
||||
server {
|
||||
pagespeed on;
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name debug-filters.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@";
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters debug;
|
||||
}
|
||||
server {
|
||||
pagespeed on;
|
||||
listen @@SECONDARY_PORT@@;
|
||||
listen [::]:@@SECONDARY_PORT@@;
|
||||
server_name broken-fetch.example.com;
|
||||
pagespeed FileCachePath "@@FILE_CACHE@@/broken-fetch";
|
||||
|
||||
# Set up a fetch proxy that will 404 every request.
|
||||
pagespeed FetchProxy "brokenfetch.example.com:1111";
|
||||
|
||||
# Prevent loopback fetch by explicitly authorizing the domain. Loopback
|
||||
# fetches would work, and for this test, we're trying to have fetches fail,
|
||||
# so they are instead picked up by the ipro recorder.
|
||||
pagespeed Domain http://broken-fetch.example.com;
|
||||
pagespeed InPlaceResourceOptimization on;
|
||||
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
pagespeed EnableFilters rewrite_javascript;
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed CriticalImagesBeaconEnabled false;
|
||||
}
|
||||
server {
|
||||
listen @@PRIMARY_PORT@@;
|
||||
listen [::]:@@PRIMARY_PORT@@;
|
||||
@@ -1324,6 +1762,14 @@ http {
|
||||
}
|
||||
|
||||
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
|
||||
# TODO(oschaaf): The following breaks nginx starting up, as the bad header
|
||||
# value gets rejected during configuration parsing. However, we can't easily
|
||||
# build a test for that right now.
|
||||
# pagespeed AddResourceHeader "X-Fo\n\no" "Bar";
|
||||
# pagespeed AddResourceHeader "X-Foo" "Ba\nr";
|
||||
|
||||
# For testing that AddResourceHeader gets passed through
|
||||
pagespeed AddResourceHeader "X-Foo" "Bar";
|
||||
add_header "" "";
|
||||
}
|
||||
|
||||
@@ -1375,6 +1821,16 @@ http {
|
||||
pagespeed Library 43 1o978_K0_LNE5_ystNklf
|
||||
http://www.modpagespeed.com/rewrite_javascript.js;
|
||||
pagespeed RetainComment " google_ad_section*";
|
||||
pagespeed PermitIdsForCssCombining "allowed-to-combine-1-*";
|
||||
pagespeed PermitIdsForCssCombining "allowed-to-combine-2-*";
|
||||
|
||||
# Test proxying of non-.pagespeed. resources.
|
||||
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/modpagespeed_http
|
||||
http://@@PAGESPEED_TEST_HOST@@/do_not_modify;
|
||||
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/content_type_present
|
||||
http://@@PAGESPEED_TEST_HOST@@:8091;
|
||||
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/content_type_absent
|
||||
http://@@PAGESPEED_TEST_HOST@@:8092;
|
||||
|
||||
add_header X-Extra-Header 1;
|
||||
|
||||
@@ -1494,6 +1950,77 @@ http {
|
||||
expires 5m;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/example.json {
|
||||
expires 10m;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/cc200/ {
|
||||
add_header "Cache-Control" "max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200p/ {
|
||||
add_header "Cache-Control" "private, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200nc/ {
|
||||
add_header "Cache-Control" "no-cache, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200ns/ {
|
||||
add_header "Cache-Control" "no-store, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200nt/ {
|
||||
add_header "Cache-Control" "no-transform, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma5/ {
|
||||
add_header "Cache-Control" "s-maxage=5, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50/ {
|
||||
add_header "Cache-Control" "s-maxage=50, max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50nsp/ {
|
||||
add_header "Cache-Control" "s-maxage=50,max-age=200";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc9/ {
|
||||
add_header "Cache-Control" "max-age=9";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200cc9/ {
|
||||
add_header "Cache-Control" "max-age=200, max-age=9";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50sma5/ {
|
||||
add_header "Cache-Control" "max-age=200, s-maxage=50, s-maxage=5";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50cc9/ {
|
||||
add_header "Cache-Control" "max-age=200, s-maxage=50, max-age=9";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50cc9nsp/ {
|
||||
add_header "Cache-Control" "max-age=200,s-maxage=50,max-age=9";
|
||||
}
|
||||
location /mod_pagespeed_test/ipro/cc200sma50sma51/ {
|
||||
add_header "Cache-Control" "max-age=200, s-maxage=50, s-maxage=51";
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/wait/ {
|
||||
# TODO(jmarantz): ModPagespeedInPlaceWaitForOptimized should be superfluous,
|
||||
# or made equivalent to ModPagespeedInPlaceRewriteDeadlineMs -1, which waits
|
||||
# forever. Otherwise ModPagespeedInPlaceRewriteDeadlineMs should just have
|
||||
# the specified deadline.
|
||||
# # See https://github.com/pagespeed/mod_pagespeed/issues/1171 for more
|
||||
# detailed discussion.
|
||||
pagespeed InPlaceWaitForOptimized on;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/wait/long/ {
|
||||
# Make the deadline long here for valgrind tests. We could
|
||||
# conditionalize this.
|
||||
pagespeed InPlaceRewriteDeadlineMs 10000;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/wait/short/ {
|
||||
pagespeed EnableFilters in_place_optimize_for_browser;
|
||||
|
||||
# Make the deadline short here as we expect to always miss it
|
||||
# in tests.
|
||||
pagespeed InPlaceRewriteDeadlineMs 1;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/instant/wait/ {
|
||||
pagespeed InPlaceWaitForOptimized on;
|
||||
|
||||
@@ -1510,14 +2037,16 @@ http {
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/instant/deadline/ {
|
||||
pagespeed InPlaceRewriteDeadlineMs -1;
|
||||
set $ps_deadline -1;
|
||||
pagespeed ImageRecompressionQuality $ps_deadline;
|
||||
pagespeed InPlaceRewriteDeadlineMs $ps_deadline;
|
||||
}
|
||||
|
||||
# Test to make sure that user-authenticated resources do not get cached and
|
||||
# optimized.
|
||||
location /mod_pagespeed_test/auth/ {
|
||||
auth_basic "Restricted";
|
||||
auth_basic_user_file "@@SERVER_ROOT@@mod_pagespeed_test/auth/passwd.conf";
|
||||
auth_basic_user_file "@@SERVER_ROOT@@/mod_pagespeed_test/auth/passwd.conf";
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/ipro/cookie/ {
|
||||
@@ -1558,11 +2087,31 @@ http {
|
||||
pagespeed FetchHttps enable;
|
||||
location /mod_pagespeed_test/https_fetch/ {
|
||||
pagespeed DisableFilters inline_images;
|
||||
set $ps_gstatic "https://www.gstatic.com/psa/static";
|
||||
pagespeed MapProxyDomain
|
||||
http://localhost:@@PRIMARY_PORT@@/https_gstatic_dot_com
|
||||
https://www.gstatic.com/psa/static;
|
||||
$ps_gstatic;
|
||||
}
|
||||
|
||||
location /mod_pagespeed_test/strip_subresource_hints/default/ {
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed RewriteLevel CoreFilters;
|
||||
pagespeed DisAllow *dontrewriteme*;
|
||||
}
|
||||
location /mod_pagespeed_test/strip_subresource_hints/default_passthrough/ {
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed RewriteLevel PassThrough;
|
||||
}
|
||||
location /mod_pagespeed_test/strip_subresource_hints/preserve_on/ {
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed PreserveSubresourceHints on;
|
||||
pagespeed RewriteLevel CoreFilters;
|
||||
}
|
||||
location /mod_pagespeed_test/strip_subresource_hints/preserve_off/ {
|
||||
pagespeed DisableFilters add_instrumentation;
|
||||
pagespeed PreserveSubresourceHints off;
|
||||
pagespeed RewriteLevel CoreFilters;
|
||||
}
|
||||
# $host implicitly tests script variable support. I'd love to test it more
|
||||
# directly, but so far this is the best I've come up with and duplicating
|
||||
# the test doesn't seem to make sense.
|
||||
@@ -1570,6 +2119,11 @@ http {
|
||||
"http://$host:@@PRIMARY_PORT@@/mod_pagespeed_test/ipro/instant/"
|
||||
"@@SERVER_ROOT@@/mod_pagespeed_test/ipro/instant/";
|
||||
|
||||
location /mod_pagespeed_test/public/ {
|
||||
add_header "Cache-Control" "public, max-age=600";
|
||||
pagespeed PreserveUrlRelativity off;
|
||||
}
|
||||
|
||||
pagespeed EnableFilters remove_comments;
|
||||
|
||||
# Test LoadFromFile mapping by mapping one dir to another.
|
||||
@@ -1583,7 +2137,6 @@ http {
|
||||
"@@SERVER_ROOT@@/mod_pagespeed_test/load_from_file/file_dir/httponly/";
|
||||
pagespeed LoadFromFileRuleMatch Disallow \.ssp.css$ps_dollar;
|
||||
pagespeed LoadFromFileRuleMatch Allow exception\.ssp\.css$ps_dollar;
|
||||
|
||||
#charset koi8-r;
|
||||
|
||||
#access_log logs/host.access.log main;
|
||||
@@ -1630,6 +2183,7 @@ http {
|
||||
image/svg+xml svg svgz;
|
||||
image/webp webp;
|
||||
|
||||
application/json json;
|
||||
application/java-archive jar war ear;
|
||||
application/mac-binhex40 hqx;
|
||||
application/msword doc;
|
||||
|
||||
+20
-24
@@ -23,10 +23,12 @@
|
||||
# Exits with status 2 if command line args are wrong.
|
||||
#
|
||||
# Usage:
|
||||
# ./run_tests.sh primary_port secondary_port mod_pagespeed_dir
|
||||
# Example:
|
||||
# ./run_tests.sh 8050 8051 /path/to/mod_pagespeed
|
||||
# ./run_tests.sh /path/to/mod_pagespeed /path/to/nginx/binary
|
||||
#
|
||||
# By default the test script uses several ports. If you have a port conflict
|
||||
# and need to override one you can do that by setting the relevant environment
|
||||
# variable. For example:
|
||||
# PRIMARY_PORT=1234 ./run_tests.sh /.../mod_pagespeed /.../nginx/binary
|
||||
|
||||
# Normally we test only with the native fetcher off. Set
|
||||
# TEST_NATIVE_FETCHER=true to also test the native fetcher, set
|
||||
@@ -43,40 +45,34 @@ RUN_TESTS=${RUN_TESTS:-true}
|
||||
# true.
|
||||
USE_VALGRIND=${USE_VALGRIND:-false}
|
||||
|
||||
if [ "$#" -ne 4 ] ; then
|
||||
echo "Usage: $0 primary_port secondary_port mod_pagespeed_dir"
|
||||
echo " nginx_executable"
|
||||
if [ "$#" -ne 2 ] ; then
|
||||
echo "Usage: $0 mod_pagespeed_dir nginx_executable"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PRIMARY_PORT="$1"
|
||||
SECONDARY_PORT="$2"
|
||||
MOD_PAGESPEED_DIR="$3"
|
||||
NGINX_EXECUTABLE="$4"
|
||||
RCPORT1=9991
|
||||
RCPORT2=9992
|
||||
RCPORT3=9993
|
||||
RCPORT4=9994
|
||||
RCPORT5=9995
|
||||
RCPORT6=9996
|
||||
RCPORT7=9997
|
||||
MOD_PAGESPEED_DIR="$1"
|
||||
NGINX_EXECUTABLE="$2"
|
||||
|
||||
: ${PRIMARY_PORT:=8050}
|
||||
: ${SECONDARY_PORT:=8051}
|
||||
: ${CONTROLLER_PORT:=8053}
|
||||
: ${RCPORT:=9991}
|
||||
: ${PAGESPEED_TEST_HOST:=selfsigned.modpagespeed.com}
|
||||
: ${PHP_PORT:=9000}
|
||||
|
||||
this_dir="$( cd $(dirname "$0") && pwd)"
|
||||
|
||||
function run_test_checking_failure() {
|
||||
"$MOD_PAGESPEED_DIR/install/start_php.sh" "$PHP_PORT"
|
||||
USE_VALGRIND="$USE_VALGRIND" \
|
||||
PRIMARY_PORT="$PRIMARY_PORT" \
|
||||
SECONDARY_PORT="$SECONDARY_PORT" \
|
||||
MOD_PAGESPEED_DIR="$MOD_PAGESPEED_DIR" \
|
||||
NGINX_EXECUTABLE="$NGINX_EXECUTABLE" \
|
||||
PAGESPEED_TEST_HOST="$PAGESPEED_TEST_HOST" \
|
||||
RUN_TESTS="$RUN_TESTS" \
|
||||
RCPORT1="$RCPORT1" \
|
||||
RCPORT2="$RCPORT2" \
|
||||
RCPORT3="$RCPORT3" \
|
||||
RCPORT4="$RCPORT4" \
|
||||
RCPORT5="$RCPORT5" \
|
||||
RCPORT6="$RCPORT6" \
|
||||
RCPORT7="$RCPORT7" \
|
||||
CONTROLLER_PORT="$CONTROLLER_PORT" \
|
||||
RCPORT="$RCPORT" \
|
||||
bash "$this_dir/nginx_system_test.sh"
|
||||
STATUS=$?
|
||||
echo "With $@ setup."
|
||||
|
||||
@@ -163,3 +163,31 @@
|
||||
fun:_ZN3re23DFA10AddToQueueEPNS0_5WorkqEij
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
<re2 uninitialized value in optimized code>
|
||||
Memcheck:Value8
|
||||
fun:_ZNK3re210SparseSetTIvE8containsEi
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
<re2 uninitialized value in optimized code>
|
||||
Memcheck:Cond
|
||||
fun:_ZNK3re210SparseSetTIvE8containsEi
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
<re2 uninitialized value in optimized code>
|
||||
Memcheck:Value8
|
||||
fun:_ZNK3re211SparseArrayIiE9has_indexEi
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
<re2 uninitialized value in optimized code>
|
||||
Memcheck:Cond
|
||||
fun:_ZNK3re211SparseArrayIiE9has_indexEi
|
||||
...
|
||||
}
|
||||
|
||||
+1
Submodule testing-dependencies/headers-more-nginx-module added at 30fb25901c
Submodule
+1
Submodule testing-dependencies/mod_pagespeed added at f61c3a5c4e
Submodule
+1
Submodule testing-dependencies/nginx added at 6917d29d40
Submodule
+1
Submodule testing-dependencies/ngx_cache_purge added at 331fe43e8d
Submodule
+1
Submodule testing-dependencies/ngx_devel_kit added at e443262071
+1
Submodule testing-dependencies/set-misc-nginx-module added at 72be6512cf
Reference in New Issue
Block a user