Compare commits

..

265 Commits

Author SHA1 Message Date
Otto van der Schaaf e6931ba037 Release version 1.12.34.3 2017-09-28 14:48:58 +02:00
Otto van der Schaaf f4124cb5d1 Correct the ngx_pagespeed-specific release version 2017-09-28 14:47:22 +02:00
Otto van der Schaaf cf57d720e0 nginx-1.13.4: use preprocessor define instead of const for comparison
Address a mistake I made in https://github.com/pagespeed/ngx_pagespeed/pull/1458

While testing the draft for 1.12.34.3 I noticed that older nginx
versions would fail to compile. Switch kNginx13_1_4 to a #define so we
can use it to properly compare.

Note: this will have to be backported to master
2017-09-28 14:47:22 +02:00
PikachuEXE 6320f71a7c Fix compiling issue with older nginx (#1470) 2017-09-28 14:47:22 +02:00
Otto van der Schaaf f5eccb7618 Adress @jmarantz his comment from #1453's review (#1458)
PR #1453 was merged too soon, using this PR to address
https://github.com/pagespeed/ngx_pagespeed/pull/1453#discussion_r134222719

(Sorry Josh!)
2017-09-28 14:47:22 +02:00
Otto van der Schaaf 257c2bcb54 nginx 1.13.4: Fix compilation error (#1453)
* Compilation of ngx_pagespeed broke with the following commit in
nginx: https://github.com/nginx/nginx/commit/129b06dc5dfab7b4513a4f274b3778cd9b8a6a22
This change intends to unbreak it while maintaining backwards
compatibility.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1451
2017-09-28 14:47:22 +02:00
Otto van der Schaaf b70c70ecb9 Revert "stop crashing when unplugged" (#1400)
This is just for the branch. 1.12.34.2 will be marked as
stable, backing out this change avoids having to test a new
beta.

This reverts commit 149c47ace4.
2017-03-30 22:28:09 +02:00
Jeff Kaufman 149c47ace4 stop crashing when unplugged 2017-01-19 13:49:59 -05:00
Jeff Kaufman 0ca15283c8 travis: send emails to new pagespeed-ci group instead of individual devs 2016-12-19 13:47:02 -05:00
Jeff Kaufman f3c64ca8a2 Version 1.12.34.2 2016-12-14 10:26:08 -05:00
Jeff Kaufman ecd323ea60 config: use Release binaries when building with --with-debug if that's all that's available (#1332)
* config: use Release binaries when building with --with-debug if that's all that's available

* prompt the user before going ahead and using release binaries

* exit 1, reword message
2016-12-14 10:15:35 -05:00
Steve Hill a1fc37a9f2 Version 1.12.34.1 2016-12-06 13:29:20 -05:00
hillsp 4c51a5ce60 Add format_binary_url.sh (#1331) 2016-12-06 13:25:36 -05:00
hillsp 0dfc12ffe2 Delete prepare_psol.sh (#1310)
Replaced with install/build_psol.sh  in mod_pagespeed.
2016-12-06 12:07:44 -05:00
hillsp f7502b1b40 Mark CentralControllerPort as Experimental (#1326) 2016-11-30 14:43:55 -05:00
Joshua Marantz 617f0e6bee Add a new server-name to help test a repro for broken pagespeed resources (#1324)
after ipro-recorded optimations.

for https://github.com/pagespeed/mod_pagespeed/issues/1145
and https://github.com/pagespeed/ngx_pagespeed/issues/1319 .
2016-11-21 14:11:56 -05:00
hillsp 42115f54da Need clone --recursive 2016-11-21 10:49:59 -05:00
hillsp 3d9f2aee37 First pass at modernising travis.yml 2016-11-21 10:38:05 -05:00
Joshua Marantz d77c7eac17 test config for disabling rewriters in ajax (#1320) 2016-11-14 08:09:44 -05:00
Jeff Kaufman 97134d951e test: run_tests.sh should just assume 8050 and 8051 (#1315)
Right now run_tests.sh assumes it has 8053 and 9991 without causing any
problems.  Start assuming we have 8050 and 8051 as well instead of
requiring people to pass them in.
2016-11-03 14:58:05 -04:00
Jeff Kaufman 17e4162334 remote-config: renaming paths to be more informative (#1312) 2016-11-03 07:03:31 -04:00
Jeff Kaufman d70dcbc4d0 remote-config: use one port for testing, against a new python server (#1293)
* remote-config: use one port for testing, against a new python-based server

* properly reference remote configu urls
2016-11-01 12:29:25 -05:00
Sen Jiang 62c66e2c9c Fix non-zero exit code even if the script succeed (#1302)
The script succeeded but the exit code is 1 because it's not a dryrun so the last command failed.
2016-10-25 09:35:01 -05:00
Jeff Kaufman 09478cac70 installer: reference the --no-deps-check option properly (#1305) 2016-10-24 12:00:27 -05:00
hillsp 14b4723326 Fix sparsehash path (#1300) 2016-10-20 13:55:21 -04:00
Maks Orlovich ad41e72a83 Our config tests need to be compiled with --std=c++11 now (#1295) 2016-10-13 14:50:41 -04:00
Jeff Kaufman 7a54f88ae8 config: give full path to autoconf.err if 'checking for psol' fails. (#1294) 2016-10-13 10:42:24 -04:00
Jeff Kaufman e7be591e91 testing: check_flushing needs to know the host name (#1292) 2016-10-12 18:02:56 -04:00
Jeff Kaufman 711b6a4954 install: fix quoting (#1291)
We want to parse $additional_configure_args into an array the way the
shell would, which we're using eval for.  But because we were missing
quotes whitespace was being stripped.  Basically:

    $ function lines() { for x in "$@"; do echo "$x"; done; }

    $ lines a "b   c" d
    a
    b   c
    d

    $ a='a "b   c" d'
    $ eval e=($a)
    $ eval f=("$a")

    $ lines "${e[@]}"
    a
    b c
    d

    $ lines "${f[@]}"
    a
    b   c
    d

We were doing this like e when we should have been doing it like f.
2016-10-12 12:22:37 -04:00
hillsp 916ff52307 Fix travis.yaml for new DEPS file 2016-10-07 21:44:32 -04:00
Jeff Kaufman cd004c6d0c tests: check flushing changed its arguments (#1288) 2016-10-07 15:51:24 -04:00
Jeff Kaufman 0fd456fa57 build_ngx_pagespeed: handle quoted arguments (#1286)
* build_ngx_pagespeed: handle quoted arguments

If you enter --with-cc-opt='-arg1 -arg2' when the script asks for
additional arguments we want that to remain as one chunk all the way
through to being a single argument to ./configure
2016-10-05 08:26:04 -04:00
Jeff Kaufman 3b226aab7e install: default to latest-beta (#1283)
* install: default to latest-beta

* latest stable instead
2016-10-03 15:16:24 -04:00
hillsp 90627b1fbd Add controller tests for nginx (#1280) 2016-09-26 13:55:22 -04:00
Jeff Kaufman 6cb4b8dde3 We need -lstdc++ to come after psol.a (#1273) (#1274) 2016-09-24 16:04:52 -04:00
Jeff Kaufman d2af4962e6 load-from-file: config for testing load from file with a low size limit (#1268)
nginx side of the fix for https://github.com/pagespeed/mod_pagespeed/issues/1386
2016-09-23 18:20:26 -04:00
Jeff Kaufman b997d79ea7 install: add script to install nginx_pagespeed (#1263)
install: add script to install nginx_pagespeed

Automated version of the instructions on https://developers.google.com/speed/pagespeed/module/build_ngx_pagespeed_from_source

Tested on fresh vms of debian8, centos 6 and 7, rhel 6 and 7, and ubuntu lts 12, 14, and 16

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1262
2016-09-21 07:48:03 -04:00
Joshua Marantz 0baa230bd7 Add default setting for whether to test with a controller port. (#1278)
* Add default setting for whether to test with a controller port.

* Use RUN_CONTROLLER_TEST, which will actually be defaulted in
system/system_test.sh.  Comment out the controller port configuration
in the default nginx template.

* Finish up the conditionalization of the babysitter tests.

* Run the reload tests even with the controller off.

* clean up the diffs a little.
2016-09-20 15:42:47 -04:00
Joshua Marantz 1118910228 the remote config test is in a separate script now, so run it from the master test script (#1260) 2016-09-19 19:25:24 -04:00
hillsp 7584be2668 Work-around broken GCE Ubuntu repo 2016-09-15 16:23:11 -04:00
hillsp c8f8aff23f Add GLOBAL_STATISTICS_URL variable (#1270) 2016-09-12 13:52:06 -04:00
Otto van der Schaaf 76eeec5972 special-responses: fix for hanging sometimes on special responses (#1238)
After calling ngx_http_filter_finalize_request return NGX_DONE
as we are still in pre-access phase. This bug shows up when the
"special" response is generated from, for example, php as opposed
to a static file.

Second part of the fix for
https://github.com/pagespeed/ngx_pagespeed/issues/1146
2016-09-07 10:49:53 +02:00
hillsp 2d24ec68f1 Additional suppressions for new RE2 (#1266) 2016-09-06 10:07:40 -04:00
Maks Orlovich 269ed10ed5 Also look for headers in /url in mod_pagespeed tree (#1264)
This is needed because the current GURL implementation there --- and hence
google_url.h needs an extra compat header that's there.
2016-09-02 15:11:50 -04:00
Jeff Kaufman 94dde75a86 combine-ids: add configuration for system test (#1259) 2016-09-01 15:04:03 -04:00
Joshua Marantz 9b47332d9c allow sloppy exit (#1258)
* set up a test subdir with cc:public

* allow 'adding function to sequence' warnings on shutdown, without breaking the nginx debug tests
2016-08-29 17:06:26 -04:00
Egor Suvorov 4b7a7cc15e Make NgxMessageHandler::FileMessage() add data into internal buffer as well (#1255) 2016-08-25 15:10:46 -04:00
Jeff Kaufman f8f32efb97 Test shm checkpointing. Relies on shm checkpointing implementation in mod_pagespeed. (#930) 2016-08-23 07:46:20 -04:00
Otto van der Schaaf 3015cf0372 Allow processing of script variablies in more options (#1239)
All directory- and process- scoped options are allowed with this
change, when "ProcessScriptVariables all" is specified.

Option list compiled from:
https://docs.google.com/spreadsheets/d/1qJSUZqd2Te-4SDtm1Av6u-AckNv_oHEp1qdaUjNqZoM/edit#gid=0
2016-08-10 21:04:47 +02:00
Jeffrey Crowell 8644e5d83d Update .travis.yml 2016-08-09 17:45:19 -04:00
Jeff Kaufman 7fd0f3ee2f rewrite-options: don't turn on CoreFilters just because of query params (#1228)
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1190
2016-08-04 10:44:46 -07:00
Jeffrey Crowell a919a926f4 nginx side of https://github.com/pagespeed/mod_pagespeed/issues/1371 (#1235)
nginx side of the change
https://github.com/pagespeed/mod_pagespeed/issues/1371
2016-08-03 13:09:22 -05:00
Jeff Kaufman ed5a43ef72 rewrite-domains: add test configuration for rewriting static assets (#1223)
Needed for fixing https://github.com/pagespeed/mod_pagespeed/issues/1350
2016-08-02 11:46:20 -07:00
Jeff Kaufman ee27b5bd7a json: add content-type and cache-control for example json file (#1224) 2016-07-18 11:15:31 -04:00
Otto van der Schaaf 572f59299e Check options->IsAllowed() before rewriting html. (#1225)
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1226
2016-07-15 20:41:19 +02:00
Otto van der Schaaf ebe7c61f4f Make ngx_pagespeed behave like mod_pagespeed with regard to Flushing (#1217)
This change makes ngx_pagespeed listen to the FollowFlushes option.
When set to on (=default), ngx_pagespeed will forward incoming flushes
to ProxyFetch. When writing output, we'll now also set the flush flag on
the buffers we are about to send downstream.

Companion to mps commit: https://github.com/pagespeed/mod_pagespeed/commit/02de03e825bbd1f8d4ad4e1a1bef5263a16f3857
2016-07-12 12:26:38 -04:00
Otto van der Schaaf e542347a20 Fix for when there is only server-level configuration (#1218)
When there is no top-level configuration but only server configuration,
we don't have main options to set and consider. This prevents
a NULL dereference in that case. (Later on we'll writes out a message
about why we cannot startup with this configuration).
2016-07-06 16:13:05 +02:00
Otto van der Schaaf b1d9fbf544 Fix segfault when there's no http{} block in nginx.conf (#1221)
Should fix https://github.com/pagespeed/ngx_pagespeed/issues/1220
2016-07-06 16:12:04 +02:00
Jeff Kaufman 44626a4121 url-valued-attributes: tests for mod_pagespeed/f2f0075 2016-06-24 16:54:23 -04:00
Joshua Marantz 271b0c1f15 set up a test subdir with cc:public (#1215) 2016-06-16 09:54:06 -04:00
hillsp 1bb10ec599 Suppress controller warnings in test, fix up kill signals (#1210)
* Suppress controller warnings in test, fix up kill signals

* Switch valgrind shutdown to QUIT
2016-06-10 14:54:49 -04:00
Jeffrey Crowell c4fc99c5ae README.md: fix link in travis badge 2016-06-08 13:06:25 -04:00
Jeffrey Crowell 4c09bac0c4 svn of depot_tools is going away, migrate to git. (#1211)
for some reason we were still using the svn for travis here, but git for everything else...
2016-06-08 13:05:22 -04:00
Maks Orlovich 03d69e53b1 Update for API change: kProcessScope is about to become kLegacyProcessScope (#1205)
The renaming is to make it clear that kProcessScopeStrict (aka what
ngx_pagespeed does for everything already) is what new code should be
using, rather than current kProcessScope/upcoming kLegacyProcessScope
which does weird backwards compatible things in mod_pagespeed.
2016-05-30 12:52:41 -04:00
Maks Orlovich 15c6f7c345 Make sure RewriteDriverFactory::default_options gets the top-level proces-scope options. (#1203)
Needed for ImageMaxRewritesAtOnce to work with latest revisions.
2016-05-20 10:07:24 -04:00
Joshua Marantz d7f48d88c6 Pass the install-path into Makefile (#1200)
* Pass the install-path into Makefile, rather than having the Makefile
depend on PWD.

* Move the double-quotes be before the value, to be consistent with other
Makefiles.
2016-05-16 13:32:28 -04:00
Steve Hill fd26b873e9 Remove stray -q on pgrep. 2016-05-13 17:47:09 -04:00
hillsp d6c395151f Fix nginx_system_test so that it doesn't wait for verify_nginx_release.sh (#1199)
or wait indefinitely if it can't kill nginx.
2016-05-13 16:06:38 -04:00
Joshua Marantz dab6b8ac04 During system-tests, don't write into the source-controlled htdocs area. (#1197)
Instead, use a new (not-yet-committed) target in Makefile.tests to build
a mirror htdocs in test/tmp/root that sym-links the large readonly
section and deep copies the test areas for purge and flush tests.
2016-05-13 08:44:14 -04:00
hillsp 77cd95b552 Fix IPRO and missing Content-Length headers in 32-bit builds. (#1196) 2016-05-11 13:34:00 -04:00
Joshua Marantz be7837507f respect purge requests when serving ipro requests from ngx_pagespeed (#1193)
* respect purge requests when serving ipro requests from ngx_pagespeed

* Add TODO to share common base with ApacheFetch.
2016-05-11 11:08:04 -04:00
Jeffrey Crowell 7094df4c11 add build status indicator for trunk-tracking (#1195) 2016-05-11 07:56:34 -07:00
Nikolay Kolev 76bc257af6 Removed the redundant bracket. (#1189) 2016-05-05 14:44:59 -04:00
Jeffrey Crowell 3208d56aa4 add travis to trunk-tracking branch (#1186)
* add travis to trunk-tracking branch
2016-05-02 16:14:16 -04:00
hillsp 090ec03a68 System test updates for CentralControllerPort. (#1182) 2016-04-28 15:45:29 -04:00
Maks Orlovich e885e02a3c Fix build with recent nginx which lacks NGX_CONF_MULTI (#1185) 2016-04-26 15:37:26 -04:00
Jeffrey Crowell 6f5042020b fix up the description in the run_tests.sh (#1176)
run_tests had the wrong invocation of the script in the comments. fix
that.
2016-04-11 16:52:02 -04:00
Jeff Kaufman f3063e2daa Companion to mps change to set s-maxage on unoptimized ipro resources (#1171) 2016-04-07 16:02:02 -04:00
Otto van der Schaaf 56ee9ff24e Fix for async waits vs client aborts and HTTP/2 RST_FRAMES
This change makes nginx close the request when we receive a close

event or RST_STREAM while waiting for an async PSOL op to complete

by setting a read event handler, as inspired by the limit request

module from nginx.



Should fix https://github.com/pagespeed/ngx_pagespeed/issues/1146
2016-04-07 10:35:19 -04:00
hillsp b290a4c8a3 Merge pull request #1170 from pagespeed/cheesy_115698600
Add grpc headers to search path.
2016-04-04 17:54:12 -04:00
Jeff Kaufman 297b4ab34b handle additional warnings 2016-03-29 10:07:09 -04:00
Joshua Marantz b975ae59df Merge pull request #1164 from pagespeed/jmarantz-remove-cache-html
remove a no-longer-needed arg to ProxyFetchFactory::InitiatePropertyC…
2016-03-28 13:51:33 -04:00
Joshua Marantz c0e917801d remove a no-longer-needed arg to ProxyFetchFactory::InitiatePropertyCacheLookup 2016-03-28 13:42:28 -04:00
Maks Orlovich a3bc2cae03 Merge pull request #1157 from pagespeed/morlovich-cpp11-on
Turn on C++11 for all compilers, not just clang.
2016-03-17 10:02:40 -04:00
Maks Orlovich 7fe4e09076 Turn on C++11 for all compilers, not just clang.
Explain why we do it via config.make better.
Remove partial workaround for config.make not invoked for dynamic modules,
nginx dev fixes the root issue, and the workaround is insufficient anyway.
2016-03-16 15:42:42 -04:00
Jeff Kaufman ee20289863 Merge pull request #1156 from pagespeed/jefftk-psauxww
controller: don't fail tests when running in emacs
2016-03-15 17:05:10 -04:00
Jeff Kaufman c3f2858e31 controller: don't fail tests when running in emacs
Apparently, when running in emacs and piped into another command, ps limits
it's output to COLUMNS making check_process_names fail.  Telling ps to use
wide, wide output with 'ww' fixes this.

Additionally, use check_from so that if this test does fail we can debug
it better, seeing what grep was looking at.
2016-03-15 16:36:52 -04:00
Otto van der Schaaf 59005bec88 Merge pull request #1150 from pagespeed/oschaaf-trunk-tracking-issue-1148
NgxFetch: Log url and error when url parsing fails.
2016-03-11 14:53:00 +01:00
Otto van der Schaaf 6634754dba NgxFetch: Log url and error when url parsing fails.
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1148
2016-03-11 14:34:24 +01:00
Jeff Kaufman a9142f0003 Merge pull request #1105 from pagespeed/oschaaf-trunk-tracking-issue-1064
vary-header: Emit a single vary header in the IPRO flow
2016-03-08 06:21:46 -08:00
Jeff Kaufman 8efb831ba4 Support centralized process changes in github.com/pagespeed/mod_pagespeed/commit/9bf7523 2016-03-07 16:14:43 -05:00
huibaolin fcbe51efaf Merge pull request #1145 from pagespeed/huibao-webp
Add system tests for image format, quality, and response in IPRO
2016-03-07 11:41:53 -05:00
Kees Spoelstra 08e284f9cb Strip subresource hints pagespeed automatic system test configuration
Corresponding changes for:
- pull https://github.com/pagespeed/mod_pagespeed/pull/1204
- issue Strip subresource hints #973 https://github.com/pagespeed/mod_pagespeed/issues/973
2016-03-07 10:50:59 -05:00
Huibao Lin 8582bab69c Add system tests for image format, quality, and response in IPRO 2016-03-07 09:58:44 -05:00
Jeff Kaufman 5264647a65 Merge pull request #1139 from pagespeed/oschaaf-trunk-tracking-issue-1138
IPRO: Copy the cache control value to ensure a correct lifetime
2016-03-03 11:15:10 -05:00
Otto van der Schaaf 85d0db2550 IPRO: Copy the cache control value to ensure a correct lifetime
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1138
2016-03-02 23:42:36 +01:00
hillsp 8e25b58597 Merge pull request #1130 from pagespeed/cheesy_115114559
Update protobuf path for non chromium version
2016-02-23 15:07:37 -05:00
Steve Hill 6eee387802 Update protobuf path for non chromium version 2016-02-22 17:52:55 -05:00
huibaolin 2315173946 Merge pull request #1125 from pagespeed/huibao-webp
Allow varying on Accept header for ipro-for-browser.example.com
2016-02-19 15:54:52 -05:00
Huibao Lin 54bd8bf4f8 For backward compatibility, only allow varying on Accept header for ipro-for-browser.example.com 2016-02-18 11:29:27 -05:00
Jeffrey Crowell 60f91becb7 Merge pull request #1122 from pagespeed/oschaaf-trunk-tracking-issue-1120
Fix shutdown when ngx_pagespeed is completely disabled.
2016-02-17 10:29:39 -05:00
Jeffrey Crowell d959f01848 Merge pull request #1115 from pagespeed/oschaaf-trunk-tracking-dynamic-modules
Support building ngx_pagespeed as a dynamic module
2016-02-16 11:00:53 -05:00
Otto van der Schaaf f60c754d82 Fix shutdown when ngx_pagespeed is completely disabled.
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1120
2016-02-15 10:54:53 +01:00
Otto van der Schaaf 09f53881de Support building ngx_pagespeed as a dynamic module.
As of 1.9.11, nginx supports loading dynamic modules
This change makes us support building ngx_pagespeed.so

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1116
2016-02-13 00:10:39 +01:00
Prayag Verma 929c5c5908 Fix a typo
`neet` → `need`
2016-02-11 13:18:13 -05:00
Piotr Sikora 064ced104d Fix build with nginx-1.9.11+.
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2016-02-10 15:03:45 -05:00
Maks Orlovich a73dc7ba74 Merge pull request #1103 from pagespeed/morlovich-ua-tweak-for-fontservice
Adjust our UA string to fix to make it compatible with fonts.g.c parsing on IE11.
2016-02-08 16:18:21 -05:00
Otto van der Schaaf b081bb7aec vary-header: Emit a single vary header in the IPRO flow
The report from some time ago mentioned three Vary: headers,
but I can now only reproduce two using trunk-tracking plus the
original repro-configuration.

This fix unflags r->gzip_vary as set by the gzip module when PSOL
hands us Vary: Accept-Encoding, to make sure that nginx's core
header filter doesn't append another one.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1064
2016-01-28 03:37:01 +01:00
Maks Orlovich 0a60e0ef8b Adjust our UA string to fix to make it compatible with fonts.google.com parsing on IE11.
Counterpart of:
https://github.com/pagespeed/mod_pagespeed/commit/f3639e84c0196a5f5151ff5e54ad57285db09b37
2016-01-27 09:16:49 -05:00
Maks Orlovich 1926c78ca2 Merge pull request #1102 from pagespeed/morlovich-no-more-spdy-specific-config
Adjust to library API change: no more spdy-specific config.
2016-01-25 15:33:35 -05:00
Maks Orlovich c3598134ee Adjust to library API change: no more spdy-specific config. 2016-01-25 12:33:29 -05:00
Jeff Kaufman 43f09a877b Merge pull request #1101 from pagespeed/oschaaf-trunk-tracking-basefetch-valgrind
Fix valgrind complaint caused by NgxBaseFetch
2016-01-25 11:05:37 -05:00
Jeff Kaufman d023bb35f6 Merge pull request #1098 from pagespeed/oschaaf-trunk-tracking-rzero-crash
Eliminate CHECK that fails (rarely) during the IPRO lookup.
2016-01-22 10:12:17 -05:00
Otto van der Schaaf 60c1f4cc4e Fix valgrind complaint caused by NgxBaseFetch
We should not use r->connection after we finalize the request.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1100
2016-01-22 16:06:42 +01:00
Otto van der Schaaf b88e067c6d Eliminate CHECK that fails (rarely) during the IPRO lookup.
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1096
2016-01-21 22:08:43 +01:00
Jeff Kaufman b214fb43e3 Merge pull request #1061 from pagespeed/oschaaf-trunk-tracking-add-resource-header
AddResourceHeader: Add test configuration
2016-01-19 13:26:01 -05:00
Joshua Marantz 9e6048f771 Merge pull request #1092 from pagespeed/jmarantz-ipro-flow-cache-not-flaky
remove 'IPRO flow uses cache as expected' from flaky-list, ...
2016-01-05 15:11:46 -05:00
Maks Orlovich 653875cb68 Merge pull request #1076 from pagespeed/morlovich-h2-bit
Store whether h2 is in use in RequestContext.
2016-01-05 12:35:51 -05:00
Joshua Marantz a512d95258 remove 'IPRO flow uses cache as expected' from flaky-list, but strip out 'Fetch timed out' from log-warning check 2016-01-05 11:46:35 -05:00
Otto van der Schaaf a4441220b1 Merge pull request #1085 from pagespeed/oschaaf-trunk-tracking-internal-redirect-crasher
Fix crasher on 404 .pagespeed. resources w/a custom location
2016-01-04 22:03:05 +01:00
Jeffrey Crowell 374ee1c750 Merge pull request #1089 from pagespeed/crowell-reapply-744
reapply:  location-header: tweak location header handling
2015-12-31 10:54:29 -05:00
Jeffrey Crowell 059dd20b10 reapply: location-header: tweak location header handling
- Fix potentially sending the location header into PSOL twice.
- Be more thorough when unsetting the location header

Attempts to fix #725

from oschaaf
2015-12-31 10:46:39 -05:00
Otto van der Schaaf 1964ef5219 Fix crasher on 404 .pagespeed. resources w/a custom location
- Fix nginx-side flow so we handle .pagespeed. resources ok
  when they will land on a customized 404 internal location.
- Additionally, check for a wiped request context and make sure
  we do not dereference a null pointer, which is what hurt in
  the flow we entered above as the IPRO lookup still was
  generating events while the nginx side request context was
  gone.
- Also, as a preliminary measure, do not check fail when we
  receive a stale event originating from a NgxBaseFetch that
  is no longer associated with our request context.
  Do log a warning so we'll hear about this happening either
  through system test failures or a bug report.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1081
2015-12-28 15:59:13 +01:00
Jeff Kaufman 56a5d41ec3 Restore dropped fix for #957
@rfnx fixed #957 in acb89a, but this was accidentally merged to master
instead of trunk-tracking.  I checked for this sort of problem as part
of the 1.10 release, but missed this commit.  Restored.

Fixes #1054
2015-12-18 15:01:15 -05:00
Jeff Kaufman 7ee1efe0dd Merge pull request #1071 from pagespeed/oschaaf-trunk-tracking-log-debug-noise
log: initialize logging earlier
2015-12-17 11:36:34 -05:00
Maks Orlovich eb2a81ee79 Store whether h2 is in use in RequestContext. 2015-12-15 09:29:02 -05:00
Otto van der Schaaf 37e1c3618a log: initialize logging earlier
It turns out to be possible to initialize logging earlier by
grabbing the log from a global ngx_cycle structure.

This makes us start logging earlier, yet loses the
"No threading detected ..." messages both from stderr and
in error.log when nginx initially starts.

With this change, these messages will now be logged as we start
logging earlier:

"
flush
.
"

These originate from SystemCachePath::CacheKey which appends
newlines to the key, and the resulting cache key ends up being
logged. We might want to change that, because the resulting
lines in error.log look weird and might raise questions.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/895
2015-12-11 12:02:21 +01:00
Jeffrey Crowell df498ea788 Merge pull request #1067 from pagespeed/crowell-fix-gcc5
add flags for new GCC on config tests
2015-12-10 15:45:47 -05:00
Jeffrey Crowell 4b4d353156 add flags for new GCC on config tests
closes #1066
2015-12-10 15:41:44 -05:00
Maks Orlovich c9d4912746 Merge pull request #1050 from pagespeed/morlovich-compiler-req
Add compiler version checks for what we want to support going forward.

Also make us actually build with clang (the log_message_handler.cc change
and config.make change)
2015-12-09 14:50:11 -05:00
Otto van der Schaaf 2b74f6bed3 AddResourceHeader: Add test configuration
nps side of https://github.com/pagespeed/mod_pagespeed/pull/1200
2015-12-09 04:35:24 +01:00
Maks Orlovich f1a6cd0ade Whitespace tweak 2015-12-07 10:01:23 -05:00
Joshua Marantz 0c01c0644e Merge pull request #1057 from pagespeed/jmarantz-2-pass-ipro
suppress errors on new 2-pass and 3-pass ipro tests
2015-12-02 16:45:48 -05:00
Joshua Marantz 14aa4fd962 suppress errors on new 2-pass and 3-pass ipro tests 2015-12-02 15:01:37 -05:00
Joshua Marantz 36a7ff9543 Merge pull request #1056 from pagespeed/jmarantz-no-error-on-slow-ReadFile
do not consider it a test failure to get a slow ReadFile operation.
2015-12-02 08:31:34 -05:00
Joshua Marantz 706577a34b do not consider it a test failure to get a slow ReadFile operation. 2015-12-02 08:27:47 -05:00
Otto van der Schaaf 6703b2d76e Merge pull request #1055 from pagespeed/oschaaf-trunk-tracking-location-header-handling
location-header: Be careful with headers_out->location
2015-12-01 18:56:53 +01:00
Otto van der Schaaf 40c05b4a4f location-header: Be careful with headers_out->location
Only set headers_out->location when the upstream originally did
as well. If the Location: header value involved starts with "/"
nginx will absolutify it, ignoring any X-Forwarded-Proto header
in the process.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/819
(Confirmed: https://github.com/pagespeed/ngx_pagespeed/issues/1029)
Hopefully fixes https://github.com/pagespeed/ngx_pagespeed/issues/711
2015-12-01 18:55:02 +01:00
Maks Orlovich bc875647f1 Add compiler version checks for what we want to support going forward,
and make us actually build with clang (the log_message_handler.cc change
and config.make change)
2015-11-25 13:44:13 -05:00
Maks Orlovich f88a0763fd Merge pull request #1048 from pagespeed/morlovich-buildflag
Pass in -D_GLIBCXX_USE_CXX11_ABI=0, so people using gcc-5.x can use our psol.a
2015-11-25 08:56:16 -05:00
Maks Orlovich 239ca9aa80 Pass in -D_GLIBCXX_USE_CXX11_ABI=0, so people using gcc-5.x can use psol.a
we built with 4.8

See issue 942
2015-11-24 15:16:06 -05:00
Jeff Kaufman 37c51d3b9e Merge pull request #1042 from pagespeed/jefftk-content-experiment
Add ContentExperiment support
2015-11-24 11:46:04 -05:00
Jeff Kaufman 2468257e2d Add ContentExperiment support 2015-11-20 16:39:02 -05:00
Jeff Kaufman 4628e1c0ea Merge pull request #1035 from pagespeed/jefftk-script-var-testing
Support script variables in ShardDomain
2015-11-19 11:01:41 -08:00
Jeff Kaufman 7f98ab448b Merge pull request #1047 from pagespeed/jefftk-ngx-brotli
Fix interaction with ngx_brotli module.
2015-11-18 11:20:17 -08:00
Piotr Sikora 103c479fbb Fix interaction with ngx_brotli module.
Reported by George Liu (eva2000) on GitHub (issue #1021).

Signed-off-by: Piotr Sikora <piotrsikora@google.com>

Conflicts:
	config
2015-11-16 18:26:30 -05:00
Jeffrey Crowell 887bd8fa98 Merge pull request #1046 from pagespeed/crowell_content_encoding
add content_encoding to headers_out
2015-11-16 11:09:04 -05:00
Jeffrey Crowell 804f234268 add remaining shortcuts to headers_out_t
this change is required for gzip cache change going into mod_pagespeed.
2015-11-16 10:56:23 -05:00
Jeff Kaufman ea82f0de19 Support script variables in ShardDomain 2015-11-02 10:08:00 -05:00
Jeff Kaufman 5f312820e5 Merge pull request #974 from pagespeed/jefftk-handler-restrictions
Add support for blocking access to our handlers.
2015-11-02 08:18:10 -05:00
Jeff Kaufman 7efac4ac4e Merge pull request #1028 from pagespeed/oschaaf-trunk-tracking-issue-1015
IPRO+MPD: Make In-Place-Resource-Optimization with MapProxyDomain work
2015-10-28 13:30:04 -04:00
Otto van der Schaaf 634b813071 IPRO+MPD: Make In-Place-Resource-Optimization with MapProxyDomain work
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/1015

Pull with MPS Side for this change:
https://github.com/pagespeed/mod_pagespeed/pull/1161
2015-10-27 18:11:35 +01:00
Joshua Marantz d30972985b Merge pull request #1026 from pagespeed/jmarantz-remove-set-ua
Don't call RewriteDriver::SetUserAgent on the UA in the request-headers.
2015-10-22 15:17:15 -04:00
Joshua Marantz 3a6e833eae Don't call RewriteDriver::SetUserAgent on the UA in the request-headers.
RewriteDriver::SetRequestHeaders already pulls the UA from the request-headers.
2015-10-22 14:19:00 -04:00
Joshua Marantz 90c8ac8a12 Revert "Don't call RewriteDriver::SetUserAgent as the user-agent is already in the request-headers"
This reverts commit 6ccc1c513b.
2015-10-22 14:13:01 -04:00
Joshua Marantz 6ccc1c513b Don't call RewriteDriver::SetUserAgent as the user-agent is already in the request-headers 2015-10-22 13:20:00 -04:00
Jeff Kaufman fe47eeb4f3 Add support for blocking access to our handlers.
Nginx side of the fix for https://github.com/pagespeed/mod_pagespeed/issues/1088
2015-09-18 09:03:01 -04:00
Joshua Marantz e42f61e263 Merge pull request #1002 from pagespeed/jmarantz-log-slow-file-ops
ignore errors about slow file operations
2015-07-31 17:01:39 -04:00
Joshua Marantz 8bac32c669 ignore errors about slow file operations, which can occur when running valgrind tests 2015-07-31 16:57:20 -04:00
Jeffrey Crowell 4bef2af22c Merge pull request #995 from pagespeed/crowell-disable-sendfile
add test servers for sending x-sendfile and x-accel-redirect
2015-07-23 17:34:58 -04:00
Jeffrey Crowell 52bd966edd add test servers for sending x-sendfile and x-accel-redirect 2015-07-23 13:34:25 -04:00
Jeff Kaufman 0f7a1f4503 Merge pull request #994 from pagespeed/jefftk-allow-script-variables
config: whitelist a few more directives for script variables
2015-07-23 10:36:57 -04:00
Jeff Kaufman 7f477d6575 config: whitelist a few more directives for script variables
When configuring downstream caching if you have an origin with multiple caches in front of it you might want to choose how you handle requests in response to which cache you're getting them from.  Whitelist DownstreamCachePurgeLocationPrefix, DownstreamCachePurgeMethod, and DownstreamCacheRewrittenPercentageThreshold for scripting so this is possible.
2015-07-22 10:32:41 -04:00
Jan-Willem Maessen cc10f15f53 Fix pagespeed_libraries_generator.sh to fetch pagespeed_libraries.conf from github rather than svn. 2015-07-09 10:18:51 -04:00
Jeffrey Crowell 9ee745c2ef Revert "temporarily comment tests using modpagespeed.com"
This reverts commit 5337e4b558.

closes #984
2015-07-07 13:15:33 -04:00
Jeffrey Crowell 5337e4b558 temporarily comment tests using modpagespeed.com
revert this commit when modpagespeed.com is back up
2015-07-06 12:36:44 -04:00
jmarantz b31bf7b090 Merge pull request #967 from pagespeed/jmarantz-psoff-dir-on
nginx system test changes to repro issue https://github.com/pagespeed…
2015-05-19 11:12:14 -04:00
Joshua Marantz 8464a00a77 nginx system test changes to repro issue https://github.com/pagespeed/mod_pagespeed/issues/1077 2015-05-18 09:46:12 -04:00
Jeff Kaufman b048ceb858 Merge pull request #966 from pagespeed/jefftk-doneandsetheaders
Handle DoneAndSetHeaders() new second argument that wants to know whe…
2015-05-15 10:33:32 -04:00
Jeff Kaufman 0fbdf3ee97 Handle DoneAndSetHeaders() new second argument that wants to know whether the response is complete. 2015-05-14 15:26:10 -04:00
Jeffrey Crowell a9d85960b5 add psol tar.gz to gitignore 2015-05-13 11:57:32 -04:00
Jeffrey Crowell cd19284062 initialize uninitialized variables. 2015-04-01 15:45:22 -04:00
Jeffrey Crowell c2a756049e add support for nginx 1.7.11 --with-threads 2015-04-01 15:10:26 -04:00
Maks Orlovich 6b2999dfd4 Merge pull request #944 from pagespeed/morlovich-api-adjust-InitiatePropertyCacheLookup
Adjust to API change to InitiatePropertyCacheLookup
2015-04-01 14:08:33 -04:00
Maks Orlovich 5658c20327 Adjust to API change to InitiatePropertyCacheLookup
The last argument was not actually used, and hence was removed.
2015-03-30 17:02:58 -04:00
Jeffrey Crowell ec2dea84fe Merge pull request #943 from pagespeed/crowell-rm_unused_variable
move 'type' variable to inside an #if statement
2015-03-30 14:34:48 -04:00
Jeffrey Crowell e206e871aa move 'type' variable to inside an #if statement
removes an unused variable when compile without NGX_DEBUG, allows for
building with -Werror.
2015-03-30 14:33:33 -04:00
Jeff Kaufman f4fd9a3f7c Merge pull request #935 from pagespeed/jefftk-system-public
system/public/ was moved to system/, update our references.
2015-03-18 17:04:21 -07:00
Jeff Kaufman cf88925f1e system/public/ was moved to system/, update our references. 2015-03-13 14:38:16 -04:00
Jeff Kaufman 5ea8fb9f3e Merge pull request #934 from pagespeed/jefftk-automatic-moved
Moved `automatic/` into `pagespeed/` and got rid of the `public/` hierarchy.
2015-03-13 10:44:08 -04:00
Jeff Kaufman cd31a6b129 Move automatic/public to automatic/. 2015-03-13 09:59:52 -04:00
Jeff Kaufman 137792e88f Change references from net/instaweb/automatic to pagespeed/automatic. 2015-03-13 09:30:14 -04:00
Jeffrey Crowell 91cd587e68 Merge pull request #932 from pagespeed/crowell_rm-test-grep
rm "unexpected response" grep from system test
2015-03-05 14:42:05 -05:00
Otto van der Schaaf e9608b03b7 Merge pull request #931 from pagespeed/oschaaf-trunk-tracking-native-fetcher-more-fixes
native-fetcher: fixes
2015-03-05 20:35:21 +01:00
Jeffrey Crowell 6e1a9a73a5 rm "unexpected response" grep from system test 2015-03-05 14:02:55 -05:00
Otto van der Schaaf 3875acf392 native-fetcher: fixes
- Native fetching broke in https://github.com/pagespeed/ngx_pagespeed/pull/925
  Make changes so we can do early-stage fetches in the startup process
  to fix that.
- Properly cancel out any pending fetches upon ShutDown()
- Decline fetching after ShutDown(), decline fetching when Init()
  failed.
2015-03-05 14:43:29 +01:00
Jeffrey Crowell 4dd70b40ef Merge pull request #925 from pagespeed/crowell_rconfig
Port remote configuration option to nginx.
2015-03-04 13:26:04 -05:00
Jeffrey Crowell 88d9b5241d Merge remote-tracking branch 'origin/trunk-tracking' into crowell_rconfig 2015-02-25 16:47:48 -05:00
Otto van der Schaaf 23905f8ce9 Merge pull request #922 from pagespeed/oschaaf-trunk-tracking-native-fetcher-fixes
native-fetcher: fix a few bugs
2015-02-25 21:13:02 +01:00
Otto van der Schaaf effe857083 native-fetcher: Fix a few bugs
- Add handling for header only responses
- Fixup nginx i/o handling
- Fix issues in parser state
- Revert timeout for native fetcher dns resolve to 10 seconds
- Ignore warning that gets logged with this change in tests during
  fetching from a host that refuses connections.

Should help stabilizing (valgrind) test runs some more.
2015-02-25 21:03:01 +01:00
Jeffrey Crowell 599a3bca5c update to match apache for hostnames 2015-02-24 17:36:08 -05:00
Jeffrey Crowell c26313e7ab Port remote configuration option to nginx. 2015-02-23 11:25:17 -05:00
Otto van der Schaaf bcba22dd95 Merge pull request #919 from pagespeed/oschaaf-trunk-tracking-native-fetcher-pull-755
Call async_fetch_->Done after all usages.
2015-02-18 13:38:17 +01:00
Otto van der Schaaf 1ea7e3e568 Merge pull request #917 from pagespeed/oschaaf-trunk-tracking-native-fetcher-deflake
native-fetcher: bump dns timeout to deflake running the tests
2015-02-17 21:27:32 +01:00
Jeff Kaufman 34341251f6 Merge pull request #908 from pagespeed/oschaaf-trunk-tracking-shutdown-system-test-failure
shutdown: fix system test failure in error.log sanity check
2015-02-17 13:28:56 -05:00
Vasily Chekalkin d1f2a43a71 Call async_fetch_->Done after all usages.
AsyncFetch::Done will delete itself. Accessing
async_fetch_->extra_respond_headers() will crash nginx.
2015-02-17 12:18:30 +01:00
Otto van der Schaaf 58b1264745 native-fetcher: bump dns timeout to deflake running the tests
Nginx sometimes receives an expected response from 8.8.8.8 when
resolving host names, and the subsequent retry doesn't finish up
in 10 seconds. Bumping the timeout helps, but does not fully
explain why nginx is sometimes receiving an unexpected response.
I'll create a separate issue for investigating that.
2015-02-17 11:05:34 +01:00
Otto van der Schaaf 8b6fdf56ef shutdown: fix system test failure in error.log sanity check
- Should shut down with a clean valgrind and sane logging for the
  current test workload.
- Minor cleanup
2015-02-13 21:00:43 +01:00
Otto van der Schaaf 93d70feb3b Merge pull request #907 from pagespeed/oschaaf-trunk-tracking-test-reload
configuration-reload-test: wait for the new worker to get ready
2015-02-12 20:05:27 +01:00
Otto van der Schaaf 62c8947b2d configuration-reload-test: wait for the new worker to get ready
After sending a SIGHUP, wait for the new worker process with the
new configuration to handle further requests, or else the tests
running after that might get confused when the new worker becomes
active with fresh shared mem statistics and shared mem cache.
2015-02-12 18:08:18 +01:00
Otto van der Schaaf 22749d7222 Merge pull request #906 from pagespeed/oschaaf-trunk-tracking-module-position
module-position: optional switch to install at HTTP_AUX_FILTER_MODULES
2015-02-12 17:09:23 +01:00
Otto van der Schaaf a8141eadd3 module-position: optional switch to install at HTTP_AUX_FILTER_MODULES
This change adds a flag to optionally position the module at HTTP_AUX_FILTER_MODULES
instead of just in front of the gzip module. Doing so allows header module(s) to
fully manipulate any response headers before they are send to the user-agent.
With https://github.com/pagespeed/ngx_pagespeed/pull/880, SSI no longer hangs,
and other modules using subrequests should not do so either. SSI subrequests are
not optimized when ngx_pagespeed runs at HTTP_AUX_FILTER_MODULES, so the test for
it is added to the expected failures when the tests are run for this module position.

To build with the module respositioned:
  POSITION_AUX=true ./configure ......
The same variable can be set before running the system tests, in which case it will
perform additional header tests and add the SSI test to the expected failures.
2015-02-12 16:23:11 +01:00
Otto van der Schaaf 2d28ff38e8 Merge pull request #899 from pagespeed/oschaaf-trunk-tracking-shutdown
trunk-tracking-shutdown: improve shutdown code
2015-02-10 23:52:33 +01:00
Otto van der Schaaf d7f1c0dc48 Shutdown: improve shutdown handling
- Fix valgrind errors
- Add a test to make sure all logged output looks sane by whitelisting
  current errors/warnings.
- Stop our nginx test instances after we are done testing.
- Add tests for shutting down and reloading configuration under high
  load (depends on ab).
- Reduce the number of keepalive requests in the keepalive tests to speed
  up test runs.
- Fix exiting with open file descriptors, fix cleanup in nginx's cache
  manager/loader processes
- Attempt to finish up queued up NgxBaseFetches/requests on shutdown/reload
- Under valgrind the blocking rewrite started failing after adding a test
  for reloading configuration under high load.
  I've added it to the expected failures for valgrind, looking into this
  is up next.
- Decline in ps_resource_handler when nginx is quitting. This makes us
  more reliable on continued stress during shutdown/reload.
2015-02-10 23:13:44 +01:00
Jeffrey Crowell 737e9396f5 Merge pull request #892 from pagespeed/crowell-fix-888
Replace CHECK with return failure and log.
2015-01-30 10:28:04 -05:00
Jeffrey Crowell 81029dafa6 Replace CHECK with return failure and log.
Fixes #888 along with
https://code.google.com/p/modpagespeed/source/detail?r=4533
2015-01-30 10:23:00 -05:00
Otto van der Schaaf 001cd2dc4c Merge pull request #889 from pagespeed/oschaaf-trunk-tracking-content-handler-error-responses
content-handling-errors: fall back to nginx's default handling
2015-01-27 16:50:04 +01:00
Otto van der Schaaf 3efebb7948 content-handling-errors: fall back to nginx's default handling
This change passes on non succesful status codes for pagespeed
resources and other places where we act as a content handler to
nginx. This has two benefits:
- Instead of a blank page, the user agent receives a formatted
  and (hopefully customized and informative) response.
- Header modules are able to operate on that response, which was
  requested in https://github.com/pagespeed/ngx_pagespeed/issues/612#issuecomment-58855816
2015-01-26 22:13:15 +01:00
Otto van der Schaaf 02b67b79ad Merge pull request #885 from pagespeed/oschaaf-trunk-tracking-release-early
Release base fetch early, eliminate write_pending and fetch_done
2015-01-26 16:46:30 +01:00
Otto van der Schaaf d0858790e4 Merge pull request #884 from pagespeed/oschaaf-trunk-tracking-base-fetch
base-fetch: prevent unused constructions and prop. cache lookups
2015-01-23 20:09:45 +01:00
Otto van der Schaaf 4d945b1c59 Release base fetch early, eliminate write_pending and fetch_done
Get rid of write_pending & fetch_done flags on the request context.
Assume that having ctx->base_fetch set means we have outstanding
work and thus we are not done yet, for simplicity.
This also means we'll release the base fetch earlier which seems
like a good idea to me.
2015-01-23 15:07:14 +01:00
Otto van der Schaaf 7d965aced7 Merge pull request #880 from pagespeed/oschaaf-trunk-tracking-run-posted-requests
posted-requests: run posted requests when appropriate
2015-01-21 19:47:13 +01:00
Otto van der Schaaf a5411a1c7c base-fetch: prevent unused constructions and prop. cache lookups
- Don't construct `NgxBaseFetch` instances and call `Done(false)` later when it turns out it wasn't needed.
- Track the purpose of the base fetch instead of just wether it is an IPRO lookup or not for more informational tracing
  as well as avoiding constructing base fetches when their purpose isn't know yet.
- Don't initiate a property cache lookup when we won't need it (`ProxyFetchFactory::InitiatePropertyCacheLookup`)
- Improve IPRO handling of `NgxBaseFetch` and make it clearer. Indicate we want to supress further events when the
  base fetch was used to lookup an IPRO url, and the result was not indicative of something we can respond with to the
  browser.
- Remove unused `RequestRouting` constants
2015-01-20 02:19:47 +01:00
Otto van der Schaaf 8a1260a1d1 posted-requests: run posted requests when appropriate
Request termination code relies on posted requests being run.
One of the things this fixes is that we won't hang when configured
to run before the SSI module.

Avoids trouble when changing the module order, which helps
https://github.com/pagespeed/ngx_pagespeed/issues/612
2015-01-19 10:28:00 +01:00
Otto van der Schaaf f2e7b15d9c Merge pull request #879 from pagespeed/oschaaf-trunk-tracking-server-header
server-header: improve handling of server header
2015-01-17 20:28:34 +01:00
Otto van der Schaaf 5bc61a7092 server-header: improve handling of server header
- Fixes an issue in the html flow that would prevent overriding the
value of the 'Server' response-header.
- Add tests that ensure we emit a single and correct server header
in all flows when not overriding it.
- Add tests that ensure overriding the 'Server' response header
works. The resource and IPRO flow are added to the expected failures
as those are not working yet (and will be adressed in a follow-up).

Fixed https://github.com/pagespeed/ngx_pagespeed/issues/864 (html flow)
2015-01-17 20:27:45 +01:00
Otto van der Schaaf 03819f4e4a Merge pull request #876 from pagespeed/oschaaf-single-fd-fixed
Oschaaf single fd fixed
2015-01-16 15:53:06 +01:00
Otto van der Schaaf 7ef61d2580 base-fetch-leak: Shut down NgxEventConnection before deleting it
Shutdown will drain the pipe and process the last events which
will give nginx the opportunity to run the cleanup handlers on the
associated requests.
2015-01-10 22:45:04 +01:00
Otto van der Schaaf a73c096950 Revert "Merge pull request #872 from pagespeed/jefftk-revert-834"
This reverts commit 7bd90f7b3a, reversing
changes made to 58228564dd.
2015-01-10 22:07:21 +01:00
Jeff Kaufman 7bd90f7b3a Merge pull request #872 from pagespeed/jefftk-revert-834
Revert "NgxConnection: single event mechanism
2015-01-09 10:25:12 -05:00
Jeff Kaufman 73981ffe1a Revert "NgxConnection: single event mechanism for NgxFetch and NgxBaseFetch"
This reverts commit 5dfe42f3d3.
2015-01-08 13:02:19 -05:00
Jeff Kaufman 58228564dd Merge pull request #869 from pagespeed/jefftk-system-moved
mod_pagespeed moved the location of the system directory; update our includes
2015-01-06 09:50:11 -05:00
Jeff Kaufman 340c86a49e mod_pagespeed moved the location of the system directory; update our includes 2015-01-06 09:22:56 -05:00
Otto van der Schaaf abdafc7aa4 Merge pull request #834 from pagespeed/oschaaf-single-pipe2
NgxConnection: single event mechanism for NgxFetch and NgxBaseFetch
2014-12-30 21:52:07 +01:00
Jan-Willem Maessen 8cf10873d1 Merge pull request #863 from pagespeed/jmaessen-ngx-message-handler-fix
Make ngx_message_handler work with new message_handler api.
2014-12-19 16:13:26 -05:00
Jan-Willem Maessen 2496716e36 Make ngx_message_handler work with new message_handler api. 2014-12-19 15:11:55 -05:00
Jeff Kaufman af364344e9 Merge pull request #862 from pagespeed/jefftk-rmdir
testing: give '-p' to mkdir
2014-12-17 12:55:44 -05:00
Jeff Kaufman 9da45910c7 rm won't remove the containing directory if a file is removed out from under it, which means the directory will still be there but will be empty. This is not a problem, so pass '-p' to not fail on already existing directories. 2014-12-17 12:50:23 -05:00
Otto van der Schaaf 5dfe42f3d3 NgxConnection: single event mechanism for NgxFetch and NgxBaseFetch
Abstract the pipe communication into NgxEventConnection, for reuse
by NgxBaseFetch and NgxUrlAsyncFetcher.

Based on Chai's earlier work, but with a few fixes discovered
while working on this and SPDY module compatibility

- Uses less file descriptors, I expect this to be faster but need
  measurement is needed to back that.
- Fixed NgxUrlAsyncFetcher actually shutting down its fetchers.
- Fixes a bug where we wouldn't clean idle pooled NgxConnections.
- Fixes a bug for requests that are finalized mid-IPRO lookup.
- Makes us use ngx_handle_read_event/ngx_del_event
2014-12-14 02:29:40 +01:00
Jeff Kaufman bff15040be Merge pull request #857 from pagespeed/jefftk-upstream-check-failure-function
Upstream the change to check_failures_and_exit, moving it to mod_pagespeed
2014-12-04 15:42:31 -05:00
Jeff Kaufman 3c5c5076de Upstream the change to check_failures_and_exit, moving it to mod_pagespeed 2014-12-04 13:22:13 -05:00
Jeff Kaufman eab4f8672f Merge pull request #852 from pagespeed/jefftk-move-tests-to-system
Move duplicate tests from the nginx-specific system test to system
2014-12-02 20:12:52 -05:00
Jeff Kaufman 852e376130 Move duplicate tests from the nginx-specific system test to system/system_test
As system/system_test.sh is in the mod_pagespeed repo, this is just a bunch of
deletes.
2014-12-02 15:11:23 -05:00
Jeff Kaufman b7529a8d9a Merge pull request #855 from pagespeed/jefftk-fix-tempdir
Rework parallization separation
2014-12-02 13:34:03 -05:00
Jeff Kaufman 5dd93fffae Rework parallization separation 2014-12-01 10:49:08 -05:00
Jeff Kaufman 48d23f10ba Merge pull request #851 from pagespeed/jefftk-fix-url-purging
Fix error with url cache purging test.  Followup to #850.
2014-11-17 11:25:03 -05:00
Jeff Kaufman f924bc72d9 Fix error with url cache purging test. Followup to #850. 2014-11-17 11:19:51 -05:00
Otto van der Schaaf 1aff187d0e Merge pull request #850 from pagespeed/oschaaf-trunk-tracking-script-filters-test
script-filters: Add a test for modifying filters via script variables
2014-11-14 16:03:22 +01:00
Jeff Kaufman 3b64df255a Merge pull request #849 from pagespeed/jefftk-prioritize-critical-css-test
testing: allow the prioritize_critical_css post test to fail
2014-11-14 10:02:49 -05:00
Otto van der Schaaf 0eeeca6e47 script-filters: Add a test for modifying filters via script variables
As requested via https://github.com/pagespeed/ngx_pagespeed/pull/822
2014-11-14 15:56:13 +01:00
Jeff Kaufman 6f68ba2f68 testing: allow the prioritize_critical_css post test to fail 2014-11-14 08:56:37 -05:00
Otto van der Schaaf e6e70c32a8 Merge pull request #822 from pagespeed/oschaaf-trunk-tracking-script-filters
script-filters: Allow using script variables in Enable/DisableFilters
2014-11-06 22:35:44 +01:00
Jeffrey Crowell a3e20a05e2 Merge pull request #846 from pagespeed/oschaaf-trunk-tracking-conf-multi-typo
NGX_CONF_MULTI: Typo
2014-11-04 13:46:55 -05:00
Otto van der Schaaf e28255e2ef NGX_CONF_MULTI: Typo
Fix accidental double pipe symbol.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/843
2014-11-04 13:29:49 +01:00
Otto van der Schaaf 10ac8ae4a3 Merge pull request #798 from pagespeed/oschaaf-trunk-tracking-conf-multi
older-nginx-versions: Add NGX_CONF_MULTI to ps_command flags.
2014-10-30 15:13:27 +01:00
Jeffrey Crowell 1b3ca08e22 Merge pull request #841 from pagespeed/crowell-tengine-stable-support
Check type of resolver_ctx->addrs.
2014-10-29 14:59:51 -04:00
Jeffrey Crowell de5bc5d943 Check type of resolver_ctx->addrs.
Check the type of resolver_ctx->addrs and make sure that it is
ngx_addr_t* instead of in_addr_t*. addresses issue #839
2014-10-29 14:49:55 -04:00
Otto van der Schaaf afd0f01686 script-filters: Allow using script variables in Enable/DisableFilters
To support a non-evil way (if-in-location) of tuning SPDY specific
configuration, allow scripting of Enable/DisableFilters in nginx.conf
2014-10-10 17:33:44 +02:00
Otto van der Schaaf 0cdb81fab4 Merge pull request #795 from pagespeed/oschaaf-native-fetcher-remove-check
native-fetcher: remove a DCHECK that possibly fires on shutdown.
2014-10-06 17:04:56 +02:00
hillsp b492d3966e Merge pull request #811 from pagespeed/cheesy-device-matching
Support minor PSOL API change for matches_device_type
2014-09-22 17:38:06 -04:00
Steve Hill 232c05a81d Merge remote-tracking branch 'origin/trunk-tracking' into cheesy-device-matching 2014-09-19 18:17:20 -04:00
Steve Hill adbe2cb359 Remove unit tests; They are now in system_test.sh 2014-09-19 18:14:18 -04:00
Jeffrey Crowell 88370cf54d Merge pull request #809 from pagespeed/crowell-update-config
Merge config from 1.9.32.1
2014-09-19 10:47:08 -04:00
Jeffrey Crowell b43a973071 Merge config from 1.9.32.1 2014-09-19 10:30:38 -04:00
Steve Hill a524127d49 PSOL API change and unit tests for matches_device_type 2014-09-18 18:22:46 -04:00
Otto van der Schaaf 53a6de6da8 Merge pull request #797 from pagespeed/oschaaf-finalized-requests-fix
connection_read_handler: fix potential double free
2014-09-15 16:26:29 +02:00
Otto van der Schaaf 66f1b9aa9b older-nginx-versions: Add NGX_CONF_MULTI to ps_command flags.
Older nginx versions don't allow 'pagespeed' configuration
directives to appear in blocks other then http{} without it.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/786
2014-09-14 09:19:13 +02:00
Otto van der Schaaf 6903286aa4 connection_read_handler: fix potential double free
In connection_read_handler(), make sure we act accordingly when
r->connection->error is set (indicating the the current request has
been finalized).

Reproduction of what happens when we don't: enable IPRO+SPDY, and
rapidly refresh a page with chrome. These rapid abortions will
eventually trigger a segfault/hang/misc bad behaviour.
2014-09-13 16:30:34 +02:00
Otto van der Schaaf 46dc39f5a9 Merge pull request #794 from pagespeed/oschaaf-ipro-race
IPRO: Fix a race in processing writes() from NgxBaseFetch
2014-09-12 16:33:29 +02:00
Otto van der Schaaf 7d8fefe780 native-fetcher: remove a DCHECK that possibly fires on shutdown. 2014-09-11 23:33:22 +02:00
Otto van der Schaaf 43d1706e2f IPRO: Fix a race in processing writes() from NgxBaseFetch
For FetchInPlaceResource, NgxBaseFetch would send two bytes down its
pipe, one upon HeaderComplete() and one upon HandleDone(). We need
only one to resume processing on the nginx side.

There is a race between ps_connection_read_handler() and processing
of the byte send by NgxBaseFetch::HandleDone().
ps_connection_read_handler() clears the pipe when the request is
finalized, and also drains it on each event - so two writes could be
processed as one when lucky, masking the problem).

One concrete problem this solved for me was that SPDY + IPRO +
proxy_pass would segfault, hang, and/or pass on 5xx/404 responses
from IPRO lookup fetches to the browser, next to alerts about
r->count being zero in nginx's error.log

Might fix https://github.com/pagespeed/ngx_pagespeed/issues/788
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/792
2014-09-11 23:14:41 +02:00
Otto van der Schaaf 622d088a3e Merge pull request #790 from pagespeed/oschaaf-trunk-tracking-native-fetcher-keepalive
native fetcher: Support http keep-alive
2014-09-05 17:29:22 +02:00
Otto van der Schaaf 0290f52a88 native fetcher: Support http keep-alive
Based on @dinic his work, add keep-alive support for the native fetcher.
Adds a new option, usable at the http{} level in configuration:

pagespeed NativeFetcherMaxKeepaliveRequests 50;

The default value is 100 (aligned to nginx). Setting the value to 1 turns off
keep-alive requests altogether).

Most notable changes:
- Request keep-alive by adding the appropriate request header
- Fixes connections getting reused while they are servicing other requests:
- Remove connection from the pool of available connections for keepalive when applicable
- Disable keepalive in more appropriate situations
- Response parsing fixes
- Remove connections that timeout from the k.a. pool
- Add a few sanity (D)CHECKS
- Emit debug messages for traceability
- Fix for ignoring ipv6 addresses returned from dns queries when ipv6 is enabled.
- Bump the fetch timeout in test configuration to deflake tests that require dns
  lookups (which will be done via 8.8.8.8 currently for the native fetcher)
2014-09-05 17:23:16 +02:00
Maks Orlovich c94146a54d Merge pull request #791 from pagespeed/morlovich-trunk-tracking-remove-deprecated-headers
Remove use of deprecated forwarding headers
2014-09-04 16:06:52 -04:00
Maks Orlovich f3a1cb6cf4 Remove use of deprecated forwarding headers 2014-09-04 09:16:05 -04:00
33 changed files with 3646 additions and 2906 deletions
+45
View File
@@ -0,0 +1,45 @@
language: c++
install:
- mv $TRAVIS_BUILD_DIR ~/ngxpagespeed
- sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip g++ python gperf make devscripts fakeroot git curl netcat-traditional gcc-mozilla clang-3.4 2>&1 > /dev/null
- export PATH=/usr/lib/gcc-mozilla/bin:$PATH
- sudo ln -sf /usr/lib/gcc-mozilla/lib/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
# - sudo sh -c 'echo "image/webp webp" >> /etc/mime.types'
# - mkdir -p ~/bin
# - cd ~/bin
# - git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- mkdir ~/mod_pagespeed
- cd ~/mod_pagespeed
- git clone --recursive https://github.com/pagespeed/mod_pagespeed.git src
- cd src
- python build/gyp_chromium --depth=.
- cd ~/mod_pagespeed/src/pagespeed/automatic
- make BUILDTYPE=Release -C ../../pagespeed/automatic all
- cd ~
- git clone https://github.com/FRiCKLE/ngx_cache_purge.git
- NGX_CACHE_PURGE=$PWD/ngx_cache_purge
- wget https://openresty.org/download/ngx_openresty-1.9.7.2.tar.gz
- tar xzf ngx_openresty-*.tar.gz
- cd ngx_openresty-*/
- ./configure --with-luajit
- make
- NGX_DEVEL_KIT=$(echo $HOME/ngx_openresty-*/build/ngx_devel_kit-*/)
- SET_MISC_MODULE=$(echo $HOME/ngx_openresty-*/build/set-misc-nginx-module-*/)
- HEADERS_MORE_MODULE=$(echo $HOME/ngx_openresty-*/build/headers-more-nginx-module-*/)
- cd ~
- wget https://github.com/nginx/nginx/archive/branches/default.zip
- unzip default.zip
- cd nginx-branches-default
- MOD_PAGESPEED_DIR="$HOME/mod_pagespeed/src" ./auto/configure --add-module=$HOME/ngxpagespeed --add-module="$NGX_CACHE_PURGE" --add-module="$NGX_DEVEL_KIT" --add-module="$SET_MISC_MODULE" --add-module="$HEADERS_MORE_MODULE" --with-ipv6
- make
- sudo make install
script:
- echo "build successful"
- echo "cd ~/ngxpagespeed"
- echo "sudo ./test/run_tests.sh $HOME/mod_pagespeed $HOME/nginx-branches-default/objs/nginx"
sudo: required
compiler:
- gcc
notifications:
email:
- pagespeed-ci@googlegroups.com
+1
View File
@@ -0,0 +1 @@
https://dl.google.com/dl/page-speed/psol/1.12.34.2-$BIT_SIZE_NAME.tar.gz
+2
View File
@@ -1,5 +1,7 @@
![ngx_pagespeed](https://lh6.googleusercontent.com/-qufedJIJq7Y/UXEvVYxyYvI/AAAAAAAADo8/JHDFQhs91_c/s401/04_ngx_pagespeed.png)
[![Build Status](https://travis-ci.org/pagespeed/ngx_pagespeed.svg?branch=trunk-tracking)](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
+228 -57
View File
@@ -17,24 +17,36 @@
# PSOL_BINARY: absolute path to pagespeed_automatic.a
mod_pagespeed_dir="${MOD_PAGESPEED_DIR:-unset}"
position_aux="${POSITION_AUX:-unset}"
if [ "$mod_pagespeed_dir" = "unset" ] ; then
mod_pagespeed_dir="$ngx_addon_dir/psol/include"
build_from_source=false
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.4.tar.gz"
echo " $ tar -xzvf 1.9.32.4.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
@@ -65,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
@@ -77,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
@@ -95,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
@@ -103,8 +144,24 @@ psol_binary="${PSOL_BINARY:-unset}"
if [ "$psol_binary" = "unset" ] ; then
if $build_from_source ; then
psol_binary="\
$mod_pagespeed_dir/net/instaweb/automatic/pagespeed_automatic.a"
$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
@@ -127,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"
ngx_feature_libs="$pagespeed_libs"
ngx_feature_test="
GoogleString output_buffer;
net_instaweb::StringWriter write_to_string(&output_buffer);
@@ -162,52 +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_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_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"
# 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/")
# 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 objs/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"
+7
View File
@@ -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
+534
View File
@@ -0,0 +1,534 @@
#!/bin/bash
function usage() {
echo "
Usage: build_ngx_pagespeed.sh [options]
Installs ngx_pagespeed and its dependencies. Can optionally build and install
nginx as well.
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.
-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.
-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."
}
# Prints an error message and exits with an error code.
function fail() {
local error_message="$@"
echo "$@" >&2
# 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
}
# 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.
function run() {
if "$DRYRUN"; then
echo "would run $@"
else
if ! "$@"; then
echo "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
echo "Detected that we're missing the following depencencies:"
echo " $missing_dependencies"
echo "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() {
local prompt="$1"
read -p "$prompt [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:pdh \
--longoptions ngx-pagespeed-version:,nginx-version:,dynamic-module \
--longoptions buildir:,no-deps-check,dryrun,help \
-n "$(basename "$0")" -- "$@")
if [ $? != 0 ]; then
usage
exit 1
fi
eval set -- "$opts"
NPS_VERSION="latest-stable"
NGINX_VERSION=""
BUILDDIR="$HOME"
DO_DEPS_CHECK=true
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
;;
-d | --dryrun) shift
DRYRUN="true"
;;
-h | --help) shift
usage
exit 0
;;
--) shift
break
;;
*)
echo "Invalid argument: $1"
usage
exit 1
;;
esac
done
if [ ! -d "$BUILDDIR" ]; then
fail "Told to build in $BUILDDIR, but that directory doesn't exist."
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.
if 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
echo "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
echo "Detected that gcc is older than 4.8. Installing gcc-mozilla"
echo "which installs gcc-4.8 into /usr/lib/gcc-mozilla/ and doesn't"
echo "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
echo "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
echo "Detected that gcc is older than 4.8. Scientific Linux provides"
echo "a gcc package that installs gcc-4.8 into /opt/ and doesn't"
echo "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
echo "Dependencies are all set."
else
echo "Not checking whether 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."
exit 1
fi
continue_or_exit "OK to delete $directory?"
run rm -rf "$directory"
fi
}
nps_baseurl="https://github.com/pagespeed/ngx_pagespeed/archive"
# 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.
nps_url_fname="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.
nps_url_fname="$NPS_VERSION"
nps_downloaded_fname="ngx_pagespeed-${NPS_VERSION}"
fi
nps_downloaded="$TEMPDIR/$nps_downloaded_fname.zip"
run wget "$nps_baseurl/$nps_url_fname.zip" -O "$nps_downloaded"
nps_module_dir="$BUILDDIR/$nps_downloaded_fname"
delete_if_already_exists "$nps_module_dir"
echo "Extracting ngx_pagespeed..."
run unzip -q "$nps_downloaded" -d "$BUILDDIR"
run cd "$nps_module_dir"
# 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
run wget "$psol_url"
echo "Extracting PSOL..."
run tar -xzf $(basename "$psol_url") # extracts to psol/
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[@]}")
echo
if [ -z "$NGINX_VERSION" ]; then
# They didn't specify an nginx version, so we're just preparing the
# module for them to install.
echo "ngx_pagespeed is ready to be built against nginx."
echo "When running ./configure pass in:"
echo " $(quote_arguments "${configure_args[@]}")"
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 ./configure"
echo "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
# Download and build nginx.
nginx_leaf="nginx-${NGINX_VERSION}.tar.gz"
nginx_fname="$TEMPDIR/$nginx_leaf"
run wget "http://nginx.org/download/$nginx_leaf" -O "$nginx_fname"
nginx_dir="$BUILDDIR/nginx-${NGINX_VERSION}/"
delete_if_already_exists "$nginx_dir"
echo "Extracting nginx..."
run tar -xzf "$nginx_fname" --directory "$BUILDDIR"
"$DRYRUN" || cd "$nginx_dir"
configure=("./configure" "${configure_args[@]}")
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
echo "About to configure nginx with:"
echo " $(quote_arguments "${configure[@]}")"
continue_or_exit "Does this look right?"
run "${configure[@]}"
continue_or_exit "Build nginx?"
run make
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
if "$DRYRUN"; then
echo "[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 "$@"
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
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
-94
View File
@@ -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."
+5 -5
View File
@@ -29,7 +29,7 @@
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "net/instaweb/public/version.h"
#include "net/instaweb/util/public/string_util.h"
#include "pagespeed/kernel/base/string_util.h"
// Make sure we don't attempt to use LOG macros here, since doing so
// would cause us to go into an infinite log loop.
@@ -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);
}
}
+218 -43
View File
@@ -12,40 +12,193 @@
* 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/http/public/response_headers.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 "net/instaweb/util/public/google_message_handler.h"
#include "net/instaweb/util/public/message_handler.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/posix_timer.h"
#include "pagespeed/kernel/http/response_headers.h"
namespace net_instaweb {
NgxBaseFetch::NgxBaseFetch(ngx_http_request_t* r, int pipe_fd,
const char kHeadersComplete = 'H';
const char kFlush = 'F';
const char kDone = 'D';
NgxEventConnection* NgxBaseFetch::event_connection = NULL;
int NgxBaseFetch::active_base_fetches = 0;
NgxBaseFetch::NgxBaseFetch(StringPiece url,
ngx_http_request_t* r,
NgxServerContext* server_context,
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers)
PreserveCachingHeaders preserve_caching_headers,
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),
pipe_fd_(pipe_fd),
references_(2),
ipro_lookup_(false),
preserve_caching_headers_(preserve_caching_headers) {
base_fetch_type_(base_fetch_type),
preserve_caching_headers_(preserve_caching_headers),
detached_(false),
suppress_(false) {
if (pthread_mutex_init(&mutex_, NULL)) CHECK(0);
__sync_add_and_fetch(&NgxBaseFetch::active_base_fetches, 1);
}
NgxBaseFetch::~NgxBaseFetch() {
pthread_mutex_destroy(&mutex_);
__sync_add_and_fetch(&NgxBaseFetch::active_base_fetches, -1);
}
bool NgxBaseFetch::Initialize(ngx_cycle_t* cycle) {
CHECK(event_connection == NULL) << "event connection already set";
event_connection = new NgxEventConnection(ReadCallback);
return event_connection->Init(cycle);
}
void NgxBaseFetch::Terminate() {
if (event_connection != NULL) {
GoogleMessageHandler handler;
PosixTimer timer;
int64 timeout_us = Timer::kSecondUs * 30;
int64 end_us = timer.NowUs() + timeout_us;
static unsigned int sleep_microseconds = 100;
handler.Message(
kInfo,"NgxBaseFetch::Terminate rounding up %d active base fetches.",
NgxBaseFetch::active_base_fetches);
// Try to continue processing and get the active base fetch count to 0
// untill the timeout expires.
// TODO(oschaaf): This needs more work.
while (NgxBaseFetch::active_base_fetches > 0 && end_us > timer.NowUs()) {
event_connection->Drain();
usleep(sleep_microseconds);
}
if (NgxBaseFetch::active_base_fetches != 0) {
handler.Message(
kWarning,"NgxBaseFetch::Terminate timed out with %d active base fetches.",
NgxBaseFetch::active_base_fetches);
}
// Close down the named pipe.
event_connection->Shutdown();
delete event_connection;
event_connection = NULL;
}
}
const char* BaseFetchTypeToCStr(NgxBaseFetchType type) {
switch(type) {
case kPageSpeedResource:
return "ps resource";
case kHtmlTransform:
return "html transform";
case kAdminPage:
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();
bool detached = base_fetch->detached();
#if (NGX_DEBUG) // `type` is unused if NGX_DEBUG isn't set, needed for -Werror.
const char* type = BaseFetchTypeToCStr(base_fetch->base_fetch_type_);
#endif
int refcount = base_fetch->DecrementRefCount();
#if (NGX_DEBUG)
ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
"pagespeed [%p] event: %c. bf:%p (%s) - refcnt:%d - det: %c", r,
data.type, base_fetch, type, refcount, detached ? 'Y': 'N');
#endif
// If we ended up destructing the base fetch, or the request context is
// detached, skip this event.
if (refcount == 0 || detached) {
return;
}
ps_request_ctx_t* ctx = ps_get_request_context(r);
// 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 %d", r, r->count);
rc = NGX_ERROR;
run_posted = false;
} else {
rc = ps_base_fetch::ps_base_fetch_handler(r);
}
#if (NGX_DEBUG)
ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
"pagespeed [%p] ps_base_fetch_handler() returned %d for %c",
r, rc, data.type);
#endif
ngx_connection_t* c = r->connection;
ngx_http_finalize_request(r, rc);
if (run_posted) {
// See http://forum.nginx.org/read.php?2,253006,253061
ngx_http_run_posted_requests(c);
}
}
void NgxBaseFetch::Lock() {
@@ -75,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;
}
@@ -104,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()) {
@@ -115,21 +278,19 @@ ngx_int_t NgxBaseFetch::CollectHeaders(ngx_http_headers_out_t* headers_out) {
preserve_caching_headers_);
}
void NgxBaseFetch::RequestCollection() {
int rc;
char c = 'A'; // What byte we write is arbitrary.
while (true) {
rc = write(pipe_fd_, &c, 1);
if (rc == 1) {
break;
} else if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
// TODO(jefftk): is this rare enough that spinning isn't a problem? Could
// we get into a case where the pipe fills up and we spin forever?
void NgxBaseFetch::RequestCollection(char type) {
if (suppress_) {
return;
}
} else {
perror("NgxBaseFetch::RequestCollection");
break;
}
// We must optimistically increment the refcount, and decrement it
// when we conclude we failed. If we only increment on a successfull write,
// there's a small chance that between writing and adding to the refcount
// both pagespeed and nginx will release their refcount -- destructing
// this NgxBaseFetch instance.
IncrementRefCount();
if (!event_connection->WriteEvent(type, this)) {
DecrementRefCount();
}
}
@@ -137,49 +298,63 @@ void NgxBaseFetch::HandleHeadersComplete() {
int status_code = response_headers()->status_code();
bool status_ok = (status_code != 0) && (status_code < 400);
if (!ipro_lookup_ || status_ok) {
if ((base_fetch_type_ != kIproLookup) || status_ok) {
// If this is a 404 response we need to count it in the stats.
if (response_headers()->status_code() == HttpStatus::kNotFound) {
server_context_->rewrite_stats()->resource_404_count()->Add(1);
}
}
// For the IPRO lookup, suppress notification of the nginx side here.
// If we send both this event and the one from done, nasty stuff will happen
// if we loose the race with with the nginx side destructing this base fetch
// instance (and thereby clearing the byte and its pending extraneous event.
if (!ipro_lookup_) {
RequestCollection(); // Headers available.
RequestCollection(kHeadersComplete); // Headers available.
// For the IPRO lookup, supress notification of the nginx side here.
// If we send both the headerscomplete event and the one from done, nasty
// stuff will happen if we loose the race with with the nginx side destructing
// this base fetch instance.
if (base_fetch_type_ == kIproLookup && !status_ok) {
suppress_ = true;
}
}
bool NgxBaseFetch::HandleFlush(MessageHandler* handler) {
RequestCollection(); // A new part of the response body is available.
Lock();
need_flush_ = true;
Unlock();
RequestCollection(kFlush); // A new part of the response body is available
return true;
}
void NgxBaseFetch::Release() {
DecrefAndDeleteIfUnreferenced();
int NgxBaseFetch::DecrementRefCount() {
return DecrefAndDeleteIfUnreferenced();
}
void NgxBaseFetch::DecrefAndDeleteIfUnreferenced() {
int NgxBaseFetch::IncrementRefCount() {
return __sync_add_and_fetch(&references_, 1);
}
int NgxBaseFetch::DecrefAndDeleteIfUnreferenced() {
// Creates a full memory barrier.
if (__sync_add_and_fetch(&references_, -1) == 0) {
int r = __sync_add_and_fetch(&references_, -1);
if (r == 0) {
delete this;
}
return r;
}
void NgxBaseFetch::HandleDone(bool success) {
// TODO(jefftk): it's possible that instead of locking here we can just modify
// CopyBufferToNginx to only read done_called_ once.
CHECK(!done_called_) << "Done already called!";
Lock();
done_called_ = true;
Unlock();
close(pipe_fd_); // Indicates to nginx that we're done with the rewrite.
pipe_fd_ = -1;
RequestCollection(kDone);
DecrefAndDeleteIfUnreferenced();
}
bool NgxBaseFetch::IsCachedResultValid(const ResponseHeaders& headers) {
return OptionsAwareHTTPCacheCallback::IsCacheValid(
url_, *options_, request_context(), headers);
}
} // namespace net_instaweb
+86 -22
View File
@@ -17,22 +17,35 @@
// Author: jefftk@google.com (Jeff Kaufman)
//
// Collects output from pagespeed and buffers it until nginx asks for it.
// Notifies nginx via pipe to call CollectAccumulatedWrites() on flush.
// Notifies nginx via NgxEventConnection to call ReadCallback() when
// the headers are computed, when a flush should be performed, and when done.
//
// - nginx creates a base fetch and passes it to a new proxy fetch.
// - The proxy fetch manages rewriting and thread complexity, and through
// several chained steps passes rewritten html to HandleWrite().
// - Written data is buffered.
// - When Flush() is called the base fetch writes a byte to a pipe nginx is
// watching so nginx knows to call CollectAccumulatedWrites() to pick up the
// rewritten html.
// - When Done() is called the base fetch closes the pipe, which tells nginx to
// make a final call to CollectAccumulatedWrites().
// - When HandleHeadersComplete(), HandleFlush(), or HandleDone() is called by
// PSOL, events are written to NgxEventConnection which will end up being
// handled by ReadCallback() on nginx's thread.
// When applicable, request processing will be continued via a call to
// ps_base_fetch_handler().
// - ps_base_fetch_handler() will pull the header and body bytes from PSOL
// via CollectAccumulatedWrites() and write those to the module's output.
//
// This class is referred two in two places: the proxy fetch and nginx's
// request. It must stay alive until both are finished. The proxy fetch will
// call Done() to indicate this; nginx will call Release(). Once both Done()
// and Release() have been called this class will delete itself.
// This class is referred to in three places: the proxy fetch, nginx's request,
// and pending events written to the associated NgxEventConnection. It must stay
// alive until the proxy fetch and nginx request are finished, and no more
// events are pending.
// - The proxy fetch will call Done() to indicate this.
// - nginx will call Detach() when the associated request is handled
// completely (e.g. the request context is about to be destroyed).
// - ReadCallback() will call DecrementRefCount() on instances associated to
// 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_
@@ -45,22 +58,46 @@ extern "C" {
#include "ngx_pagespeed.h"
#include "ngx_event_connection.h"
#include "ngx_server_context.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/headers.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/http/headers.h"
namespace net_instaweb {
enum NgxBaseFetchType {
kIproLookup,
kHtmlTransform,
kPageSpeedResource,
kAdminPage,
kPageSpeedProxy
};
class NgxBaseFetch : public AsyncFetch {
public:
NgxBaseFetch(ngx_http_request_t* r, int pipe_fd,
NgxBaseFetch(StringPiece url, ngx_http_request_t* r,
NgxServerContext* server_context,
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers);
PreserveCachingHeaders preserve_caching_headers,
NgxBaseFetchType base_fetch_type,
const RewriteOptions* options);
virtual ~NgxBaseFetch();
// Statically initializes event_connection, require for PSOL and nginx to
// communicate.
static bool Initialize(ngx_cycle_t* cycle);
// Attempts to finish up request processing queued up in the named pipe and
// PSOL for a fixed amount of time. If time is up, a fast and rough shutdown
// is attempted.
// Statically terminates and NULLS event_connection.
static void Terminate();
static void ReadCallback(const ps_event_data& data);
// Puts a chain in link_ptr if we have any output data buffered. Returns
// NGX_OK on success, NGX_ERROR on errors. If there's no data to send, sends
// data only if Done() has been called. Indicates the end of output by
@@ -77,9 +114,24 @@ class NgxBaseFetch : public AsyncFetch {
// time for resource fetches. Not called at all for proxy fetches.
ngx_int_t CollectHeaders(ngx_http_headers_out_t* headers_out);
// Called by nginx when it's done with us.
void Release();
void set_ipro_lookup(bool x) { ipro_lookup_ = x; }
// Called by nginx to decrement the refcount.
int DecrementRefCount();
// Called by pagespeed to increment the refcount.
int IncrementRefCount();
// Detach() is called when the nginx side releases this base fetch. It
// sets detached_ to true and decrements the refcount. We need to know
// this to be able to handle events which nginx request context has been
// released while the event was in-flight.
void Detach() { detached_ = true; DecrementRefCount(); }
bool detached() { return detached_; }
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);
@@ -89,7 +141,7 @@ class NgxBaseFetch : public AsyncFetch {
// Indicate to nginx that we would like it to call
// CollectAccumulatedWrites().
void RequestCollection();
void RequestCollection(char type);
// Lock must be acquired first.
// Returns:
@@ -105,20 +157,32 @@ class NgxBaseFetch : public AsyncFetch {
// Called by Done() and Release(). Decrements our reference count, and if
// it's zero we delete ourself.
void DecrefAndDeleteIfUnreferenced();
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_;
int pipe_fd_;
// How many active references there are to this fetch. Starts at two,
// decremented once when Done() is called and once when Release() is called.
// decremented once when Done() is called and once when Detach() is called.
// Incremented for each event written by pagespeed for this NgxBaseFetch, and
// decremented on the nginx side for each event read for it.
int references_;
pthread_mutex_t mutex_;
bool ipro_lookup_;
NgxBaseFetchType base_fetch_type_;
PreserveCachingHeaders preserve_caching_headers_;
// Set to true just before the nginx side releases its reference
bool detached_;
bool suppress_;
DISALLOW_COPY_AND_ASSIGN(NgxBaseFetch);
};
+172
View File
@@ -0,0 +1,172 @@
/*
* Copyright 2014 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: oschaaf@we-amp.com (Otto van der Schaaf)
extern "C" {
#include <ngx_channel.h>
}
#include "ngx_event_connection.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/message_handler.h"
namespace net_instaweb {
NgxEventConnection::NgxEventConnection(callbackPtr callback)
: event_handler_(callback) {
}
bool NgxEventConnection::Init(ngx_cycle_t* cycle) {
int file_descriptors[2];
if (pipe(file_descriptors) != 0) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "pagespeed: pipe() failed");
return false;
}
if (ngx_nonblocking(file_descriptors[0]) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_nonblocking_n "pagespeed: pipe[0] failed");
} else if (ngx_nonblocking(file_descriptors[1]) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_nonblocking_n "pagespeed: pipe[1] failed");
} else if (!CreateNgxConnection(cycle, file_descriptors[0])) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"pagespeed: failed to create connection.");
} else {
pipe_read_fd_ = file_descriptors[0];
pipe_write_fd_ = file_descriptors[1];
return true;
}
close(file_descriptors[0]);
close(file_descriptors[1]);
return false;
}
bool NgxEventConnection::CreateNgxConnection(ngx_cycle_t* cycle,
ngx_fd_t pipe_fd) {
// pipe_fd (the read side of the pipe will end up as c->fd on the
// underlying ngx_connection_t that gets created here)
ngx_int_t rc = ngx_add_channel_event(cycle, pipe_fd, NGX_READ_EVENT,
&NgxEventConnection::ReadEventHandler);
return rc == NGX_OK;
}
void NgxEventConnection::ReadEventHandler(ngx_event_t* ev) {
ngx_connection_t* c = static_cast<ngx_connection_t*>(ev->data);
ngx_int_t result = ngx_handle_read_event(ev, 0);
if (result != NGX_OK) {
CHECK(false) << "pagespeed: ngx_handle_read_event error: " << result;
}
if (ev->timedout) {
ev->timedout = 0;
return;
}
if (!NgxEventConnection::ReadAndNotify(c->fd)) {
// This was copied from ngx_channel_handler(): for epoll, we need to call
// ngx_del_conn(). Sadly, no documentation as to why.
if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
ngx_del_conn(c, 0);
}
ngx_close_connection(c);
ngx_del_event(ev, NGX_READ_EVENT, 0);
}
}
// Deserialize ps_event_data's from the pipe as they become available.
// Subsequently do some bookkeeping, cleanup, and error checking to keep
// the mess out of ps_base_fetch_handler.
bool NgxEventConnection::ReadAndNotify(ngx_fd_t fd) {
while (true) {
// We read only one ps_event_data at a time for now:
// We can end up recursing all the way and end up calling ourselves here.
// If that happens in the middle of looping over multiple ps_event_data's we
// have obtained with read(), the results from the next read() will make us
// process events out of order. Which can give headaches.
// Alternatively, we could maintain a queue to make sure we process in
// sequence
ps_event_data data;
ngx_int_t size = read(fd, static_cast<void*>(&data), sizeof(data));
if (size == -1) {
if (errno == EINTR) {
continue;
// TODO(oschaaf): should we worry about spinning here?
} else if (ngx_errno == EAGAIN || ngx_errno == EWOULDBLOCK) {
return true;
}
}
if (size <= 0) {
return false;
}
data.connection->event_handler_(data);
return true;
}
}
bool NgxEventConnection::WriteEvent(void* sender) {
return WriteEvent('X' /* Anything char is fine */, sender);
}
bool NgxEventConnection::WriteEvent(char type, void* sender) {
ssize_t size = 0;
ps_event_data data;
ngx_memzero(&data, sizeof(data));
data.type = type;
data.sender = sender;
data.connection = this;
while (true) {
size = write(pipe_write_fd_,
static_cast<void*>(&data), sizeof(data));
if (size == sizeof(data)) {
return true;
} else if (size == -1) {
// TODO(oschaaf): should we worry about spinning here?
if (ngx_errno == EINTR || ngx_errno == EAGAIN
|| ngx_errno == EWOULDBLOCK) {
continue;
} else {
return false;
}
} else {
CHECK(false) << "pagespeed: unexpected return value from write(): "
<< size;
}
}
CHECK(false) << "Should not get here";
return false;
}
// Reads and processes what is available in the pipe.
void NgxEventConnection::Drain() {
NgxEventConnection::ReadAndNotify(pipe_read_fd_);
}
void NgxEventConnection::Shutdown() {
close(pipe_write_fd_);
close(pipe_read_fd_);
}
} // namespace net_instaweb
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright 2014 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: oschaaf@we-amp.com (Otto van der Schaaf)
//
// NgxEventConnection implements a means to send events from other threads to
// nginx's event loop, and is implemented by a named pipe under the hood.
// A single instance is used by NgxBaseFetch, and one instance is created per
// NgxUrlAsyncFetcher when native fetching is on.
#ifndef NGX_EVENT_CONNECTION_H_
#define NGX_EVENT_CONNECTION_H_
extern "C" {
#include <ngx_http.h>
}
#include <pthread.h>
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/http/headers.h"
namespace net_instaweb {
class NgxEventConnection;
// Represents a single event that can be written to or read from the pipe.
// Technically, sender is the only data we need to send. type and connection are
// included to provide a means to trace the events along with some more
// info.
typedef struct {
char type;
void* sender;
NgxEventConnection* connection;
} ps_event_data;
// Handler signature for receiving events
typedef void (*callbackPtr)(const ps_event_data&);
// Abstracts a connection to nginx through which events can be written.
class NgxEventConnection {
public:
explicit NgxEventConnection(callbackPtr handler);
// Creates the file descriptors and ngx_connection_t required for event
// messaging between pagespeed and nginx.
bool Init(ngx_cycle_t* cycle);
// Shuts down the underlying file descriptors and connection created in Init()
void Shutdown();
// Constructs a ps_event_data and writes it to the underlying named pipe.
bool WriteEvent(char type, void* sender);
// Convenience overload for clients that have a single event type.
bool WriteEvent(void* sender);
// Reads and processes what is available in the named pipe's buffer.
void Drain();
private:
static bool CreateNgxConnection(ngx_cycle_t* cycle, ngx_fd_t pipe_fd);
static void ReadEventHandler(ngx_event_t* e);
static bool ReadAndNotify(ngx_fd_t fd);
callbackPtr event_handler_;
// We own these file descriptors
ngx_fd_t pipe_write_fd_;
ngx_fd_t pipe_read_fd_;
DISALLOW_COPY_AND_ASSIGN(NgxEventConnection);
};
} // namespace net_instaweb
#endif // NGX_EVENT_CONNECTION_H_
+97 -130
View File
@@ -37,7 +37,7 @@ extern "C" {
}
#include "ngx_fetch.h"
#include "net/instaweb/util/public/basictypes.h"
#include "base/logging.h"
#include <algorithm>
@@ -45,71 +45,28 @@ extern "C" {
#include <typeinfo>
#include <vector>
#include "net/instaweb/util/public/scoped_ptr.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/inflating_fetch.h"
#include "net/instaweb/http/public/request_headers.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/http/public/response_headers_parser.h"
#include "net/instaweb/public/version.h"
#include "net/instaweb/public/global_constants.h"
#include "net/instaweb/util/public/condvar.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/pool.h"
#include "net/instaweb/util/public/pool_element.h"
#include "net/instaweb/util/public/pthread_mutex.h"
#include "net/instaweb/util/public/statistics.h"
#include "net/instaweb/util/public/string_writer.h"
#include "net/instaweb/util/public/string_util.h"
#include "net/instaweb/util/public/thread_system.h"
#include "net/instaweb/util/public/timer.h"
#include "net/instaweb/util/public/writer.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/condvar.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/pool.h"
#include "pagespeed/kernel/base/pool_element.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string_writer.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/base/writer.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/response_headers_parser.h"
namespace net_instaweb {
class NgxConnection : public PoolElement<NgxConnection> {
public:
NgxConnection(MessageHandler* handler, int max_keepalive_requests);
~NgxConnection();
void SetSock(u_char *sockaddr, socklen_t socklen) {
socklen_ = socklen;
ngx_memcpy(&sockaddr_, sockaddr, socklen);
}
// Close ensures that NgxConnection deletes itself at the appropriate time,
// which can be after receiving a non-keepalive response, or when the remote
// server closes the connection when the NgxConnection is pooled and idle.
void Close();
// Once keepalive is disabled, it can't be toggled back on.
void set_keepalive(bool k) { keepalive_ = keepalive_ && k; }
bool keepalive() { return keepalive_; }
typedef Pool<NgxConnection> NgxConnectionPool;
static NgxConnection* Connect(ngx_peer_connection_t* pc,
MessageHandler* handler,
int max_keepalive_requests);
static void IdleWriteHandler(ngx_event_t* ev);
static void IdleReadHandler(ngx_event_t* ev);
static NgxConnectionPool connection_pool;
static PthreadMutex connection_pool_mutex;
// c_ is owned by NgxConnection and freed in ::Close()
ngx_connection_t* c_;
static const int64 keepalive_timeout_ms;
static const GoogleString ka_header;
private:
int max_keepalive_requests_;
bool keepalive_;
socklen_t socklen_;
u_char sockaddr_[NGX_SOCKADDRLEN];
MessageHandler* handler_;
DISALLOW_COPY_AND_ASSIGN(NgxConnection);
};
NgxConnection::NgxConnectionPool NgxConnection::connection_pool;
PthreadMutex NgxConnection::connection_pool_mutex;
// Default keepalive 60s.
@@ -130,7 +87,18 @@ NgxConnection::NgxConnection(MessageHandler* handler,
}
NgxConnection::~NgxConnection() {
CHECK(c_ == NULL) << "NgxFetch: Underlying connection should be NULL";
CHECK(c_ == NULL) << "NgxConnection: Underlying connection should be NULL";
}
void NgxConnection::Terminate() {
for (NgxConnectionPool::iterator p = connection_pool.begin();
p != connection_pool.end(); ++p) {
NgxConnection* nc = *p;
ngx_close_connection(nc->c_);
nc->c_ = NULL;
delete nc;
}
connection_pool.Clear();
}
NgxConnection* NgxConnection::Connect(ngx_peer_connection_t* pc,
@@ -163,7 +131,7 @@ NgxConnection* NgxConnection::Connect(ngx_peer_connection_t* pc,
connection_pool.Remove(nc);
ngx_log_error(NGX_LOG_DEBUG, pc->log, 0,
"NgxFetch: re-using connection %p (pool size: %l)\n",
"NgxFetch: re-using connection %p (pool size: %l)",
nc, connection_pool.size());
return nc;
}
@@ -194,7 +162,7 @@ void NgxConnection::Close() {
// out or has been closed remotely.
connection_pool.Remove(this);
ngx_log_error(NGX_LOG_DEBUG, c_->log, 0,
"NgxFetch: removed connection %p (pool size: %l)\n",
"NgxFetch: removed connection %p (pool size: %l)",
this, connection_pool.size());
removed_from_pool = true;
break;
@@ -241,7 +209,7 @@ void NgxConnection::Close() {
connection_pool.Add(this);
ngx_log_error(NGX_LOG_DEBUG, c_->log, 0,
"NgxFetch: Added connection %p (pool size: %l - "
" max_keepalive_requests_ %d)\n",
" max_keepalive_requests_ %d)",
this, connection_pool.size(), max_keepalive_requests_);
}
}
@@ -329,7 +297,7 @@ bool NgxFetch::Start(NgxUrlAsyncFetcher* fetcher) {
fetcher_ = fetcher;
bool ok = Init();
if (ok) {
ngx_log_error(NGX_LOG_DEBUG, log_, 0, "NgxFetch %p: initialized\n",
ngx_log_error(NGX_LOG_DEBUG, log_, 0, "NgxFetch %p: initialized",
this);
} // else Init() will have emitted a reason
return ok;
@@ -347,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;
}
@@ -414,7 +384,7 @@ bool NgxFetch::Init() {
return false;
} else {
ngx_log_error(NGX_LOG_DEBUG, log_, 0,
"NgxFetch %p: start resolve for: %s\n",
"NgxFetch %p: start resolve for: %s",
this, s_ipaddress.c_str());
}
@@ -447,10 +417,10 @@ const char* NgxFetch::str_url() {
return str_url_.c_str();
}
// This function should be called only once. The only argument is success or
// This function should be called only once. The only argument is sucess or
// not.
void NgxFetch::CallbackDone(bool success) {
ngx_log_error(NGX_LOG_DEBUG, log_, 0, "NgxFetch %p: CallbackDone: %s\n",
ngx_log_error(NGX_LOG_DEBUG, log_, 0, "NgxFetch %p: CallbackDone: %s",
this, success ? "OK":"FAIL");
if (async_fetch_ == NULL) {
@@ -487,7 +457,7 @@ void NgxFetch::CallbackDone(bool success) {
}
}
ngx_log_error(NGX_LOG_DEBUG, log_, 0,
"NgxFetch %p: connection %p attempt keep-alive: %s\n",
"NgxFetch %p: connection %p attempt keep-alive: %s",
this, connection_, keepalive ? "Yes":"No");
}
@@ -496,9 +466,6 @@ void NgxFetch::CallbackDone(bool success) {
connection_ = NULL;
}
// TODO(oschaaf): see https://github.com/pagespeed/ngx_pagespeed/pull/755
async_fetch_->Done(success);
if (fetcher_ != NULL) {
if (fetcher_->track_original_content_length()
&& async_fetch_->response_headers()->Has(
@@ -508,7 +475,7 @@ void NgxFetch::CallbackDone(bool success) {
}
fetcher_->FetchComplete(this);
}
async_fetch_->Done(success);
async_fetch_ = NULL;
}
@@ -739,7 +706,7 @@ int NgxFetch::Connect() {
connection_ = NgxConnection::Connect(&pc, message_handler(),
fetcher_->max_keepalive_requests_);
ngx_log_error(NGX_LOG_DEBUG, fetcher_->log_, 0,
"NgxFetch %p Connect() connection %p for [%s]\n",
"NgxFetch %p Connect() connection %p for [%s]",
this, connection_, str_url());
if (connection_ == NULL) {
@@ -755,13 +722,13 @@ int NgxFetch::Connect() {
}
// When the fetch sends the request completely, it will hook the read event,
// and prepare to parse the response.
// and prepare to parse the response. Timer set in Init() is still in effect.
void NgxFetch::ConnectionWriteHandler(ngx_event_t* wev) {
ngx_connection_t* c = static_cast<ngx_connection_t*>(wev->data);
NgxFetch* fetch = static_cast<NgxFetch*>(c->data);
ngx_buf_t* out = fetch->out_;
while (out->pos < out->last) {
bool ok = true;
while (wev->ready && out->pos < out->last) {
int n = c->send(c, out->pos, out->last - out->pos);
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: ConnectionWriteHandler "
@@ -770,31 +737,36 @@ void NgxFetch::ConnectionWriteHandler(ngx_event_t* wev) {
if (n >= 0) {
out->pos += n;
} else if (n == NGX_AGAIN) {
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
fetch->CallbackDone(false);
}
// Timer set in Init() is still in effect.
return;
break;
} else {
c->error = 1;
fetch->CallbackDone(false);
return;
ok = false;
break;
}
}
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
if (ok) {
if (out->pos == out->last) {
ok = ngx_handle_read_event(c->read, 0) == NGX_OK;
} else {
ok = ngx_handle_write_event(c->write, 0) == NGX_OK;
}
}
if (!ok) {
fetch->message_handler()->Message(
kWarning, "NgxFetch %p: failed to hook next event", fetch);
c->error = 1;
fetch->CallbackDone(false);
}
return;
}
// Timer set in Init() is still in effect.
void NgxFetch::ConnectionReadHandler(ngx_event_t* rev) {
ngx_connection_t* c = static_cast<ngx_connection_t*>(rev->data);
NgxFetch* fetch = static_cast<NgxFetch*>(c->data);
bool ok = true;
for (;;) {
while(rev->ready) {
int n = c->recv(
c, fetch->in_->start, fetch->in_->end - fetch->in_->start);
@@ -804,56 +776,39 @@ void NgxFetch::ConnectionReadHandler(ngx_event_t* rev) {
if (n == NGX_AGAIN) {
break;
}
if (n == 0) {
} else if (n == 0) {
// If the content length was not known, we assume that we have read
// all if we at least parsed the headers.
// If we do know the content length, having a mismatch on the bytes read
// will be interpreted as an error.
if (fetch->content_length_known_) {
fetch->CallbackDone(fetch->content_length_ == fetch->bytes_received_);
} else {
fetch->CallbackDone(fetch->parser_.headers_complete());
}
return;
ok = (fetch->content_length_known_ && fetch->content_length_ == fetch->bytes_received_)
|| fetch->parser_.headers_complete();
fetch->done_ = true;
break;
} else if (n > 0) {
fetch->in_->pos = fetch->in_->start;
fetch->in_->last = fetch->in_->start + n;
if (!fetch->response_handler(c)) {
fetch->CallbackDone(false);
return;
ok = fetch->response_handler(c);
if (fetch->done_ || !ok) {
break;
}
if (fetch->done_) {
fetch->CallbackDone(true);
return;
}
}
if (!rev->ready) {
break;
}
}
if (fetch->done_) {
if (!ok) {
fetch->CallbackDone(false);
} else if (fetch->done_) {
fetch->CallbackDone(true);
return;
}
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
} else if (ngx_handle_read_event(rev, 0) != NGX_OK) {
fetch->CallbackDone(false);
}
// Timer set in Init() is still in effect.
}
// Parse the status line: "HTTP/1.1 200 OK\r\n"
bool NgxFetch::HandleStatusLine(ngx_connection_t* c) {
NgxFetch* fetch = static_cast<NgxFetch*>(c->data);
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: Handle status line\n", fetch);
"NgxFetch %p: Handle status line", fetch);
// This function only works after Nginx-1.1.4. Before nginx-1.1.4,
// ngx_http_parse_status_line didn't save http_version.
@@ -866,14 +821,20 @@ bool NgxFetch::HandleStatusLine(ngx_connection_t* c) {
} else if (n == NGX_AGAIN) { // not completed
return true;
}
ResponseHeaders* response_headers =
fetch->async_fetch_->response_headers();
response_headers->SetStatusAndReason(
static_cast<HttpStatus::Code>(fetch->get_status_code()));
response_headers->set_major_version(fetch->get_major_version());
response_headers->set_minor_version(fetch->get_minor_version());
fetch->in_->pos += n;
fetch->set_response_handler(NgxFetch::HandleHeader);
return fetch->response_handler(c);
if ((fetch->in_->last - fetch->in_->pos) > 0) {
return fetch->response_handler(c);
}
return true;
}
// Parse the HTTP headers
@@ -885,12 +846,16 @@ bool NgxFetch::HandleHeader(ngx_connection_t* c) {
fetch->message_handler_);
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: Handle headers\n", fetch);
"NgxFetch %p: Handle headers", fetch);
if (n > size) {
return false;
} else if (fetch->parser_.headers_complete()) {
if (fetch->async_fetch_->response_headers()->FindContentLength(
// TODO(oschaaf): We should also check if the request method was HEAD
// - but I don't think PSOL uses that at this point.
if (fetch->get_status_code() == 304 || fetch->get_status_code() == 204) {
fetch->done_ = true;
} else if (fetch->async_fetch_->response_headers()->FindContentLength(
&fetch->content_length_)) {
if (fetch->content_length_ < 0) {
fetch->message_handler_->Message(
@@ -911,9 +876,11 @@ bool NgxFetch::HandleHeader(ngx_connection_t* c) {
}
fetch->in_->pos += n;
fetch->set_response_handler(NgxFetch::HandleBody);
if ((fetch->in_->last - fetch->in_->pos) > 0) {
return fetch->response_handler(c);
if (!fetch->done_) {
fetch->set_response_handler(NgxFetch::HandleBody);
if ((fetch->in_->last - fetch->in_->pos) > 0) {
return fetch->response_handler(c);
}
}
} else {
fetch->in_->pos += n;
@@ -930,7 +897,7 @@ bool NgxFetch::HandleBody(ngx_connection_t* c) {
fetch->bytes_received_add(size);
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: Handle body (%d bytes)\n", fetch, size);
"NgxFetch %p: Handle body (%d bytes)", fetch, size);
if ( fetch->async_fetch_->Write(StringPiece(data, size),
fetch->message_handler()) ) {
@@ -940,7 +907,7 @@ bool NgxFetch::HandleBody(ngx_connection_t* c) {
fetch->in_->pos += size;
} else {
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: async fetch write failure\n", fetch);
"NgxFetch %p: async fetch write failure", fetch);
return false;
}
return true;
@@ -949,7 +916,7 @@ bool NgxFetch::HandleBody(ngx_connection_t* c) {
void NgxFetch::TimeoutHandler(ngx_event_t* tev) {
NgxFetch* fetch = static_cast<NgxFetch*>(tev->data);
ngx_log_error(NGX_LOG_DEBUG, fetch->log_, 0,
"NgxFetch %p: TimeoutHandler called\n", fetch);
"NgxFetch %p: TimeoutHandler called", fetch);
fetch->CallbackDone(false);
}
@@ -973,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;
}
+52 -5
View File
@@ -39,12 +39,14 @@ extern "C" {
#include "ngx_url_async_fetcher.h"
#include <vector>
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/pool.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/http/public/url_async_fetcher.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/http/public/response_headers_parser.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/pool.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/response_headers_parser.h"
#include "pagespeed/kernel/thread/pthread_mutex.h"
namespace net_instaweb {
@@ -53,6 +55,51 @@ typedef bool (*response_handler_pt)(ngx_connection_t* c);
class NgxUrlAsyncFetcher;
class NgxConnection;
class NgxConnection : public PoolElement<NgxConnection> {
public:
NgxConnection(MessageHandler* handler, int max_keepalive_requests);
~NgxConnection();
void SetSock(u_char *sockaddr, socklen_t socklen) {
socklen_ = socklen;
ngx_memcpy(&sockaddr_, sockaddr, socklen);
}
// Close ensures that NgxConnection deletes itself at the appropriate time,
// which can be after receiving a non-keepalive response, or when the remote
// server closes the connection when the NgxConnection is pooled and idle.
void Close();
// Once keepalive is disabled, it can't be toggled back on.
void set_keepalive(bool k) { keepalive_ = keepalive_ && k; }
bool keepalive() { return keepalive_; }
typedef Pool<NgxConnection> NgxConnectionPool;
static NgxConnection* Connect(ngx_peer_connection_t* pc,
MessageHandler* handler,
int max_keepalive_requests);
static void IdleWriteHandler(ngx_event_t* ev);
static void IdleReadHandler(ngx_event_t* ev);
// Terminate will cleanup any idle connections upon shutdown.
static void Terminate();
static NgxConnectionPool connection_pool;
static PthreadMutex connection_pool_mutex;
// c_ is owned by NgxConnection and freed in ::Close()
ngx_connection_t* c_;
static const int64 keepalive_timeout_ms;
static const GoogleString ka_header;
private:
int max_keepalive_requests_;
bool keepalive_;
socklen_t socklen_;
u_char sockaddr_[NGX_SOCKADDRLEN];
MessageHandler* handler_;
DISALLOW_COPY_AND_ASSIGN(NgxConnection);
};
class NgxFetch : public PoolElement<NgxFetch> {
public:
NgxFetch(const GoogleString& url,
+4 -15
View File
@@ -70,7 +70,7 @@ extern "C" {
}
}
NgxGZipSetter::NgxGZipSetter() : enabled_(false), initialized_(false) { }
NgxGZipSetter::NgxGZipSetter() : enabled_(0) { }
NgxGZipSetter::~NgxGZipSetter() { }
// Helper functions to determine signature.
@@ -95,7 +95,7 @@ bool IsNgxBitmaskCommand(ngx_command_t* command) {
HasLocalConfig(command));
}
// Initialize the NgxGZipSetter.
// Initialize the NgxGzipSetter.
// Find the gzip, gzip_vary, gzip_http_version and gzip_types commands in the
// gzip module. Enable if the signature of the zip command matches with what we
// trust. Also sets up redirects for the configurations. These redirect handle
@@ -105,16 +105,6 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
#if (NGX_HTTP_GZIP)
bool gzip_signature_mismatch = false;
bool other_signature_mismatch = false;
// If we initialized already we don't have to scan again.
if (initialized_) {
// Config might have changed, so re-enable if we have gzip.
if (gzip_command_.command_ != NULL) {
enabled_ = true;
} else {
enabled_ = false;
}
return;
}
for (int m = 0; ngx_modules[m] != NULL; m++) {
if (ngx_modules[m]->commands != NULL) {
for (int c = 0; ngx_modules[m]->commands[c].name.len; c++) {
@@ -132,7 +122,7 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
current_command->set = ngx_gzip_redirect_conf_set_flag_slot;
gzip_command_.command_ = current_command;
gzip_command_.module_ = ngx_modules[m];
enabled_ = true;
enabled_ = 1;
} else {
ngx_conf_log_error(
NGX_LOG_WARN, cf, 0,
@@ -199,7 +189,6 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
}
}
}
initialized_ = true;
if (gzip_signature_mismatch) {
return; // Already logged error.
} else if (!enabled_) {
@@ -392,7 +381,7 @@ void NgxGZipSetter::AddGZipHTTPTypes(ngx_conf_t* cf) {
}
void NgxGZipSetter::RollBackAndDisable(ngx_conf_t* cf) {
ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0,
ngx_conf_log_error(NGX_LOG_INFO, cf, 0,
"pagespeed: rollback gzip, explicit configuration");
for (std::vector<ngx_flag_t*>::iterator i = ngx_flags_set_.begin();
i != ngx_flags_set_.end(); ++i) {
+1 -2
View File
@@ -60,7 +60,7 @@ extern "C" {
#include "ngx_pagespeed.h"
#include "net/instaweb/util/public/basictypes.h"
#include "pagespeed/kernel/base/basictypes.h"
namespace net_instaweb {
@@ -91,7 +91,6 @@ class NgxGZipSetter {
ngx_command_ctx gzip_vary_command_;
ngx_command_ctx gzip_http_version_command_;
bool enabled_;
bool initialized_;
public:
NgxGZipSetter();
+16 -19
View File
@@ -18,13 +18,13 @@
#include <signal.h>
#include "net/instaweb/util/public/abstract_mutex.h"
#include "net/instaweb/util/public/debug.h"
#include "net/instaweb/util/public/shared_circular_buffer.h"
#include "net/instaweb/util/public/string_util.h"
#include "net/instaweb/public/version.h"
#include "pagespeed/kernel/base/abstract_mutex.h"
#include "pagespeed/kernel/base/debug.h"
#include "pagespeed/kernel/base/posix_timer.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/time_util.h"
#include "pagespeed/kernel/sharedmem/shared_circular_buffer.h"
namespace {
@@ -88,32 +88,29 @@ ngx_uint_t NgxMessageHandler::GetNgxLogLevel(MessageType type) {
return NGX_LOG_ALERT;
}
void NgxMessageHandler::MessageVImpl(MessageType type, const char* msg,
va_list args) {
ngx_uint_t log_level = GetNgxLogLevel(type);
GoogleString formatted_message = Format(msg, args);
void NgxMessageHandler::MessageSImpl(MessageType type,
const GoogleString& message) {
if (log_ != NULL) {
ngx_uint_t log_level = GetNgxLogLevel(type);
ngx_log_error(log_level, log_, 0/*ngx_err_t*/, "[%s %s] %s",
kModuleName, kModPagespeedVersion, formatted_message.c_str());
kModuleName, kModPagespeedVersion, message.c_str());
} else {
GoogleMessageHandler::MessageVImpl(type, msg, args);
GoogleMessageHandler::MessageSImpl(type, message);
}
// Prepare a log message for the SharedCircularBuffer only.
AddMessageToBuffer(type, formatted_message);
AddMessageToBuffer(type, message);
}
void NgxMessageHandler::FileMessageVImpl(MessageType type, const char* file,
int line, const char* msg,
va_list args) {
ngx_uint_t log_level = GetNgxLogLevel(type);
GoogleString formatted_message = Format(msg, args);
void NgxMessageHandler::FileMessageSImpl(
MessageType type, const char* file, int line, const GoogleString& message) {
if (log_ != NULL) {
ngx_uint_t log_level = GetNgxLogLevel(type);
ngx_log_error(log_level, log_, 0/*ngx_err_t*/, "[%s %s] %s:%d:%s",
kModuleName, kModPagespeedVersion, file, line,
formatted_message.c_str());
message.c_str());
} else {
GoogleMessageHandler::FileMessageVImpl(type, file, line, msg, args);
GoogleMessageHandler::FileMessageSImpl(type, file, line, message);
}
AddMessageToBuffer(type, file, line, message);
}
} // namespace net_instaweb
+8 -8
View File
@@ -28,11 +28,11 @@ extern "C" {
#include <cstdarg>
#include "net/instaweb/system/public/system_message_handler.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/system/system_message_handler.h"
namespace net_instaweb {
@@ -53,10 +53,10 @@ class NgxMessageHandler : public SystemMessageHandler {
ngx_log_t* log() { return log_; }
protected:
virtual void MessageVImpl(MessageType type, const char* msg, va_list args);
virtual void MessageSImpl(MessageType type, const GoogleString& message);
virtual void FileMessageVImpl(MessageType type, const char* filename,
int line, const char* msg, va_list args);
virtual void FileMessageSImpl(MessageType type, const char* file,
int line, const GoogleString& message);
private:
ngx_uint_t GetNgxLogLevel(MessageType type);
+549 -481
View File
File diff suppressed because it is too large Load Diff
+17 -7
View File
@@ -34,8 +34,8 @@ extern "C" {
}
#include "base/logging.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/util/public/string_util.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/response_headers.h"
namespace net_instaweb {
@@ -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);
@@ -84,15 +84,11 @@ enum PreserveCachingHeaders {
typedef struct {
NgxBaseFetch* base_fetch;
ngx_connection_t* pagespeed_connection;
ngx_http_request_t* r;
bool html_rewrite;
bool in_place;
bool write_pending;
bool fetch_done;
PreserveCachingHeaders preserve_caching_headers;
// for html rewrite
@@ -107,8 +103,16 @@ 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);
void copy_request_headers_from_ngx(const ngx_http_request_t* r,
RequestHeaders* headers);
@@ -123,6 +127,12 @@ ngx_int_t copy_response_headers_to_ngx(
StringPiece ps_determine_host(ngx_http_request_t* r);
namespace ps_base_fetch {
ngx_int_t ps_base_fetch_handler(ngx_http_request_t* r);
} // namespace ps_base_fetch
} // namespace net_instaweb
#endif // NGX_PAGESPEED_H_
+68 -29
View File
@@ -26,30 +26,30 @@
#include "ngx_server_context.h"
#include "ngx_url_async_fetcher.h"
#include "net/instaweb/http/public/content_type.h"
#include "net/instaweb/http/public/rate_controller.h"
#include "net/instaweb/http/public/rate_controlling_url_async_fetcher.h"
#include "net/instaweb/http/public/wget_url_fetcher.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/system/public/in_place_resource_recorder.h"
#include "net/instaweb/system/public/serf_url_async_fetcher.h"
#include "net/instaweb/system/public/system_caches.h"
#include "net/instaweb/system/public/system_rewrite_options.h"
#include "net/instaweb/util/public/google_message_handler.h"
#include "net/instaweb/util/public/null_shared_mem.h"
#include "net/instaweb/util/public/posix_timer.h"
#include "net/instaweb/util/public/property_cache.h"
#include "net/instaweb/util/public/scheduler_thread.h"
#include "net/instaweb/util/public/shared_circular_buffer.h"
#include "net/instaweb/util/public/shared_mem_statistics.h"
#include "net/instaweb/util/public/slow_worker.h"
#include "net/instaweb/util/public/stdio_file_system.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"
#include "net/instaweb/util/public/thread_system.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/null_shared_mem.h"
#include "pagespeed/kernel/base/posix_timer.h"
#include "pagespeed/kernel/base/stdio_file_system.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/sharedmem/shared_circular_buffer.h"
#include "pagespeed/kernel/sharedmem/shared_mem_statistics.h"
#include "pagespeed/kernel/thread/pthread_shared_mem.h"
#include "pagespeed/kernel/thread/scheduler_thread.h"
#include "pagespeed/kernel/thread/slow_worker.h"
#include "pagespeed/system/in_place_resource_recorder.h"
#include "pagespeed/system/serf_url_async_fetcher.h"
#include "pagespeed/system/system_caches.h"
#include "pagespeed/system/system_rewrite_options.h"
namespace net_instaweb {
@@ -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,10 +82,15 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
ngx_shared_circular_buffer_(NULL),
hostname_(hostname.as_string()),
port_(port),
process_script_variables_(false),
process_script_variables_set_(false) {
process_script_variables_mode_(ProcessScriptVariablesMode::kOff),
process_script_variables_set_(false),
shut_down_(false) {
InitializeDefaultOptions();
default_options()->set_beacon_url("/ngx_pagespeed_beacon");
// Put in the version of the ngx-pagespeed release. We don't release mod_pagespeed
// so we cannot rely on PSOL to hand us to right version. Note that if we perform
// another release, this must be either updated or removed.
default_options()->set_x_header_value("1.12.34.3-0");
SystemRewriteOptions* system_options = dynamic_cast<SystemRewriteOptions*>(
default_options());
system_options->set_file_cache_clean_inode_limit(500000);
@@ -147,18 +151,17 @@ 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;
}
bool NgxRewriteDriverFactory::InitNgxUrlAsyncFetchers() {
log_ = ngx_cycle->log;
for (size_t i = 0; i < ngx_url_async_fetchers_.size(); ++i) {
if (!ngx_url_async_fetchers_[i]->Init()) {
return false;
}
}
return true;
RewriteOptions* NgxRewriteDriverFactory::NewRewriteOptionsForQuery() {
return new NgxRewriteOptions(thread_system());
}
bool NgxRewriteDriverFactory::CheckResolver() {
@@ -186,6 +189,13 @@ ServerContext* NgxRewriteDriverFactory::NewServerContext() {
return NULL;
}
void NgxRewriteDriverFactory::ShutDown() {
if (!shut_down_) {
shut_down_ = true;
SystemRewriteDriverFactory::ShutDown();
}
}
void NgxRewriteDriverFactory::ShutDownMessageHandlers() {
ngx_message_handler_->set_buffer(NULL);
ngx_html_parse_message_handler_->set_buffer(NULL);
@@ -210,9 +220,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);
@@ -250,4 +270,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
+24 -20
View File
@@ -32,13 +32,9 @@ extern "C" {
#include <set>
#include "net/instaweb/system/public/system_rewrite_driver_factory.h"
#include "net/instaweb/util/public/md5_hasher.h"
#include "net/instaweb/util/public/scoped_ptr.h"
// TODO(oschaaf): We should reparent ApacheRewriteDriverFactory and
// NgxRewriteDriverFactory to a new class OriginRewriteDriverFactory and factor
// out as much as possible.
#include "pagespeed/kernel/base/md5_hasher.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/system/system_rewrite_driver_factory.h"
namespace net_instaweb {
@@ -52,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.
@@ -67,10 +69,10 @@ 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();
bool InitNgxUrlAsyncFetchers();
// Check resolver configured or not.
bool CheckResolver();
@@ -80,6 +82,7 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
static void InitStats(Statistics* statistics);
NgxServerContext* MakeNgxServerContext(StringPiece hostname, int port);
virtual ServerContext* NewServerContext();
virtual void ShutDown();
// Starts pagespeed threads if they've not been started already. Must be
// called after the caller has finished any forking it intends to do.
@@ -94,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;
@@ -115,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_;
@@ -161,8 +164,9 @@ 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_;
DISALLOW_COPY_AND_ASSIGN(NgxRewriteDriverFactory);
};
+62 -36
View File
@@ -30,9 +30,9 @@ extern "C" {
#include "net/instaweb/public/version.h"
#include "net/instaweb/rewriter/public/file_load_policy.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/system/public/system_caches.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/timer.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/system/system_caches.h"
namespace net_instaweb {
@@ -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,14 +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;
// Only allow script variable support for LoadFromFile for now.
// 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")) {
compile_scripts = false;
}
if (n_args == 1 && StringCaseEqual(directive, "ClearInheritedScripts")) {
clear_inherited_scripts_ = true;
@@ -357,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");
@@ -385,7 +415,7 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
result = driver_factory->ParseAndSetOption1(
directive,
arg,
scope >= RewriteOptions::kProcessScope,
scope >= RewriteOptions::kLegacyProcessScope,
&msg,
handler);
}
@@ -398,7 +428,7 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
directive,
args[1],
args[2],
scope >= RewriteOptions::kProcessScope,
scope >= RewriteOptions::kLegacyProcessScope,
&msg,
handler);
}
@@ -470,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;
@@ -510,10 +540,6 @@ NgxRewriteOptions* NgxRewriteOptions::Clone() const {
return options;
}
void NgxRewriteOptions::Merge(const RewriteOptions& src) {
SystemRewriteOptions::Merge(src);
}
const NgxRewriteOptions* NgxRewriteOptions::DynamicCast(
const RewriteOptions* instance) {
return dynamic_cast<const NgxRewriteOptions*>(instance);
+7 -6
View File
@@ -29,11 +29,13 @@ extern "C" {
#include <vector>
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/ref_counted_ptr.h"
#include "net/instaweb/util/public/stl_util.h" // for STLDeleteElements
#include "ngx_rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/system/public/system_rewrite_options.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/ref_counted_ptr.h"
#include "pagespeed/kernel/base/stl_util.h" // for STLDeleteElements
#include "pagespeed/system/system_rewrite_options.h"
#define NGX_PAGESPEED_MAX_ARGS 10
@@ -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);
@@ -140,7 +142,6 @@ class NgxRewriteOptions : public SystemRewriteOptions {
// Make an identical copy of these options and return it.
virtual NgxRewriteOptions* Clone() const;
virtual void Merge(const RewriteOptions& src);
// Returns a suitably down cast version of 'instance' if it is an instance
// of this class, NULL if not.
+22 -9
View File
@@ -27,15 +27,16 @@ extern "C" {
#include "ngx_rewrite_driver_factory.h"
#include "ngx_rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/system/public/add_headers_fetcher.h"
#include "net/instaweb/system/public/loopback_route_fetcher.h"
#include "net/instaweb/system/public/system_request_context.h"
#include "pagespeed/system/add_headers_fetcher.h"
#include "pagespeed/system/loopback_route_fetcher.h"
#include "pagespeed/system/system_request_context.h"
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,
+14 -3
View File
@@ -22,7 +22,7 @@
#define NGX_SERVER_CONTEXT_H_
#include "ngx_message_handler.h"
#include "net/instaweb/system/public/system_server_context.h"
#include "pagespeed/system/system_server_context.h"
extern "C" {
#include <ngx_http.h>
@@ -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);
};
+78 -135
View File
@@ -31,22 +31,22 @@ extern "C" {
#include <map>
#include <set>
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/inflating_fetch.h"
#include "net/instaweb/http/public/request_headers.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/http/public/response_headers_parser.h"
#include "net/instaweb/public/version.h"
#include "net/instaweb/util/public/condvar.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/pool.h"
#include "net/instaweb/util/public/pool_element.h"
#include "net/instaweb/util/public/statistics.h"
#include "net/instaweb/util/public/string_util.h"
#include "net/instaweb/util/public/thread_system.h"
#include "net/instaweb/util/public/timer.h"
#include "net/instaweb/util/public/writer.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/condvar.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/pool.h"
#include "pagespeed/kernel/base/pool_element.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/base/writer.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/response_headers_parser.h"
namespace net_instaweb {
@@ -65,7 +65,8 @@ namespace net_instaweb {
thread_system_(thread_system),
message_handler_(handler),
mutex_(NULL),
max_keepalive_requests_(max_keepalive_requests) {
max_keepalive_requests_(max_keepalive_requests),
event_connection_(NULL) {
resolver_timeout_ = resolver_timeout;
fetch_timeout_ = fetch_timeout;
ngx_memzero(&proxy_, sizeof(proxy_));
@@ -76,12 +77,17 @@ namespace net_instaweb {
mutex_ = thread_system_->NewMutex();
log_ = log;
pool_ = NULL;
command_connection_ = NULL;
pipe_fd_ = -1;
resolver_ = resolver;
// If init fails, set shutdown_ so no fetches will be attempted.
if (!Init(const_cast<ngx_cycle_t*>(ngx_cycle))) {
shutdown_ = true;
message_handler_->Message(
kError, "NgxUrlAsyncFetcher failed to init, fetching disabled.");
}
}
NgxUrlAsyncFetcher::~NgxUrlAsyncFetcher() {
DCHECK(shutdown_) << "Shut down before destructing NgxUrlAsyncFetcher.";
message_handler_->Message(
kInfo,
"Destruct NgxUrlAsyncFetcher with [%d] active fetchers",
@@ -89,19 +95,12 @@ namespace net_instaweb {
CancelActiveFetches();
active_fetches_.DeleteAll();
NgxConnection::Terminate();
if (pool_ != NULL) {
ngx_destroy_pool(pool_);
pool_ = NULL;
}
if (command_connection_ != NULL) {
ngx_close_connection(command_connection_);
command_connection_ = NULL;
}
if (pipe_fd_ != -1) {
close(pipe_fd_);
pipe_fd_ = -1;
}
if (mutex_ != NULL) {
delete mutex_;
mutex_ = NULL;
@@ -152,9 +151,13 @@ namespace net_instaweb {
// Create the pool for fetcher, create the pipe, add the read event for main
// thread. It should be called in the worker process.
bool NgxUrlAsyncFetcher::Init() {
log_ = ngx_cycle->log;
bool NgxUrlAsyncFetcher::Init(ngx_cycle_t* cycle) {
log_ = cycle->log;
CHECK(event_connection_ == NULL) << "event connection already set";
event_connection_ = new NgxEventConnection(ReadCallback);
if (!event_connection_->Init(cycle)) {
return false;
}
if (pool_ == NULL) {
pool_ = ngx_create_pool(4096, log_);
if (pool_ == NULL) {
@@ -164,41 +167,6 @@ namespace net_instaweb {
}
}
int pipe_fds[2];
int rc = pipe(pipe_fds);
if (rc != 0) {
ngx_log_error(NGX_LOG_ERR, log_, 0, "pipe() failed");
return false;
}
if (ngx_nonblocking(pipe_fds[0]) == -1) {
ngx_log_error(NGX_LOG_ERR, log_, 0, "nonblocking pipe[0] failed");
return false;
}
if (ngx_nonblocking(pipe_fds[1]) == -1) {
ngx_log_error(NGX_LOG_ERR, log_, 0, "nonblocking pipe[1] failed");
return false;
}
pipe_fd_ = pipe_fds[1];
command_connection_ = ngx_get_connection(pipe_fds[0], log_);
if (command_connection_ == NULL) {
close(pipe_fds[1]);
close(pipe_fds[0]);
pipe_fd_ = -1;
return false;
}
command_connection_->recv = ngx_recv;
command_connection_->send = ngx_send;
command_connection_->recv_chain = ngx_recv_chain;
command_connection_->send_chain = ngx_send_chain;
command_connection_->log = log_;
command_connection_->read->log = log_;
command_connection_->write->log = log_;
command_connection_->data = this;
command_connection_->read->handler = CommandHandler;
ngx_add_event(command_connection_->read, NGX_READ_EVENT, 0);
if (proxy_.url.len == 0) {
return true;
}
@@ -214,8 +182,29 @@ namespace net_instaweb {
}
void NgxUrlAsyncFetcher::ShutDown() {
shutdown_ = true;
SendCmd('S');
shutdown_ = true;
if (!pending_fetches_.empty()) {
for (Pool<NgxFetch>::iterator p = pending_fetches_.begin(),
e = pending_fetches_.end(); p != e; p++) {
NgxFetch* fetch = *p;
fetch->CallbackDone(false);
}
pending_fetches_.DeleteAll();
}
if (!active_fetches_.empty()) {
for (Pool<NgxFetch>::iterator p = active_fetches_.begin(),
e = active_fetches_.end(); p != e; p++) {
NgxFetch* fetch = *p;
fetch->CallbackDone(false);
}
active_fetches_.Clear();
}
if (event_connection_ != NULL) {
event_connection_->Shutdown();
delete event_connection_;
event_connection_ = NULL;
}
}
// It's called in the rewrite thread. All the fetches are started at
@@ -223,92 +212,46 @@ namespace net_instaweb {
void NgxUrlAsyncFetcher::Fetch(const GoogleString& url,
MessageHandler* message_handler,
AsyncFetch* async_fetch) {
// Don't accept new fetches when shut down. This flow is also entered when
// we did not initialize properly in ::Init().
if (shutdown_) {
async_fetch->Done(false);
return;
}
async_fetch = EnableInflation(async_fetch);
NgxFetch* fetch = new NgxFetch(url, async_fetch,
message_handler, log_);
ScopedMutex lock(mutex_);
pending_fetches_.Add(fetch);
SendCmd('F');
}
// send command to nginx main thread
// 'F' : start a fetch
// 'S' : shutdown the fetcher
bool NgxUrlAsyncFetcher::SendCmd(const char command) {
int rc;
while (true) {
rc = write(pipe_fd_, &command, 1);
if (rc == 1) {
return true;
} else if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
// TODO(junmin): It's rare. But it need be fixed.
} else {
return false;
}
}
return true;
// TODO(oschaaf): thread safety on written vs shutdown.
// It is possible that shutdown() is called after writing an event? In that
// case, this could (rarely) fail when it shouldn't.
bool written = event_connection_->WriteEvent(this);
CHECK(written || shutdown_) << "NgxUrlAsyncFetcher: event write failure";
}
// This is the read event which is called in the main thread.
// It will do the real work. Add the work event and start the fetch.
void NgxUrlAsyncFetcher::CommandHandler(ngx_event_t* cmdev) {
char command;
int rc;
ngx_connection_t* c = static_cast<ngx_connection_t*>(cmdev->data);
NgxUrlAsyncFetcher* fetcher = static_cast<NgxUrlAsyncFetcher*>(c->data);
do {
rc = read(c->fd, &command, 1);
} while (rc == -1 && errno == EINTR);
void NgxUrlAsyncFetcher::ReadCallback(const ps_event_data& data) {
std::vector<NgxFetch*> to_start;
NgxUrlAsyncFetcher* fetcher = reinterpret_cast<NgxUrlAsyncFetcher*>(
data.sender);
CHECK(rc == -1 || rc == 0 || rc == 1);
fetcher->mutex_->Lock();
fetcher->completed_fetches_.DeleteAll();
if (rc == -1 || rc == 0) {
// EAGAIN
return;
for (Pool<NgxFetch>::iterator p = fetcher->pending_fetches_.begin(),
e = fetcher->pending_fetches_.end(); p != e; p++) {
NgxFetch* fetch = *p;
to_start.push_back(fetch);
}
std::vector<NgxFetch*> to_start;
fetcher->pending_fetches_.Clear();
fetcher->mutex_->Unlock();
switch (command) {
// All the new fetches are appended in the pending_fetches.
// Start all these fetches.
case 'F':
fetcher->mutex_->Lock();
fetcher->completed_fetches_.DeleteAll();
for (Pool<NgxFetch>::iterator p = fetcher->pending_fetches_.begin(),
e = fetcher->pending_fetches_.end(); p != e; p++) {
NgxFetch* fetch = *p;
to_start.push_back(fetch);
}
fetcher->pending_fetches_.Clear();
fetcher->mutex_->Unlock();
for (size_t i = 0; i < to_start.size(); i++) {
fetcher->StartFetch(to_start[i]);
}
CHECK(ngx_handle_read_event(cmdev, 0) == NGX_OK);
break;
// Shutdown all the fetches.
case 'S':
if (!fetcher->pending_fetches_.empty()) {
fetcher->pending_fetches_.DeleteAll();
}
if (!fetcher->active_fetches_.empty()) {
for (Pool<NgxFetch>::iterator p = fetcher->active_fetches_.begin(),
e = fetcher->active_fetches_.end(); p != e; p++) {
NgxFetch* fetch = *p;
fetch->CallbackDone(false);
}
fetcher->active_fetches_.Clear();
}
CHECK(ngx_del_event(cmdev, NGX_READ_EVENT, 0) == NGX_OK);
break;
default:
break;
for (size_t i = 0; i < to_start.size(); i++) {
fetcher->StartFetch(to_start[i]);
}
return;
+14 -12
View File
@@ -33,11 +33,14 @@ extern "C" {
}
#include <vector>
#include "ngx_event_connection.h"
#include "net/instaweb/http/public/url_async_fetcher.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/pool.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/thread_system.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/pool.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
namespace net_instaweb {
@@ -59,22 +62,21 @@ class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
~NgxUrlAsyncFetcher();
// It should be called in the module init_process callback function. Do some
// initializations which can't be done in the master process
bool Init();
// intializations which can't be done in the master process
bool Init(ngx_cycle_t* cycle);
// shutdown all the fetches.
virtual void ShutDown();
// the read handler in the main thread
static void ReadCallback(const ps_event_data& data);
virtual bool SupportsHttps() const { return false; }
virtual void Fetch(const GoogleString& url,
MessageHandler* message_handler,
AsyncFetch* callback);
// send the command from the current thread to main thread
bool SendCmd(const char command);
// the read handler in the main thread
static void CommandHandler(ngx_event_t* cmdev);
bool StartFetch(NgxFetch* fetch);
// Remove the completed fetch from the active fetch set, and put it into a
@@ -137,13 +139,13 @@ class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
ngx_pool_t* pool_;
ngx_log_t* log_;
ngx_connection_t* command_connection_; // the command pipe
int pipe_fd_; // the write pipe end
ngx_resolver_t* resolver_;
int max_keepalive_requests_;
ngx_msec_t resolver_timeout_;
ngx_msec_t fetch_timeout_;
NgxEventConnection* event_connection_;
DISALLOW_COPY_AND_ASSIGN(NgxUrlAsyncFetcher);
};
+398 -1712
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+18 -10
View File
@@ -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,16 +45,19 @@ 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"
MOD_PAGESPEED_DIR="$1"
NGINX_EXECUTABLE="$2"
: ${PRIMARY_PORT:=8050}
: ${SECONDARY_PORT:=8051}
: ${CONTROLLER_PORT:=8053}
: ${RCPORT:=9991}
: ${PAGESPEED_TEST_HOST:=selfsigned.modpagespeed.com}
this_dir="$( cd $(dirname "$0") && pwd)"
@@ -62,7 +67,10 @@ function run_test_checking_failure() {
SECONDARY_PORT="$SECONDARY_PORT" \
MOD_PAGESPEED_DIR="$MOD_PAGESPEED_DIR" \
NGINX_EXECUTABLE="$NGINX_EXECUTABLE" \
PAGESPEED_TEST_HOST="$PAGESPEED_TEST_HOST" \
RUN_TESTS="$RUN_TESTS" \
CONTROLLER_PORT="$CONTROLLER_PORT" \
RCPORT="$RCPORT" \
bash "$this_dir/nginx_system_test.sh"
STATUS=$?
echo "With $@ setup."
+28
View File
@@ -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
...
}