Compare commits

...

142 Commits

Author SHA1 Message Date
Jeff Kaufman cd8c45fc86 1.10.33.1 -> 1.10.33.2 2015-12-18 15:04:42 -05:00
Jeff Kaufman 9d6bfad665 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:04:42 -05:00
Otto van der Schaaf c253c3ba80 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-17 17:18:18 -05:00
Jeff Kaufman 8c7c8a843a 1.10.33.0 -> 1.10.33.1 2015-12-16 08:13:40 -05:00
Jeff Kaufman bcb1eb1dec release: version 1.9 -> 1.10 2015-12-14 08:27:41 -05: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
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
27 changed files with 2749 additions and 2972 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
test/tmp
psol/
psol-*.tar.gz
*.*.*.*.tar.gz
+117 -33
View File
@@ -17,6 +17,8 @@
# 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
@@ -27,8 +29,8 @@ if [ "$mod_pagespeed_dir" = "unset" ] ; then
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.8.31.2.tar.gz"
echo " $ tar -xzvf 1.8.31.2.tar.gz # expands to psol/"
echo " $ wget https://dl.google.com/dl/page-speed/psol/1.10.33.2.tar.gz"
echo " $ tar -xzvf 1.10.33.2.tar.gz # expands to psol/"
echo ""
echo " Or see the installation instructions:"
echo " https://github.com/pagespeed/ngx_pagespeed#how-to-build"
@@ -39,31 +41,6 @@ else
build_from_source=true
fi
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"
else
psol_library_dir="$ngx_addon_dir/psol/lib/$buildtype/$os_name/$arch_name"
psol_binary="$psol_library_dir/pagespeed_automatic.a"
fi
fi
echo "mod_pagespeed_dir=$mod_pagespeed_dir"
echo "build_from_source=$build_from_source"
ngx_feature="psol"
ngx_feature_name=""
ngx_feature_run=no
ngx_feature_incs="
#include \"net/instaweb/htmlparse/public/html_parse.h\"
#include \"net/instaweb/htmlparse/public/html_writer_filter.h\"
#include \"net/instaweb/util/public/string.h\"
#include \"net/instaweb/util/public/string_writer.h\"
#include \"net/instaweb/util/public/null_message_handler.h\"
"
os_name='unknown_os'
arch_name='unknown_arch'
uname_os=`uname`
@@ -94,6 +71,20 @@ 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
NGX_TEST_LD_OPT="$NGX_TEST_LD_OPT -lstdc++"
else
pagespeed_libs="-lstdc++"
fi
# 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
@@ -102,6 +93,13 @@ 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_TEST_FLAGS="$CC_TEST_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0"
case "$NGX_GCC_VER" in
4.8*)
# On GCC 4.8 and above, -Wall enables -Wunused-local-typedefs. This breaks
@@ -124,6 +122,31 @@ if [ "$WNO_ERROR" = "YES" ]; then
CFLAGS="$CFLAGS -Wno-error"
fi
psol_binary="${PSOL_BINARY:-unset}"
if [ "$psol_binary" = "unset" ] ; then
if $build_from_source ; then
psol_binary="\
$mod_pagespeed_dir/pagespeed/automatic/pagespeed_automatic.a"
else
psol_library_dir="$ngx_addon_dir/psol/lib/$buildtype/$os_name/$arch_name"
psol_binary="$psol_library_dir/pagespeed_automatic.a"
fi
fi
echo "mod_pagespeed_dir=$mod_pagespeed_dir"
echo "build_from_source=$build_from_source"
ngx_feature="psol"
ngx_feature_name=""
ngx_feature_run=no
ngx_feature_incs="
#include \"pagespeed/kernel/base/string.h\"
#include \"pagespeed/kernel/base/string_writer.h\"
#include \"pagespeed/kernel/base/null_message_handler.h\"
#include \"pagespeed/kernel/html/html_parse.h\"
#include \"pagespeed/kernel/html/html_writer_filter.h\"
"
pagespeed_include="\
$mod_pagespeed_dir \
$mod_pagespeed_dir/third_party/chromium/src \
@@ -139,9 +162,10 @@ pagespeed_include="\
$mod_pagespeed_dir/third_party/aprutil/gen/arch/$os_name/$arch_name/include"
ngx_feature_path="$pagespeed_include"
pagespeed_libs="-lstdc++ $psol_binary -lrt -pthread -lm"
pagespeed_libs="$pagespeed_libs $psol_binary -lrt -pthread -lm"
ngx_feature_libs="$pagespeed_libs"
ngx_feature_test="
GoogleString output_buffer;
net_instaweb::StringWriter write_to_string(&output_buffer);
@@ -169,6 +193,7 @@ if [ $ngx_found = yes ]; then
$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 \
@@ -183,6 +208,7 @@ if [ $ngx_found = yes ]; then
$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 \
@@ -192,13 +218,29 @@ if [ $ngx_found = yes ]; then
$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"
# Make pagespeed run immediately before gzip.
if [ "$position_aux" = "true" ] ; then
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $ngx_addon_name"
else
# Make pagespeed run immediately before gzip and Brotli.
if echo $HTTP_FILTER_MODULES | grep ngx_http_brotli_filter_module >/dev/null; then
module=ngx_http_brotli_filter_module
elif [ $HTTP_GZIP = YES ]; then
module=$HTTP_GZIP_FILTER_MODULE
else
module=$HTTP_RANGE_HEADER_FILTER_MODULE
fi
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES |\
sed "s/$module/$module $ngx_addon_name/")
fi
# Make the etag header filter run immediately before range header filter.
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/")
sed "s/$HTTP_RANGE_HEADER_FILTER_MODULE/$HTTP_RANGE_HEADER_FILTER_MODULE ngx_pagespeed_etag_filter/")
CORE_LIBS="$CORE_LIBS $pagespeed_libs"
CORE_INCS="$CORE_INCS $pagespeed_include"
echo "List of modules (in reverse order of applicability): "$HTTP_FILTER_MODULES
@@ -210,4 +252,46 @@ END
exit 1
fi
# 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 objs/autoconf.err for more details.
END
exit 1
fi
have=NGX_PAGESPEED . auto/have
+7
View File
@@ -0,0 +1,7 @@
if [ -n "$NGX_CLANG_VER" ]; then
# Chromium headers assume clang is always in C++11 mode. Oblige it.
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
fi
+2 -2
View File
@@ -13,9 +13,9 @@
# Author: vid@zippykid.com (Vid Luther)
# jefftk@google.com (Jeff Kaufman)
URL="https://modpagespeed.googlecode.com/svn/trunk/src/"
URL="https://github.com/pagespeed/mod_pagespeed/raw/master/"
URL+="net/instaweb/genfiles/conf/pagespeed_libraries.conf"
curl -s "$URL" \
curl -L -s -S "$URL" \
| grep ModPagespeedLibrary \
| while read library size hash url ; do
echo " pagespeed Library $size $hash $url;"
+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);
}
}
+162 -33
View File
@@ -15,37 +15,156 @@
*/
// Author: jefftk@google.com (Jeff Kaufman)
#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_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(ngx_http_request_t* r,
NgxServerContext* server_context,
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers)
PreserveCachingHeaders preserve_caching_headers,
NgxBaseFetchType base_fetch_type)
: AsyncFetch(request_ctx),
request_(r),
server_context_(server_context),
done_called_(false),
last_buf_sent_(false),
pipe_fd_(pipe_fd),
references_(2),
handle_error_(true),
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";
}
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);
CHECK(data.sender == ctx->base_fetch);
CHECK(r->count > 0) << "r->count: " << r->count;
int rc;
// If we are unlucky enough to have our connection finalized mid-ipro-lookup,
// we must enter a different flow. Also see ps_in_place_check_header_filter().
if ((ctx->base_fetch->base_fetch_type_ != kIproLookup)
&& r->connection->error) {
ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
"pagespeed [%p] request already finalized", r);
rc = NGX_ERROR;
} 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);
// See http://forum.nginx.org/read.php?2,253006,253061
ngx_http_run_posted_requests(c);
}
void NgxBaseFetch::Lock() {
@@ -115,21 +234,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,42 +254,54 @@ void NgxBaseFetch::HandleHeadersComplete() {
int status_code = response_headers()->status_code();
bool status_ok = (status_code != 0) && (status_code < 400);
if (status_ok || handle_error_) {
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);
}
}
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.
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();
}
+76 -23
View File
@@ -17,22 +17,32 @@
// 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.
#ifndef NGX_BASE_FETCH_H_
#define NGX_BASE_FETCH_H_
@@ -45,22 +55,43 @@ 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 "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,
NgxServerContext* server_context,
NgxBaseFetch(ngx_http_request_t* r, NgxServerContext* server_context,
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers);
PreserveCachingHeaders preserve_caching_headers,
NgxBaseFetchType base_fetch_type);
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 +108,22 @@ 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_handle_error(bool x) { handle_error_ = 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_; }
private:
virtual bool HandleWrite(const StringPiece& sp, MessageHandler* handler);
@@ -89,7 +133,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 +149,29 @@ 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;
ngx_http_request_t* request_;
GoogleString buffer_;
NgxServerContext* server_context_;
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 handle_error_;
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_
+783 -478
View File
File diff suppressed because it is too large Load Diff
+62 -15
View File
@@ -39,24 +39,72 @@ 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 {
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,
AsyncFetch* async_fetch,
MessageHandler* message_handler,
ngx_msec_t timeout_ms,
ngx_log_t* log);
~NgxFetch();
@@ -112,19 +160,19 @@ class NgxFetch : public PoolElement<NgxFetch> {
response_handler = handler;
}
// Only the Static functions could be used in callbacks.
static void NgxFetchResolveDone(ngx_resolver_ctx_t* ctx);
static void ResolveDoneHandler(ngx_resolver_ctx_t* ctx);
// Write the request.
static void NgxFetchWrite(ngx_event_t* wev);
static void ConnectionWriteHandler(ngx_event_t* wev);
// Wait for the response.
static void NgxFetchRead(ngx_event_t* rev);
static void ConnectionReadHandler(ngx_event_t* rev);
// Read and parse the first status line.
static bool NgxFetchHandleStatusLine(ngx_connection_t* c);
static bool HandleStatusLine(ngx_connection_t* c);
// Read and parse the HTTP headers.
static bool NgxFetchHandleHeader(ngx_connection_t* c);
static bool HandleHeader(ngx_connection_t* c);
// Read the response body.
static bool NgxFetchHandleBody(ngx_connection_t* c);
static bool HandleBody(ngx_connection_t* c);
// Cancel the fetch when it's timeout.
static void NgxFetchTimeout(ngx_event_t* tev);
static void TimeoutHandler(ngx_event_t* tev);
// Add the pagespeed User-Agent.
void FixUserAgent();
@@ -139,7 +187,6 @@ class NgxFetch : public PoolElement<NgxFetch> {
int64 bytes_received_;
int64 fetch_start_ms_;
int64 fetch_end_ms_;
int64 timeout_ms_;
bool done_;
int64 content_length_;
bool content_length_known_;
@@ -152,7 +199,7 @@ class NgxFetch : public PoolElement<NgxFetch> {
ngx_http_request_t* r_;
ngx_http_status_t* status_;
ngx_event_t* timeout_event_;
ngx_connection_t* connection_;
NgxConnection* connection_;
ngx_resolver_ctx_t* resolver_ctx_;
DISALLOW_COPY_AND_ASSIGN(NgxFetch);
+1 -1
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 {
+15 -18
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,31 +88,28 @@ 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);
}
}
+12 -8
View File
@@ -18,17 +18,21 @@
#define NGX_MESSAGE_HANDLER_H_
extern "C" {
#include <ngx_auto_config.h>
#if (NGX_THREADS)
#include <ngx_thread.h>
#endif
#include <ngx_core.h>
#include <ngx_log.h>
}
#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 {
@@ -49,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);
+382 -399
View File
File diff suppressed because it is too large Load Diff
+14 -6
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 {
@@ -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,14 @@ 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;
} 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 +125,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_
+32 -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 {
@@ -78,11 +78,14 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
log_(NULL),
resolver_timeout_(NGX_CONF_UNSET_MSEC),
use_native_fetcher_(false),
// 100 Aligns to nginx's server-side default.
native_fetcher_max_keepalive_requests_(100),
ngx_shared_circular_buffer_(NULL),
hostname_(hostname.as_string()),
port_(port),
process_script_variables_(false),
process_script_variables_set_(false) {
process_script_variables_set_(false),
shut_down_(false) {
InitializeDefaultOptions();
default_options()->set_beacon_url("/ngx_pagespeed_beacon");
SystemRewriteOptions* system_options = dynamic_cast<SystemRewriteOptions*>(
@@ -112,6 +115,7 @@ UrlAsyncFetcher* NgxRewriteDriverFactory::AllocateFetcher(
resolver_timeout_,
config->blocking_fetch_timeout_ms(),
resolver_,
native_fetcher_max_keepalive_requests_,
thread_system(),
message_handler());
ngx_url_async_fetchers_.push_back(fetcher);
@@ -148,16 +152,6 @@ RewriteOptions* NgxRewriteDriverFactory::NewRewriteOptions() {
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;
}
bool NgxRewriteDriverFactory::CheckResolver() {
if (use_native_fetcher_ && resolver_ == NULL) {
return false;
@@ -183,6 +177,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);
@@ -207,9 +208,11 @@ void NgxRewriteDriverFactory::StartThreads() {
threads_started_ = true;
}
void NgxRewriteDriverFactory::LoggingInit(ngx_log_t* log) {
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);
+18 -9
View File
@@ -20,6 +20,10 @@
#define NGX_REWRITE_DRIVER_FACTORY_H_
extern "C" {
#include <ngx_auto_config.h>
#if (NGX_THREADS)
#include <ngx_thread.h>
#endif
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>
@@ -28,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 {
@@ -66,7 +66,6 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
// NgxRewriteOptions.
virtual RewriteOptions* NewRewriteOptions();
virtual ServerContext* NewDecodingServerContext();
bool InitNgxUrlAsyncFetchers();
// Check resolver configured or not.
bool CheckResolver();
@@ -76,6 +75,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.
@@ -105,11 +105,17 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
void set_use_native_fetcher(bool x) {
use_native_fetcher_ = x;
}
int native_fetcher_max_keepalive_requests() {
return native_fetcher_max_keepalive_requests_;
}
void set_native_fetcher_max_keepalive_requests(int x) {
native_fetcher_max_keepalive_requests_ = x;
}
bool process_script_variables() {
return process_script_variables_;
}
void LoggingInit(ngx_log_t* log);
void LoggingInit(ngx_log_t* log, bool may_install_crash_handler);
virtual void ShutDownMessageHandlers();
@@ -140,6 +146,8 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
ngx_msec_t resolver_timeout_;
ngx_resolver_t* resolver_;
bool use_native_fetcher_;
int native_fetcher_max_keepalive_requests_;
typedef std::set<NgxMessageHandler*> NgxMessageHandlerSet;
NgxMessageHandlerSet server_context_message_handlers_;
@@ -151,6 +159,7 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
int port_;
bool process_script_variables_;
bool process_script_variables_set_;
bool shut_down_;
DISALLOW_COPY_AND_ASSIGN(NgxRewriteDriverFactory);
};
+25 -7
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 {
@@ -72,12 +72,14 @@ const char* const server_only_options[] = {
"LoadFromFileMatch",
"LoadFromFileRule",
"LoadFromFileRuleMatch",
"UseNativeFetcher"
"UseNativeFetcher",
"NativeFetcherMaxKeepaliveRequests"
};
// Options that can only be used in the main (http) option scope.
const char* const main_only_options[] = {
"UseNativeFetcher"
"UseNativeFetcher",
"NativeFetcherMaxKeepaliveRequests"
};
} // namespace
@@ -274,10 +276,16 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
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")) {
if (!StringCaseStartsWith(directive, "LoadFromFile") &&
!StringCaseEqual(directive, "EnableFilters") &&
!StringCaseEqual(directive, "DisableFilters") &&
!StringCaseEqual(directive, "DownstreamCachePurgeLocationPrefix") &&
!StringCaseEqual(directive, "DownstreamCachePurgeMethod") &&
!StringCaseEqual(directive,
"DownstreamCacheRewrittenPercentageThreshold") &&
!StringCaseEqual(directive, "ShardDomain")){
compile_scripts = false;
}
@@ -343,6 +351,16 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory,
&NgxRewriteDriverFactory::set_use_native_fetcher);
} else if (IsDirective(directive, "NativeFetcherMaxKeepaliveRequests")) {
int max_keepalive_requests;
if (StringToInt(arg, &max_keepalive_requests) &&
max_keepalive_requests > 0) {
driver_factory->set_native_fetcher_max_keepalive_requests(
max_keepalive_requests);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
} else if (StringCaseEqual("ProcessScriptVariables", args[0])) {
if (scope == RewriteOptions::kProcessScopeStrict) {
if (StringCaseEqual(arg, "on")) {
+4 -4
View File
@@ -29,11 +29,11 @@ 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 "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
+4 -4
View File
@@ -27,9 +27,9 @@ 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 {
@@ -48,7 +48,7 @@ SystemRequestContext* NgxServerContext::NewRequestContext(
ngx_http_request_t* r) {
// Based on ngx_http_variable_server_port.
bool port_set = false;
int local_port;
int local_port = 0;
#if (NGX_HAVE_INET6)
if (r->connection->local_sockaddr->sa_family == AF_INET6) {
local_port = ntohs(reinterpret_cast<struct sockaddr_in6*>(
+4 -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
+81 -136
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 {
@@ -55,6 +55,7 @@ namespace net_instaweb {
ngx_msec_t resolver_timeout,
ngx_msec_t fetch_timeout,
ngx_resolver_t* resolver,
int max_keepalive_requests,
ThreadSystem* thread_system,
MessageHandler* handler)
: fetchers_count_(0),
@@ -63,7 +64,9 @@ namespace net_instaweb {
byte_count_(0),
thread_system_(thread_system),
message_handler_(handler),
mutex_(NULL) {
mutex_(NULL),
max_keepalive_requests_(max_keepalive_requests),
event_connection_(NULL) {
resolver_timeout_ = resolver_timeout;
fetch_timeout_ = fetch_timeout;
ngx_memzero(&proxy_, sizeof(proxy_));
@@ -74,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",
@@ -87,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;
@@ -150,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) {
@@ -162,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;
}
@@ -212,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
@@ -221,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, fetch_timeout_, log_);
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;
+16 -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 {
@@ -53,27 +56,27 @@ class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
NgxUrlAsyncFetcher(
const char* proxy, ngx_log_t* log, ngx_msec_t resolver_timeout,
ngx_msec_t fetch_timeout, ngx_resolver_t* resolver,
ThreadSystem* thread_system, MessageHandler* handler);
int max_keepalive_requests, ThreadSystem* thread_system,
MessageHandler* handler);
~NgxUrlAsyncFetcher();
// It should be called in the module init_process callback function. Do some
// intializations which can't be done in the master process
bool Init();
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
@@ -136,12 +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);
};
+264 -1708
View File
File diff suppressed because it is too large Load Diff
+387 -35
View File
@@ -24,6 +24,9 @@ http {
'"$http_user_agent"';
access_log "@@ACCESS_LOG@@" cache;
# Don't put entries in the error log for 403s and 404s.
log_not_found off;
proxy_cache_path "@@PROXY_CACHE@@" levels=1:2 keys_zone=htmlcache:60m inactive=90m max_size=50m;
proxy_temp_path "@@TMP_PROXY_CACHE@@";
@@ -38,6 +41,10 @@ http {
pagespeed StaticAssetPrefix /pagespeed_custom_static/;
pagespeed MessageBufferSize 200000;
# Increase the default fetcher timeout to resolve sporadic flakeyness when
# the native fetcher uses 8.8.8.8 to resolve.
pagespeed FetcherTimeoutMs 10000;
pagespeed NativeFetcherMaxKeepaliveRequests 50;
root "@@SERVER_ROOT@@";
@@ -262,14 +269,14 @@ http {
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name mpd.example.com;
server_name secondary.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed MapProxyDomain mpd.example.com/gstatic_images
pagespeed MapProxyDomain secondary.example.com/gstatic_images
http://www.gstatic.com/psa/static;
}
# These two vhosts are for testing the experiment framework (Furious).
# These three vhosts are for testing the experiment framework (Furious).
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
@@ -279,12 +286,31 @@ http {
pagespeed RunExperiment on;
pagespeed AnalyticsID "123-45-6734";
pagespeed UseAnalyticsJs false;
pagespeed ExperimentVariable 2;
pagespeed ExperimentSpec
"id=7;enable=recompress_images;disable=convert_jpeg_to_progressive;percent=50";
pagespeed ExperimentSpec "id=2;enable=recompress_images;percent=50";
pagespeed ExperimentSpec "id=3;default;percent=0";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name contentexperiment.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed InPlaceResourceOptimization off;
pagespeed RunExperiment on;
pagespeed AnalyticsID "123-45-6734";
pagespeed UseAnalyticsJs false;
pagespeed ExperimentVariable 2;
pagespeed ExperimentSpec
"id=7;enable=recompress_images;disable=convert_jpeg_to_progressive;percent=50;options=ContentExperimentID=ID:H1BpS2TCRFmJzZgjwyeBHQ,ContentExperimentVariantID=111";
pagespeed ExperimentSpec
"id=2;enable=recompress_images;percent=50;options=ContentExperimentID=ID:H1BpS2TCRFmJzZgjwyeBHQ,ContentExperimentVariantID=222";
pagespeed ExperimentSpec
"id=3;default;percent=0;options=ContentExperimentID=123,ContentExperimentVariantID=333";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
@@ -298,6 +324,16 @@ http {
pagespeed ExperimentSpec "id=2;enable=recompress_images;percent=50";
pagespeed ExperimentSpec "id=3;default;percent=0";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name experiment.devicematch.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RunExperiment on;
pagespeed ExperimentSpec
"id=1;percent=100;matches_device_type=mobile;enable=recompress_images";
}
server {
listen @@SECONDARY_PORT@@;
@@ -368,6 +404,34 @@ http {
pagespeed DownstreamCachePurgeLocationPrefix "http://localhost:@@SECONDARY_PORT@@/purge";
}
# Set up a reverse proxy (rproxy.) and origin (origin.) as vhosts for
# showing that we can configure PageSpeed via response headers.
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name rproxy.rmcomments.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RewriteLevel PassThrough;
pagespeed DisableFilters add_instrumentation,remove_comments;
# Note that we don't enable remove_comments here; that setting comes from
# the response headers from origin.rmcomments.example.com
location / {
proxy_pass http://127.0.0.1:@@SECONDARY_PORT@@/;
proxy_set_header "Host" "origin.rmcomments.example.com";
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name origin.rmcomments.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed off;
location / {
add_header PageSpeedFilters remove_comments;
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
@@ -383,9 +447,6 @@ http {
# Build a configuration hierarchy where at the root we have turned on
# OptimizeForBandwidth, and in various subdirectories we override settings
# to make them more aggressive.
#
# In Apache we can do this all with Directory blocks, but to get the same
# inheretence in Nginx we need to have location blocks inside a server block.
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
@@ -544,15 +605,6 @@ http {
pagespeed EnableFilters rewrite_domains;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name retaincomment.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RetainComment " google_ad_section*";
}
server {
# Test host for shared memory cache.
listen @@SECONDARY_PORT@@;
@@ -569,8 +621,23 @@ http {
listen [::]:@@SECONDARY_PORT@@;
server_name xfp.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RespectXForwardedProto on;
location /redirecting_origin {
pagespeed off;
# Hack: we clear the response headers using headers_more.
# If we don't, nginx will add an extra empty Location: headers here.
# It is kind of hard to get nginx to generate a relative location header
# that starts with "/".
more_clear_headers 'Location';
add_header Location /mod_pagespeed_example;
return 301;
}
location /redirect {
proxy_method GET;
proxy_pass http://127.0.0.1:@@SECONDARY_PORT@@/redirecting_origin;
proxy_set_header "Host" "xfp.example.com";
}
}
server {
@@ -786,6 +853,13 @@ http {
pagespeed ConsolePath /custom_pagespeed_console;
pagespeed MessagesPath /custom_pagespeed_message;
pagespeed AdminPath /custom_pagespeed_admin;
pagespeed StatisticsDomains Allow *;
pagespeed GlobalStatisticsDomains Allow *;
pagespeed MessagesDomains Allow *;
pagespeed ConsoleDomains Allow *;
pagespeed AdminDomains Allow *;
pagespeed GlobalAdminDomains Allow *;
}
server {
@@ -793,18 +867,13 @@ http {
listen [::]:@@SECONDARY_PORT@@;
server_name inherit-paths.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name notransform.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters rewrite_images;
add_header Cache-Control no-transform;
pagespeed StatisticsDomains Allow *;
pagespeed GlobalStatisticsDomains Allow *;
pagespeed MessagesDomains Allow *;
pagespeed ConsoleDomains Allow *;
pagespeed AdminDomains Allow *;
pagespeed GlobalAdminDomains Allow *;
}
server {
@@ -865,7 +934,10 @@ http {
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RewriteLevel PassThrough;
pagespeed on;
add_header PageSpeedFilters add_instrumentation;
location / {
proxy_pass http://localhost:@@SECONDARY_PORT@@;
proxy_set_header Host "enable-filter-header-origin.example.com";
}
}
server {
@@ -875,7 +947,24 @@ http {
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters add_instrumentation;
pagespeed on;
add_header PageSpeed off;
location / {
proxy_pass http://localhost:@@SECONDARY_PORT@@;
proxy_set_header Host "pagespeed-off-header-origin.example.com";
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name headers.example.com;
pagespeed InPlaceRewriteDeadlineMs -1;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed LoadFromFile "http://headers.example.com/"
"@@SERVER_ROOT@@/";
location /mod_pagespeed_test/ {
more_set_headers "Server: override";
more_set_headers -s '404' 'Cache-Control: override';
}
}
server {
@@ -958,7 +1047,7 @@ http {
listen [::]:@@SECONDARY_PORT@@;
server_name date.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
add_header "Date" "Date: Fri, 16 Oct 2009 23:05:07 GMT";
add_header "Date" "Fri, 16 Oct 2009 23:05:07 GMT";
}
server {
@@ -1040,6 +1129,81 @@ http {
pagespeed DisableFilters remove_comments,add_instrumentation;
}
# Start remote config servers.
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT1@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config-partially-invalid.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT2@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config-invalid.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT3@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config-failed-fetch.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT5@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config-slow-fetch.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT6@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name remote-config-experiment.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RemoteConfigurationUrl "http://127.0.0.1:@@RCPORT7@@/remote.cfg";
pagespeed RemoteConfigurationTimeoutMs 1500;
}
# Test that pagespeed is disabled when sendfile headers are present.
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name uses-sendfile.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
add_header 'X-Sendfile' 'blablabla';
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name doesnt-sendfile.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name uses-xaccelredirect.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
add_header 'X-Accel-Redirect' 'blablabla';
}
# Proxy + IPRO a gzip'd file for testing Issue 896.
server {
listen @@SECONDARY_PORT@@;
@@ -1132,6 +1296,24 @@ http {
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name script-filters.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
root "@@SERVER_ROOT@@";
set $filters "";
set $domain_shards "cdn1.example.com,cdn2.example.com";
if ($http_X_Script) {
set $filters "add_instrumentation";
set $domain_shards "";
}
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters rewrite_domains;
pagespeed EnableFilters $filters;
pagespeed ShardDomain script-filters.example.com "$domain_shards";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
@@ -1141,13 +1323,147 @@ http {
pagespeed EnableCachePurge on;
pagespeed PurgeMethod PURGE;
root "@@SERVER_ROOT@@";
root "@@SERVER_ROOT@@/mod_pagespeed_test/purge";
pagespeed FileCachePath "@@FILE_CACHE@@_purge";
pagespeed DisableFilters add_instrumentation;
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters rewrite_css;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name psoff-dir-on.example.com;
# Test purging individual URLs without flushing the entire metadata cache.
pagespeed EnableCachePurge on;
pagespeed PurgeMethod PURGE;
root "@@SERVER_ROOT@@/mod_pagespeed_test/purge";
pagespeed FileCachePath "@@FILE_CACHE@@_dir_on";
pagespeed DisableFilters add_instrumentation;
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters rewrite_css;
pagespeed off;
location / {
pagespeed on;
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name cc-header-origin.example.com;
pagespeed InPlaceResourceOptimization off;
pagespeed off;
pagespeed FileCachePath "@@FILE_CACHE@@";
root "@@SERVER_ROOT@@";
location /mod_pagespeed_test/nostore {
add_header "Cache-Control" "max-age=12345";
add_header "Cache-Control" "public, no-store";
add_header "Cache-Control" "max-age=14";
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name enable-filter-header-origin.example.com;
pagespeed InPlaceResourceOptimization off;
pagespeed off;
pagespeed FileCachePath "@@FILE_CACHE@@";
root "@@SERVER_ROOT@@";
location / {
add_header "PageSpeedFilters" "add_instrumentation";
}
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name pagespeed-off-header-origin.example.com;
pagespeed InPlaceResourceOptimization off;
pagespeed off;
pagespeed FileCachePath "@@FILE_CACHE@@";
root "@@SERVER_ROOT@@";
location / {
add_header "PageSpeed" "off";
}
}
pagespeed MessagesDomains Allow messages-allowed.example.com;
pagespeed MessagesDomains Allow cleared-inherited.example.com;
pagespeed MessagesDomains Allow cleared-inherited-reallowed.example.com;
pagespeed MessagesDomains Allow more-messages-allowed.example.com;
pagespeed MessagesDomains Allow anything-*-wildcard.example.com;
pagespeed MessagesDomains Allow localhost;
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name messages-allowed.example.com
messages-not-allowed.example.com
more-messages-allowed.example.com
anything-a-wildcard.example.com
anything-b-wildcard.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name messages-still-not-allowed.example.com
but-this-message-allowed.example.com
and-this-one.example.com;
pagespeed MessagesDomains Allow but-this-message-allowed.example.com;
pagespeed MessagesDomains Allow and-this-one.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name cleared-inherited.example.com
cleared-inherited-reallowed.example.com
messages-allowed-at-vhost.example.com
messages-not-allowed-at-vhost.example.com
anything-c-wildcard.example.com;
pagespeed MessagesDomains Disallow *;
pagespeed MessagesDomains Allow cleared-inherited-reallowed.example.com;
pagespeed MessagesDomains Allow messages-allowed-at-vhost.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name cleared-inherited-unlisted.example.com;
pagespeed MessagesDomains Allow *;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
server_name nothing-allowed.example.com;
pagespeed MessagesDomains Disallow *;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
server_name nothing-explicitly-allowed.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name everything-explicitly-allowed.example.com
everything-explicitly-allowed-but-aliased.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed StatisticsDomains Allow everything-explicitly-allowed.example.com;
pagespeed GlobalStatisticsDomains
Allow everything-explicitly-allowed.example.com;
pagespeed MessagesDomains Allow everything-explicitly-allowed.example.com;
pagespeed ConsoleDomains Allow everything-explicitly-allowed.example.com;
pagespeed AdminDomains Allow everything-explicitly-allowed.example.com;
pagespeed GlobalAdminDomains
Allow everything-explicitly-allowed.example.com;
}
server {
listen @@PRIMARY_PORT@@;
listen [::]:@@PRIMARY_PORT@@;
@@ -1192,6 +1508,10 @@ http {
add_header 'Cache-Control' 'no-transform';
}
location /mod_pagespeed_test/no_transform {
add_header 'Cache-Control' 'no-transform';
}
# uncomment the following two lines if you're testing memcached
#pagespeed MemcachedServers "localhost:11211";
#pagespeed MemcachedThreads 1;
@@ -1206,7 +1526,16 @@ http {
#pagespeed ExperimentSpec "id=2;percent=50";
pagespeed Library 43 1o978_K0_LNE5_ystNklf
http://www.modpagespeed.com/rewrite_javascript.js;
http://www.modpagespeed.com/rewrite_javascript.js;
pagespeed RetainComment " google_ad_section*";
# Test proxying of non-.pagespeed. resources.
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/modpagespeed_http
http://@@PAGESPEED_TEST_HOST@@/do_not_modify;
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/content_type_present
http://@@PAGESPEED_TEST_HOST@@:8091;
pagespeed MapProxyDomain http://localhost:@@PRIMARY_PORT@@/content_type_absent
http://@@PAGESPEED_TEST_HOST@@:8092;
add_header X-Extra-Header 1;
@@ -1232,9 +1561,8 @@ http {
pagespeed AvoidRenamingIntrospectiveJavascript off;
location /mod_pagespeed_test/nostore {
add_header "Cache-Control" "max-age=12345";
add_header "Cache-Control" "public, no-store";
add_header "Cache-Control" "max-age=14";
proxy_pass http://localhost:@@SECONDARY_PORT@@;
proxy_set_header Host "cc-header-origin.example.com";
}
location /mod_pagespeed_test/forbid_all_disabled/disabled {
@@ -1327,6 +1655,30 @@ http {
expires 5m;
}
location /mod_pagespeed_test/ipro/wait/ {
# TODO(jmarantz): ModPagespeedInPlaceWaitForOptimized should be superfluous,
# or made equivalent to ModPagespeedInPlaceRewriteDeadlineMs -1, which waits
# forever. Otherwise ModPagespeedInPlaceRewriteDeadlineMs should just have
# the specified deadline.
# # See https://github.com/pagespeed/mod_pagespeed/issues/1171 for more
# detailed discussion.
pagespeed InPlaceWaitForOptimized on;
}
location /mod_pagespeed_test/ipro/wait/long/ {
# Make the deadline long here for valgrind tests. We could
# conditionalize this.
pagespeed InPlaceRewriteDeadlineMs 10000;
}
location /mod_pagespeed_test/ipro/wait/short/ {
pagespeed EnableFilters in_place_optimize_for_browser;
# Make the deadline short here as we expect to always miss it
# in tests.
pagespeed InPlaceRewriteDeadlineMs 1;
}
location /mod_pagespeed_test/ipro/instant/wait/ {
pagespeed InPlaceWaitForOptimized on;
+19 -3
View File
@@ -23,9 +23,9 @@
# Exits with status 2 if command line args are wrong.
#
# Usage:
# ./run_tests.sh primary_port secondary_port mod_pagespeed_dir
# ./run_tests.sh primary_port secondary_port mod_pagespeed_dir pagespeed_test_host
# Example:
# ./run_tests.sh 8050 8051 /path/to/mod_pagespeed
# ./run_tests.sh 8050 8051 /path/to/mod_pagespeed www.modpagespeed.com
#
# Normally we test only with the native fetcher off. Set
@@ -43,7 +43,7 @@ RUN_TESTS=${RUN_TESTS:-true}
# true.
USE_VALGRIND=${USE_VALGRIND:-false}
if [ "$#" -ne 4 ] ; then
if [ "$#" -ne 5 ] ; then
echo "Usage: $0 primary_port secondary_port mod_pagespeed_dir"
echo " nginx_executable"
exit 2
@@ -53,6 +53,14 @@ PRIMARY_PORT="$1"
SECONDARY_PORT="$2"
MOD_PAGESPEED_DIR="$3"
NGINX_EXECUTABLE="$4"
PAGESPEED_TEST_HOST="$5"
RCPORT1=9991
RCPORT2=9992
RCPORT3=9993
RCPORT4=9994
RCPORT5=9995
RCPORT6=9996
RCPORT7=9997
this_dir="$( cd $(dirname "$0") && pwd)"
@@ -62,7 +70,15 @@ 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" \
RCPORT1="$RCPORT1" \
RCPORT2="$RCPORT2" \
RCPORT3="$RCPORT3" \
RCPORT4="$RCPORT4" \
RCPORT5="$RCPORT5" \
RCPORT6="$RCPORT6" \
RCPORT7="$RCPORT7" \
bash "$this_dir/nginx_system_test.sh"
STATUS=$?
echo "With $@ setup."