Compare commits

..

181 Commits

Author SHA1 Message Date
Jeff Kaufman f8b87ea436 Merge pull request #636 from pagespeed/huibao-prepare-1.7.30.4-release
release: update version number 1.7.30.3 to 1.7.30.4
2014-03-13 10:37:21 -04:00
Huibao Lin 86d840f76e release: udpate version number 1.7.30.3 to 1.7.30.4 2014-03-13 10:27:21 -04:00
Jeff Kaufman 0110d33fa7 Merge pull request #635 from pagespeed/huibao-prepare-1.7.30.4-release
release: build against backported change
2014-03-13 10:26:16 -04:00
Huibao Lin 497594ba7f release: build against backported change 2014-03-13 10:18:57 -04:00
huibaolin 6db4d02a91 Merge pull request #600 from pagespeed/huibao-prepare-release-1.7.30.3-beta
release: prepare 1.7.30.3
2014-01-16 12:12:53 -08:00
Huibao Lin 1354cee4ed release: prepare 1.7.30.3 2014-01-16 15:06:49 -05:00
Jeff Kaufman 72ddb34a1c readme: release 1.7.30.2 2014-01-06 16:54:56 -05:00
Jeff Kaufman ae2d4bac7f native-fetcher: fix to work with nginx 1.5.8+
nginx 1.5.8 changed the resolver api, which the native fetcher uses.

Fixes #578.

Squash-merge of @dinic's #581.
2014-01-06 16:46:48 -05:00
Jeff Kaufman 70c47c13a4 Merge pull request #557 from pagespeed/jefftk-fix-header-only
headers: don't special case header-only requests
2013-11-08 08:32:57 -08:00
Jeff Kaufman 8021751d69 headers: don't special case header-only requests
Fixes #537.
2013-11-08 11:21:52 -05:00
Jeff Kaufman 6b29b5220d Merge pull request #555 from pagespeed/jefftk-prepare-release-1.7.30.1-beta
trunk-tracking: update to 1.7.30.1 from r3581
2013-11-08 08:19:27 -08:00
Jeff Kaufman 07286005a6 trunk-tracking: update to 1.7.30.1 from r3581
Changes:
 * r3585: With downstream caching, don't touch `Cache-Control` headers.
   * No longer require `Modify Caching Headers off`.
   * Change from `modify_caching_headers` as a boolean to a three valued enum
     `PreserveCachingHeaders`.
 * r3596: Make tests less flaky.
   * Changes WGET_DUMP to write to WGET_DIR instead of OUTDIR.
 * r3597: Remove now-redundant system tests.
   * Some system tests were moved into `automatic/system_test.sh` which means we
     can remove our forks.
 * r3598: Enable the shared memory metadata cache by default.
   * The code change just worked and needed no changes, but it also added
     substantial tests, which needed some porting.
 * Deflake the `scrape stats` test by moving it before config reloading.
2013-11-07 17:47:37 -05:00
Jeff Kaufman 721c49dc71 release: version 1.6.29.7 -> 1.7.30.1 2013-11-07 17:47:07 -05:00
Jeff Kaufman 658a30d836 Merge branch 'master' into trunk-tracking 2013-11-07 17:46:30 -05:00
Jeff Kaufman 94688bd1e5 Merge pull request #556 from pagespeed/jefftk-increase-timeout
system-test: increase timeout for keepalive tests from 1s to 2s
2013-11-07 14:46:11 -08:00
Jeff Kaufman 26aaf221c7 system-test: increase timeout for keepalive tests from 1s to 2s
The keepalive tests were occasionally bumping up against
the 1s timeout we had set for curl, but a 1s 99.9% tail
latency is a little agressive.  Drop it to 2s to make the
tests less flaky.

What we really need is a proper load testing setup, so
the keepalive test isn't doing double-duty.
2013-11-07 17:36:56 -05:00
Jeff Kaufman 530bf3c05e prepare-psol: properly include generated console files 2013-11-06 16:38:10 -05:00
Jeff Kaufman dfedc6b025 merge commit 2013-11-06 15:20:40 -05:00
Jeff Kaufman 4e3fe6f35f readme: suggest restricting the global statistics handler 2013-10-29 17:06:50 -04:00
Jeff Kaufman af6706a4c9 Merge pull request #550 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to r3581 (from r3537)
2013-10-29 06:46:47 -07:00
Jeff Kaufman b6c3001df2 trunk-tracking: update to r3581 (from r3537) 2013-10-28 16:52:56 -04:00
Jeff Kaufman b8ff84ed9b Factor out handling for errors, stats, and logs. Add nosniff protection. 2013-10-28 10:15:03 -04:00
Jeff Kaufman b83bb636f0 Factor out handling for errors, stats, and logs. Add nosniff protection. 2013-10-28 10:09:24 -04:00
Jeff Kaufman 7d6b6c4b4c versions: 1.6.29.5 -> 1.6.29.7 2013-10-28 09:59:45 -04:00
Jeff Kaufman 2629865c59 versions: 1.6.29.5 -> 1.6.29.7 2013-10-28 09:58:19 -04:00
Jeff Kaufman fd546f270b readme: 1.4.3 is stable 2013-10-23 16:25:36 -04:00
Jeff Kaufman 641fb971d1 merge commit 2013-10-23 11:07:05 -04:00
Jeff Kaufman e40cde221c Merge pull request #547 from pagespeed/jefftk-fix-dir-permissions
paths: don't require existence
2013-10-23 07:26:54 -07:00
Jeff Kaufman f956ef92e9 paths: don't require existence
Create paths for FileCachePath and LogDir if they don't exist yet and give
them proper permissions.
2013-10-22 16:47:49 -04:00
Jeff Kaufman 687e0a7028 readme: reword the canonicalize_javascript_libraries note 2013-10-21 13:26:26 -04:00
Jeff Kaufman 7c15cd83f4 canonicalize libraries: script to convert from Apache format to Nginx
Merge of Vid's #533 with some fixes.
2013-10-21 13:21:28 -04:00
Jeff Kaufman 8f6ac0660e Merge pull request #543 from pagespeed/oschaaf-shared-mem-trunk-tracking
trunk-tracking: update to build with mps r3537
2013-10-18 08:37:45 -07:00
Otto van der Schaaf 422d5afa6b trunk-tracking: update to build with mps r3537 2013-10-18 11:46:09 +02:00
Jeff Kaufman f653094040 Merge pull request #536 from pagespeed/jefftk-vlogs
logging: restore call to log_message_handler::Install()
2013-10-07 07:47:36 -07:00
Jeff Kaufman 8430a6c40e logging: remove unused constant 2013-10-04 17:52:35 -04:00
Jeff Kaufman d4fa76463d logging: restore call to log_message_handler::Install()
I missed this when moving shared components to SystemRewriteDriverFactory;
this call used to be in NgxRewriteDriverFactory::RootInit.  Without it we only
log VLOG(0), not VLOG(1) and VLOG(2) the way Apache does.

Fixes #518.
2013-10-04 17:50:19 -04:00
Jeff Kaufman 1e5769df11 Merge pull request #535 from pagespeed/jefftk-close-connection-v3
logging: fix use-after-free
2013-10-04 10:42:47 -07:00
Jeff Kaufman f1a800d37f logging: fix use-after-free
The pagespeed_connection needs a log to write to, but unfortunately
r->connection->log isn't guaranteed to still be around for the whole
lifetime of the pagespeed_connection.  Use the log from the server
context instead.

Fixes issue #522.
2013-10-04 13:21:42 -04:00
Jeff Kaufman ee4958e7dd Merge pull request #530 from pagespeed/oschaaf-process-context
Use net_instaweb::ProcessContext
2013-10-01 14:19:55 -07:00
Jeff Kaufman dbead4a62e Merge pull request #529 from pagespeed/jefftk-ipro-headers
ipro: support calling ps_in_place_body_filter multiple times
2013-09-25 08:21:42 -07:00
Jeff Kaufman 2b2d19e78d ipro: support calling ps_in_place_body_filter multiple times
Fixes #520
2013-09-25 11:21:33 -04:00
Jeff Kaufman 9ed9fecc0f ipro: fix typo: 2013-09-25 10:07:50 -04:00
Jeff Kaufman 06e64dec7a Merge pull request #531 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to r3508
2013-09-25 07:03:39 -07:00
Jeff Kaufman 420b58c346 trunk-tracking: update to r3508
No major changes that we need to be compatible with.  r3508 tweaks
InPlaceResourceRecorder::DoneAndSetHeaders so that we can now make sure to
release it: the recorder is allocated in ps_in_place_check_header_filter and
released in ps_in_place_body_filter, but if there's an error in between it will
be leaked.  We know ps_release_request_context will get run regardless because
it's set as a cleanup handler, so clean up the recorder there.

Fixes #527
2013-09-24 17:19:06 -04:00
Jeff Kaufman 36554ce92f merging: accidentally restored obselete NgxThreadSystem 2013-09-24 17:09:37 -04:00
Otto van der Schaaf c5265b47cf Use net_instaweb::ProcessContext
This fixes a few valgrind errors on shutdown, plus a potential
issue when url_util.cc would lazily initialize in a thread-unsafe
manner. Also adds --leak-check=full to the suggested valgrind
command for the system tests.
2013-09-24 23:09:14 +02:00
Jeff Kaufman c29ac1e6a3 merge commit 2013-09-24 16:16:16 -04:00
Jeff Kaufman 6e86835599 Merge pull request #528 from pagespeed/jud-gcc48
Fix GCC 4.8 build errors
2013-09-24 13:11:42 -07:00
Jud Porter f70eb5df40 Add -Wno-unused-local-typedefs and -Wno-error to CFLAGS to fix build issues on GCC 4.8. 2013-09-24 15:59:56 -04:00
Jeff Kaufman 4650aa4a3f Merge pull request #508 from pagespeed/jefftk-backport-reload-fix
reloading: backport reloading fix
2013-09-24 07:21:14 -07:00
Jeff Kaufman 34e3101edd reloading: backport reloading fix
Issue #364 was fixed upstream in r3492.  Backport the fix to master.

"We only need to shut down the caches in child processes because they are not
started in the master process.  This wasn't a problem before, but shutting down
the caches can start a thread which isn't safe to do in the master process of a
forking server like Nginx."

Also backport the change from r3497 where we use a DCHECK for
may_start_threads_.  It's bad to start threads in the root process, but it's not
worth crashing a production server over.
2013-09-13 10:11:51 -04:00
Jeff Kaufman fdbdf11bab Merge pull request #506 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update from 3485 to 3497
2013-09-13 07:02:31 -07:00
Jeff Kaufman db238e7705 trunk-tracking: update from 3485 to 3497
* Remove NgxThreadSystem because there's now a SystemThreadSystem that
  has everything we need.
* fixes https://github.com/pagespeed/ngx_pagespeed/issues/364
2013-09-12 17:33:14 -04:00
Jeff Kaufman a196cfe071 Merge branch 'master' into trunk-tracking 2013-09-12 11:27:40 -04:00
Jeff Kaufman 442d319aef Merge pull request #505 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to r3485
2013-09-12 08:27:00 -07:00
Jeff Kaufman a48c243e3e config: fix typo in FLAG_MARCH 2013-09-11 09:51:12 -04:00
Jeff Kaufman 5c17cb671c trunk-tracking: update to r3485
* Adds IPRO tests that we should have copied from apache_system_test.sh back
  when we first added IPRO.
  * The "IPRO-optimized resources should have fixed size, not chunked" test
    fails.  The problem is as it says: IPRO optimized resources are being sent
    out with `Transfer-Encoding: Chunked` instead of `Content-Length: ...`.  How
    do we fix this?
* install/system_test.sh moved to net/instaweb/automatic/system_test.sh
* minor method signature changes
* url.is_valid() is gone, replaced by .IsWebValid()
* I pushed Otto's #464 upstream, and now we need to make some IPRO changes.
* beacons have nonces now, so we need to update tests.
2013-09-10 16:57:44 -04:00
Jeff Kaufman 94d004e72c Merge pull request #504 from yaoweibin/march_i686
fixed the dynamic link problem with tengine in i686 box.
2013-09-10 08:16:31 -07:00
Weibin Yao 21a9705b78 fixed the dynamic link problem with tengine in i686 box.
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.
2013-09-10 22:59:37 +08:00
Jeff Kaufman 137182792e Merge pull request #499 from pagespeed/jefftk-simplify-handlers
handlers: collect redundant handler information
2013-08-30 06:23:16 -07:00
Jeff Kaufman 3dbb845603 handlers: collect redundant handler information
Create ps_simple_handler to combine haandling for static content, statistics,
console, and messages.
2013-08-29 16:04:22 -04:00
Jeff Kaufman ac7a6bce2c Merge pull request #498 from pagespeed/jefftk-code-cleanup
code cleanup
2013-08-29 09:51:04 -07:00
Jeff Kaufman 9baf3d01d3 code cleanup
Get rid of net_instaweb:: everywhere.  By eliminating the ngx_psol namespace we
can stop prefixing everything in ngx_pagespeed.cc with net_instaweb::

Fix other minor style issues.

Remove unnecessary declarations.

Rename ps_create_request_context to ps_route_request and CreateRequestContext to
RequestRouting because it no longer creates the request context.
2013-08-29 09:53:05 -04:00
Jeff Kaufman 1db13030fa trunk-tracking: update from r3403 to r3457
Statistics reporting is now handled in system/ but we need to call in.
2013-08-29 09:03:11 -04:00
Jeff Kaufman be2fb57d85 Merge pull request #495 from pagespeed/jefftk-cleanup-property-cache-lookup
property-cache: use ProxyFetchFactory::InitiatePropertyCacheLookup
2013-08-28 08:29:28 -07:00
Jeff Kaufman 3a99b9adff property-cache: use ProxyFetchFactory::InitiatePropertyCacheLookup 2013-08-28 09:37:47 -04:00
Jeff Kaufman 8cb48034f0 Merge pull request #494 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to r3448 from r3403
2013-08-28 06:34:49 -07:00
Jeff Kaufman 49c96c9202 trunk-tracking: update to r3448 from r3403
As of r3447 ServerContext::ChildInit is now in system/, which means we can
delete a lot of code.

DangerFetchFromUnknownHosts and FetchWithGzip are now handled by RewriteOptions.

ServerContext now needs a hostname and port, but we don't have one so we
hackishly provide a different unique id.
2013-08-27 14:10:09 -04:00
Jeff Kaufman ad2ea9498b Merge branch 'master' into trunk-tracking 2013-08-27 13:50:47 -04:00
Jeff Kaufman 3a085e114d Merge pull request #480 from pagespeed/jefftk-update-trunk-tracking
Adjust for fetchers and options that moved from apache/ to system/ in r3390
2013-08-27 07:41:24 -07:00
Jeff Kaufman 3fbb740101 Merge pull request #490 from pagespeed/new-trunk-tracking-rotation
Removing redundant X-Cache header handling.
2013-08-21 09:49:44 -07:00
Anupama Dutta fa99ac39b4 Removing redundant X-Cache header handling.
X-Cache handling is not needed because the pagespeed server never gets to see
a request with X-Cache header added by its downstream cache. X-Cache headers
are only to be added in responses served out of the downstream cache for debugging
purposes only. This piece of deleted code was also conflicting with X-Cache
headers present on upstream caches (wrt pagespeed) and hence not optimizing responses
that happened to carry this header.

(More details are present in https://github.com/pagespeed/ngx_pagespeed/issues/488)
2013-08-21 10:57:48 -04:00
Jeff Kaufman d0de777452 Merge pull request #484 from pagespeed/jefftk-base-fetch-request-headers
headers: simplify header setting
2013-08-09 15:56:46 -07:00
Jeff Kaufman eb9979f048 headers: simplify header setting
* Remove PopulateRequestHeaders() and PopulateResponseHeaders().
* Set stop copying request headers to the base fetch twice.
  * This fixes a dcheck failure in the debug build.
2013-08-09 14:10:18 -04:00
Jeff Kaufman c57c16c499 trunk-tracking: update to r3402
Adjust for fetchers and options that moved from apache/ to system/ in r3390.

Use AllocateFetcher() hook from r3402 to put the native fetcher into the fetcher
map maintained by the SystemRewriteDriverFactory.
2013-08-08 10:49:34 -04:00
Jeff Kaufman 70284c987e Merge pull request #477 from pagespeed/jefftk-style
style: indentation and other minor style fixes
2013-08-06 07:46:14 -07:00
Jeff Kaufman 64f2ab6591 style: indentation and other minor style fixes 2013-08-06 10:07:49 -04:00
Jeff Kaufman c739bf29c4 Merge branch 'master' into trunk-tracking 2013-08-05 17:30:36 -04:00
Jeff Kaufman bb1093e8b2 Merge pull request #469 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: take advantage of new functionality in system/
2013-08-05 14:24:25 -07:00
Jeff Kaufman 51eaeddfba trunk-tracking: update apache_system_test for minor changes in r3369 and r3374 2013-08-05 17:23:23 -04:00
Jeff Kaufman 122c234570 trunk-tracking: adjust for big changes from r3366
SystemRewriteDriverFactory was expanded by r3366 to do a lot of what
NgxRewriteDriverFactory used to have to do.  Take advantage of this and
simplifiy our code.
2013-08-05 11:22:58 -04:00
Jeff Kaufman ddf844b680 Merge pull request #473 from pagespeed/oschaaf-response-header-options
response-header-options: consider the response headers for options
2013-08-05 08:06:34 -07:00
Otto van der Schaaf a245f40bcf Merge pull request #472 from pagespeed/oschaaf-native-fetcher-timeouts
native-fetcher: timeouts
2013-08-05 07:57:44 -07:00
Otto van der Schaaf cafb06c011 native-fetcher: timeouts
After more testing, it turns out that the timer that is initially set
in Init() remains active throughout the whole lifetime of the fetch.

This reverts the previous change, which isn't correct, and replaces
all TODO's concerning timers with a comment about that we don't need
them.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/466
2013-08-05 16:57:02 +02:00
Otto van der Schaaf cbfbb5b6d6 response-header-options: consider the response headers for options
Take the response headers into account when determining the options
for the request. Also adds tests for this.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/356
2013-08-05 16:42:49 +02:00
Jeff Kaufman 606a75a068 Merge pull request #474 from pagespeed/oschaaf-max-buffer-size
max-buffer-size: use ngx_pagesize
2013-08-05 04:44:38 -07:00
Jeff Kaufman 0c26aafc2f Merge pull request #471 from pagespeed/oschaaf-pointer-declaration-style
pointer-declaration-style: fix style issues
2013-08-05 04:32:47 -07:00
Otto van der Schaaf 8bd4ed2ec2 max-buffer-size: use ngx_pagesize
Other modules seem to use ngx_pagesize as the default buffer size:
http://lxr.evanmiller.org/http/source/http/modules/ngx_http_gunzip_filter_module.c#L661
2013-08-05 10:33:47 +02:00
Otto van der Schaaf 9c5fb3107e pointer-declaration-style: fix style issues 2013-08-04 15:25:26 +02:00
Otto van der Schaaf 1c86ab66be Merge pull request #465 from pagespeed/oschaaf-native-fetcher-crash
native-fetcher: fix a crasher, and set a timeout
2013-08-03 00:06:13 -07:00
Otto van der Schaaf f05e3cf281 native-fetcher: fix a crasher, and set a timeout
Handle the case where ngx_event_connect_peer didn't return NGX_OK.
Also replace a TODO for adding a timer with actually adding the
timer.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/463
2013-08-01 15:39:02 +02:00
Jeff Kaufman 177b70b995 Merge pull request #460 from pagespeed/oschaaf-test-accidental-quotes
system-test: remove a few stray quotes
2013-07-30 13:53:29 -07:00
Otto van der Schaaf 3b2b28559a system-test: remove a few stray quotes
This fixes nginx's complaints about receiving invalid headers after
running the system tests.
2013-07-30 22:43:39 +02:00
Jeff Kaufman 7e89db8fa1 trunk-tracking: in_place_resource_recorder changes 2013-07-30 15:38:42 -04:00
Jeff Kaufman 9b3ab25cea Merge branch 'master' into trunk-tracking 2013-07-30 15:27:53 -04:00
Otto van der Schaaf 54ef25214c Merge pull request #457 from pagespeed/oschaaf-modify-headers
header-handling: ModifyCachingheaders & Content-Encoding
2013-07-30 12:19:46 -07:00
Otto van der Schaaf b9db498199 header-handling: ModifyCachingHeaders & Content-Encoding
- Change header handling for ModifyCachingHeaders
- Don't copy over response headers which have their hash set to 0
- Don't invent a date header
2013-07-30 21:14:49 +02:00
Jeff Kaufman 6503ebfb1a merge commit 2013-07-30 14:30:55 -04:00
Jeff Kaufman baf35dc906 Merge pull request #458 from pagespeed/jud-trunk-tracking
Trunk tracking updates
2013-07-26 12:14:24 -07:00
Jud Porter f4466918f3 System test changes to align with latest mod_pagespeed trunk. 2013-07-26 14:54:02 -04:00
Jeff Kaufman 3b6caa38aa release: merging readme changes for 1.6.29.5 2013-07-25 14:31:45 -04:00
Jeff Kaufman b1127c2a01 release: 1.6.29.5 2013-07-25 13:56:28 -04:00
Jeff Kaufman ad6429d26f ipro: support in-place resource optimization
Squash-merge of chaizhenhua's work over many pull requests, especially #450.

The copy of in_place_resource_recorder.cc is temporary and can be removed after
the next PSOL release.
2013-07-24 10:45:39 -04:00
Jeff Kaufman 59cdafaf70 Merge pull request #454 from pagespeed/oschaaf-force-caching
force-caching: fix configuration handling
2013-07-24 07:15:40 -07:00
Otto van der Schaaf 34ebc2d179 force-caching: fix configuration handling
Make pagespeed ForceCaching [on|off] work
2013-07-23 13:12:24 +02:00
Otto van der Schaaf 49c9de63cd Merge pull request #448 from pagespeed/oschaaf-log-vhost-specific
logging: respect error_log in nginx.conf server blocks
2013-07-23 01:52:34 -07:00
Otto van der Schaaf 502a604a26 logging: respect error_log in nginx.conf server blocks
This makes messages written via the NgxMessageHandler from the
NgxServerContext be written with the nginx error_log configuration
specified at the server{} level, if specified.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/447
2013-07-23 10:51:47 +02:00
Jeff Kaufman fca58f2d6f Merge pull request #444 from morlovich/morlovich-trunk-tracking-20130719
trunk-tracking: merge with MPS trunk as of 2003-07-19
2013-07-22 07:13:31 -07:00
Jeff Kaufman b2bbdcc0df Merge pull request #443 from patschi/patch-2
readme: recommend nginx 1.4.2 stable
2013-07-22 07:05:20 -07:00
Otto van der Schaaf bdb5de5a2f Merge pull request #446 from pagespeed/oschaaf-missing-beacon-urls
system-tests: fix missing beacon urls
2013-07-22 04:56:18 -07:00
Otto van der Schaaf 960d0940bb system-tests: fix missing beacon url parameters in tests
Fix 2 tests on the beacon by adding the missing url parameter
2013-07-21 14:20:16 +02:00
Otto van der Schaaf e7a91c2f0a Merge pull request #445 from pagespeed/oschaaf-fix-keepalive-test-gzip
keepalive-test: fix gzip accept encoding
2013-07-20 03:11:06 -07:00
Otto van der Schaaf e583afdb49 keepalive-test: fix gzip accept encoding
We would send "Accept-Encoding:gzip" in the request headers. NGINX
would mark that as an invalid header, as it misses a space after ':'
2013-07-20 09:06:38 +02:00
Maks Orlovich 53138d7b34 Merge with MPS trunk as of 2003-07-19
This has 2 families of changes:
- Port to changes in PropertyCache API
- Update to a MapProxyDomain test.
2013-07-19 14:28:46 -04:00
Patschi e45acf4613 nginx 1.4.2 stable released
Changelog: http://nginx.org/en/CHANGES-1.4
2013-07-19 14:45:21 +02:00
Otto van der Schaaf 47e3364332 Merge pull request #439 from pagespeed/oschaaf-shutdown-fix
shutdown: fix segfault when shutting down a worker process
2013-07-18 14:21:12 -07:00
Otto van der Schaaf 49760f03a0 shutdown: fix a crash when shutting down a worker process
Remove the deferred cleanup, as in ngx_pagespeed the fetcher
is owned by the RewriteDriverFactory.

Fixes the backtrace pointing to
net_instaweb::RewriteDriverFactory::Deleter
at https://github.com/pagespeed/ngx_pagespeed/issues/367
2013-07-18 23:20:03 +02:00
Jud Porter 2f5afcddd1 Merge pull request #440 from pagespeed/anupama-updates-to-trunk-tracking
Updating trunk-tracking to be in sync with r3298.
2013-07-15 11:05:43 -07:00
Anupama Dutta 67beee1444 Updating trunk-tracking to be in sync with r3298.
Fixes to allow ngx_pagespeed trunk-tracking branch to compile and work with r3298 mod_pagespeed revision:
- Config fix to include path for critical_keys.pb.h.
- Make changes needed due to RewriteOptions refactoring done in https://code.google.com/p/modpagespeed/source/detail?r=3226
2013-07-15 13:20:14 -04:00
Jeff Kaufman cd80e92df1 Merge pull request #435 from pagespeed/oschaaf-refactor-static-handler
static-handler: refactor to use write_handler_response
2013-07-12 13:33:30 -07:00
Otto van der Schaaf e303c92041 Merge pull request #437 from pagespeed/oschaaf-downstream-cache-fix-test
downstream-cache-test: don't hard code the port to 8051
2013-07-12 09:26:47 -07:00
Otto van der Schaaf ccd36dd658 downstream-cache-test: don't hard code the port to 8051 2013-07-12 18:21:55 +02:00
Otto van der Schaaf 3a9953e25c static-handler: refactor to use write_handler_response
This fixes sending out the weak ETag for ngx_pagespeed_static/js_defer.hash.js,
and simplifies things somewhat for this code path.
It also adds a test for it.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/434
2013-07-12 18:12:13 +02:00
Jeff Kaufman 311ea897cf Merge pull request #436 from pagespeed/jefftk-simplify-option-setting
options: refactor repeated code in option setting
2013-07-12 07:55:07 -07:00
Jeff Kaufman 4cc3e4def3 options: refactor repeated code in option setting 2013-07-12 10:44:34 -04:00
Jeff Kaufman 301a5249a8 Merge branch 'master' into trunk-tracking 2013-07-10 12:44:50 -04:00
Otto van der Schaaf 4bff89e8af Merge pull request #431 from pagespeed/oschaaf-fix-keepalive-test
keepalive-test: prevent false positives, filter a little more
2013-07-09 23:40:42 -07:00
Jeff Kaufman fa29f9ff32 merge: rate controlled fetcher 2013-07-09 10:07:13 -04:00
Jeff Kaufman aeba9eb285 Merge pull request #428 from pagespeed/jefftk-head-get
request: allow alternate request methods when rewriting html
2013-07-09 07:01:46 -07:00
Otto van der Schaaf 5d2e2d7b67 keepalive-test: prevent false positives, filter a little more
From the comments at https://github.com/pagespeed/ngx_pagespeed/pull/425,
on Chai's machine curl's output seems slightly different when it
reports it is trying to connect.
2013-07-09 15:36:57 +02:00
Jeff Kaufman e61c4f722f test: expect fewer arguments in beacon 2013-07-08 16:51:01 -04:00
Jeff Kaufman 505d3be9b9 Merge pull request #427 from pagespeed/oschaaf-rate-limiting
fetch-rate-limiting: add rate limiting for background fetches
2013-07-08 08:16:55 -07:00
Jeff Kaufman bec52734f9 request: allow alternate request methods when rewriting html 2013-07-08 11:10:25 -04:00
Otto van der Schaaf 73f7531ed5 fetch-rate-limiting: add rate limiting for background fetches
Limits the number of simultaneous background fetches performed.
Requires statistics to be turned on.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/426
2013-07-08 16:38:02 +02:00
Jeff Kaufman 96fbca62e0 Merge pull request #423 from pagespeed/oschaaf-double-forward-declaration
double-forward-declaration: remove a duplicate forward declaration
2013-07-07 08:05:12 -07:00
Otto van der Schaaf 36aed99813 double-forward-declaration: remove a duplicate forward declaration 2013-07-06 23:03:04 +02:00
Jeff Kaufman e1cd69e672 release: 1.6.29.2 -> 1.6.29.3 2013-07-04 09:48:52 -04:00
Jeff Kaufman 41f75282d8 release: 1.5.27.3 -> 1.6.29.2 in documentation 2013-07-02 11:20:48 -04:00
Jeff Kaufman aa6ef1d6f2 Merge pull request #420 from pagespeed/jefftk-trunk-tracking-nocache
headers: pass through no-store; don't duplicate cache-control
2013-07-02 08:16:33 -07:00
Jeff Kaufman 40fc16b1ea headers: pass through no-store; don't duplicate cache-control 2013-07-02 10:49:12 -04:00
Jeff Kaufman db882d350c Merge pull request #419 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to 1.6.29.2
2013-07-01 11:30:57 -07:00
Jeff Kaufman 3edd4f851f trunk-tracking: update to 1.6.29.2
* ConsoleHandler now takes a RewriteOptions
* Console needs ports to override the statistics handler path.  Before the
  console just assumed statistics were available at /mod_pagespeed_statistics.
* The "nostore" test fails.  I've marked this as an expected failure and will
  fix it in a followup.
* downstream_cache_purges stat was renamed to downstream_cache_purge_attempts
* Proxying tests with gstatic no longer use 1.gif but are switched to
  pss-architecture.png.
* DownstreamCacheLifetimeMs option was removed.
2013-07-01 14:21:09 -04:00
Jeff Kaufman cd2be9aa9c Merge pull request #417 from pagespeed/anupama-updates-to-trunk-tracking
caching: Conf updates wrt "location" option.
2013-06-25 13:01:00 -07:00
Anupama Dutta 52e1c189fa caching: Conf updates wrt "location" option.
Uses DownstreamCachePurgeLocationPrefix to avoid loopback through pagespeed server for purge requests.
2013-06-25 15:53:13 -04:00
Jeff Kaufman 0231f021ad Merge pull request #415 from pagespeed/jefftk-console
console: support /pagespeed_console
2013-06-25 08:45:43 -07:00
Jeff Kaufman 25e9fba38c console: support /pagespeed_console
sligocki is adding a feature to pagespeed where it will parse your statistics
for you and determine if there are any problems.  This CL wires up the
ConsoleHandler and also includes a few required files in the build process.

It doesn't work yet, because as of svn r3193 the console has a hardcoded json
request to '/mod_pagespeed_statistics' and in nginx we use '/ngx_...' .
I've tested this by changing all uses here to use the "mod_..." version and that
worked, but I've undone those changes.
2013-06-25 11:45:16 -04:00
Jeff Kaufman 0fc61adb30 Merge pull request #414 from pagespeed/jefftk-update-trunk-tracking
trunk-tracking: update to r3193
2013-06-24 12:04:54 -07:00
Jeff Kaufman 84ff166375 trunk-tracking: update to r3193
* statistics_logging_file_prefix is gone, replaced with log_dir
* propagate a units fix from apache_system_test
* test nonces for critical css beaconing

Previous trunk-tracking was at 3162.  Diff of apache_system_test.sh:
  https://code.google.com/p/modpagespeed/source/diff?path=/trunk/src/install/apache_system_test.sh&format=side&r=3193&old_path=/trunk/src/install/apache_system_test.sh&old=3162
2013-06-24 15:03:54 -04:00
Jeff Kaufman 04ab9a06e7 Merge pull request #412 from morlovich/morlovich-trunk-tracking-20030614
Update to match trunk as of 2003-06-17 (r3162)
2013-06-17 13:18:48 -07:00
Maks Orlovich f8454d500a Update to match trunk as of 2003-06-17.
This matches two changes:
- Anupama made the caching tests use downstream_caching.html
(Thanks to her for help in updating this)
- Jan updated some configuration defaults, which made some images
compress more.
2013-06-17 14:42:36 -04:00
Jeff Kaufman 1904494276 Merge pull request #409 from pagespeed/anupama-update-trunk-tracking-html-caching
caching: Sample proxy_cache_key construction.
2013-06-11 10:59:43 -07:00
Anupama Dutta a421f6c501 caching: Sample proxy_cache_key construction.
Adding a nginx conf snippet for constructing a proxy_cache_key based on the UserAgent and expected optimizations for that UserAgent class, bypassing the cache for all other cases. Sample config for downstream-cache proxy_cache_key construction now takes care of 2 classes of UserAgents (expected to get most of the traffic for a site) and also bypasses cache for all other desktop UAs, all mobile UAs and all tablet UAs.

(Fixing the startup phase of the nginx server to put out the original error message in case of failure.)
2013-06-11 13:33:07 -04:00
Jeff Kaufman 3359910784 Merge pull request #407 from pagespeed/anupama-updates-to-trunk-tracking
Updating trunk-tracking against PSOL r3130.
2013-06-10 14:03:11 -07:00
Anupama Dutta 1f7bab2faf Updating trunk-tracking against PSOL r3130.
Small fix for compilation error caused due to removal of all synchronous fetchers in r3128.
2013-06-10 14:18:54 -04:00
Jud Porter 4d85b56e1e Merge pull request #405 from pagespeed/jud-trunk-tracking
Fix build errors with trunk
2013-06-10 07:43:20 -07:00
Jud Porter 261e46a6d1 Merge branch 'jud-trunk-tracking' of https://github.com/pagespeed/ngx_pagespeed into jud-trunk-tracking 2013-06-10 10:32:22 -04:00
Jud Porter 556cf508f1 Revert removing system/ cc files, as that causes linker errors. 2013-06-10 10:30:20 -04:00
Jud Porter a668eafc38 Remove unnecessary cc sources from config. 2013-06-10 10:30:20 -04:00
Jud Porter a0fdf4b940 Fix add_instrumentation test. 2013-06-10 10:30:20 -04:00
Jud Porter 6f845f9fa5 Use SystemRewriteDriverFactory::InitStats instead of RewriteDriverFactory::InitStats 2013-06-10 10:30:20 -04:00
Jud Porter 7e9c6b2dbc Add CFLAGS to fix OpenSSL linker error. 2013-06-10 10:30:20 -04:00
Jud Porter d9c19b98b7 Fix paths for files moved from apache/ to system/ 2013-06-10 10:30:20 -04:00
Jud Porter 841eca0e99 Revert removing system/ cc files, as that causes linker errors. 2013-06-07 18:51:23 -04:00
Jud Porter 1a819e74c3 Remove unnecessary cc sources from config. 2013-06-07 18:19:26 -04:00
Jud Porter fcf56710d3 Fix add_instrumentation test. 2013-06-07 17:25:56 -04:00
Jud Porter c8094915b7 Use SystemRewriteDriverFactory::InitStats instead of RewriteDriverFactory::InitStats 2013-06-07 16:41:20 -04:00
Jud Porter 6d0e256f1b Add CFLAGS to fix OpenSSL linker error. 2013-06-07 16:39:44 -04:00
Jeff Kaufman 8e76e14f4e caching: support for proxy_cache
Add support for proxy_cache integration with pagespeed with:

a) Handling cache-hit-header to bypass content handling by pagespeed.
b) pagespeed_test_conf.template with the proxy_cache configuration blocks.
c) System tests for checking hit and miss headers and purge requests.
d) Checking for proxy_cache_purge module during start-up for tests.

Squash-merge of Anupama's #404
2013-06-07 11:44:47 -04:00
Jud Porter b5bb232044 Fix paths for files moved from apache/ to system/ 2013-06-07 10:52:03 -04:00
Jeff Kaufman 2503f406b6 Merge branch 'master' into trunk-tracking 2013-06-06 14:18:08 -04:00
Jeff Kaufman b04132e341 Merge pull request #396 from pagespeed/anupama-update-trunk-tracking
Getting it working with mod_pagespeed (r3061).
2013-06-03 09:43:37 -07:00
Anupama Dutta 9b7e2571bd Getting it working with mod_pagespeed (r3061).
Updating trunk-tracking to compile and work with mod_pagespeed svn revision 3061 with 2 small modifications to serf_url_async_fetcher.cc to disable SERF_HTTPS_FETCHING.

Please note that anyone building mod_pagespeed from source will need to
a) edit serf_url_async_fetcher.h to change the line "#define SERF_HTTPS_FETCHING 1" to have 0.
b) edit serf_url_async_fetcher.cc to move the definition of "apr_status_t status = APR_SUCCESS;" on line 265 to be inside the "#if SERF_HTTPS_FETCHING" block (in order to avoid a compilation error for psol/mod_pagespeed).

Highlights of this change:

1) Propagating renaming changes related to
  a) Furious -> Experiment
  b) ModPagespeed -> PageSpeed.
2) UrlPollableAsyncFetcher going away.
3) RewriteOptions now requiring a ThreadSystem parameter for construction.
4) Removing client_property_cache references and usages (since this was removed from mod_pagespeed).
5) Propagating beacon construction changes (where POST requests can now carry the url query param in the request).
6) General fixes for API/test breakages in statistics_logger, fallback property page cache,
2013-05-30 15:42:38 -04:00
Jeff Kaufman 888265b36a Merge pull request #393 from pagespeed/jefftk-loop-headers
ngx-list-iterator: Make it easier to iterate over headers.  Fixes #359.
2013-05-29 11:28:31 -07:00
Jeff Kaufman 6da81d760d ngx-list-iterator: Make it easier to iterate over headers. Fixes #359. 2013-05-29 13:43:35 -04:00
Otto van der Schaaf 08cc94bdb3 Merge pull request #391 from pagespeed/oschaaf-keepalive-test-more
keepalive-tests: add more keepalive tests
2013-05-29 08:14:55 -07:00
Otto van der Schaaf e010be17a9 keepalive-tests: add more keepalive tests
- beacon get requests
- beacon post requests
- requests on /ngx_pagespeed_static
- requests on .pagespeed. resources
2013-05-29 17:09:04 +02:00
Jeff Kaufman a898bad02d Merge pull request #389 from pagespeed/oschaaf-keepalive-test
keepalive-test: Test that we handle keep-alive requests OK
2013-05-28 10:42:13 -07:00
Otto van der Schaaf 8e1cbbf967 keepalive-test: Test that we handle keep-alive requests OK
Add a keepalive test which is repeated 100 times, with us both
behind the gzip filter and directly behind nginx's output filter.
The reason for that is that modules running after us can mask
our errors, this at least tests the most used ones.

This CL adds a failure to the expected failures, as currently,
this tests gives suspicious messages in nginx's error.log:
"client prematurely closed connection while sending response to client"

We should probably also test other code paths, like .pagespeed.
resources and the beacon with post requests as well. If this approach
is generally ok, I can proceed to add those as well.
2013-05-28 19:36:08 +02:00
Jeff Kaufman 4a4ba6592b readme: google pagespeed docs now include ngx_pagespeed 2013-05-28 11:08:03 -04:00
Jeff Kaufman b3624743e3 Merge pull request #385 from pagespeed/jefftk-quieter-startup
options: remove option parsing messages
2013-05-20 10:03:25 -07:00
Jeff Kaufman e8a284d2e7 options: remove option parsing messages 2013-05-18 14:50:31 -04:00
30 changed files with 2985 additions and 2681 deletions
+31 -33
View File
@@ -37,21 +37,21 @@ recompiling Tengine](https://github.com/pagespeed/ngx_pagespeed/wiki/Using-ngx_p
```bash
$ cd ~
$ wget https://github.com/pagespeed/ngx_pagespeed/archive/release-1.5.27.3-beta.zip
$ unzip release-1.5.27.3-beta.zip # or unzip release-1.5.27.3-beta
$ cd ngx_pagespeed-release-1.5.27.3-beta/
$ wget https://dl.google.com/dl/page-speed/psol/1.5.27.3.tar.gz
$ tar -xzvf 1.5.27.3.tar.gz # expands to psol/
$ wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.7.30.4-beta.zip
$ unzip v1.7.30.4-beta.zip # or unzip v1.7.30.4-beta
$ cd ngx_pagespeed-1.7.30.4-beta/
$ wget https://dl.google.com/dl/page-speed/psol/1.7.30.4.tar.gz
$ tar -xzvf 1.7.30.4.tar.gz # expands to psol/
```
3. Download and build nginx:
```bash
$ # check http://nginx.org/en/download.html for the latest version
$ wget http://nginx.org/download/nginx-1.4.1.tar.gz
$ tar -xvzf nginx-1.4.1.tar.gz
$ cd nginx-1.4.1/
$ ./configure --add-module=$HOME/ngx_pagespeed-release-1.5.27.3-beta
$ wget http://nginx.org/download/nginx-1.4.4.tar.gz
$ tar -xvzf nginx-1.4.4.tar.gz
$ cd nginx-1.4.4/
$ ./configure --add-module=$HOME/ngx_pagespeed-1.7.30.4-beta
$ make
$ sudo make install
```
@@ -72,8 +72,6 @@ In your `nginx.conf`, add to the main or server block:
```nginx
pagespeed on;
# needs to exist and be writable by nginx
pagespeed FileCachePath /var/ngx_pagespeed_cache;
```
@@ -86,7 +84,9 @@ location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""
location ~ "^/ngx_pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; }
location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }
location /pagespeed_console { allow 127.0.0.1; deny all; }
```
To confirm that the module is loaded, fetch a page and check that you see the
@@ -94,33 +94,14 @@ To confirm that the module is loaded, fetch a page and check that you see the
```bash
$ curl -I 'http://localhost:8050/some_page/' | grep X-Page-Speed
X-Page-Speed: 1.5.27.3-...
X-Page-Speed: 1.7.30.4-...
```
Looking at the source of a few pages you should see various changes, such as
urls being replaced with new ones like `yellow.css.pagespeed.ce.lzJ8VcVi1l.css`.
When reading the [mod_pagespeed
documentation](https://developers.google.com/speed/docs/mod_pagespeed/using_mod),
keep in mind that you need to make a small adjustment to configuration
directives: replace **ModPagespeed** with **pagespeed**:
mod_pagespeed.conf:
ModPagespeedEnableFilters collapse_whitespace,add_instrumentation
ModPagespeedRunExperiment on
ModPagespeedExperimentSpec id=3;percent=50;default
ModPagespeedExperimentSpec id=4;percent=50
ngx_pagespeed.conf:
pagespeed EnableFilters collapse_whitespace,add_instrumentation;
pagespeed RunExperiment on;
pagespeed ExperimentSpec "id=3;percent=50;default";
pagespeed ExperimentSpec "id=4;percent=50";
For more configuration details, see the [differences from mod_pagespeed
configuration](https://github.com/pagespeed/ngx_pagespeed/wiki/Configuration-differences-from-mod_pagespeed)
and <a href="https://github.com/pagespeed/ngx_pagespeed/wiki/Known-Issues">known
issues</a> wiki pages.
For complete documentation, see [Using
PageSpeed](https://developers.google.com/speed/pagespeed/module/using).
There are extensive system tests which cover most of ngx_pagespeed's
functionality. Consider [testing your
@@ -133,3 +114,20 @@ the progress of the project:
list](https://groups.google.com/forum/#!forum/ngx-pagespeed-discuss)
- [ngx-pagespeed-announce mailing
list](https://groups.google.com/forum/#!forum/ngx-pagespeed-announce)
Note: The
[canonicalize_javascript_libraries](https://developers.google.com/speed/pagespeed/module/filter-canonicalize-js)
depends on `pagespeed_libraries.conf` which is distributed in Apache's format.
To convert it to the Nginx format, run:
```bash
$ scripts/pagespeed_libraries_generator.sh > ~/pagespeed_libraries.conf
$ sudo mv ~/pagespeed_libraries.conf /etc/nginx/
```
And then include it in your Nginx configuration by reference:
```nginx
include pagespeed_libraries.conf;
pagespeed EnableFilters canonicalize_javascript_libraries;
```
+53 -22
View File
@@ -27,8 +27,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.5.27.3.tar.gz"
echo " $ tar -xzvf 1.5.27.3.tar.gz # expands to psol/"
echo " $ wget https://dl.google.com/dl/page-speed/psol/1.7.30.4.tar.gz"
echo " $ tar -xzvf 1.7.30.4.tar.gz # expands to psol/"
echo ""
echo " Or see the installation instructions:"
echo " https://github.com/pagespeed/ngx_pagespeed#how-to-build"
@@ -83,6 +83,34 @@ else
buildtype=Release
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
FLAG_MARCH='-march=i686'
fi
# Building with HTTPS fetching enabled pulls in a version of OpenSSL that causes
# linker errors, so disable it here.
CFLAGS="$CFLAGS -DSERF_HTTPS_FETCHING=0 $FLAG_MARCH"
case "$NGX_GCC_VER" in
4.8*)
# On GCC 4.8 and above, -Wall enables -Wunused-local-typedefs. This breaks
# on VerifySizesAreEqual in bit_cast in chromium/src/base/basictypes.h which
# has a typedef that is intentionally unused.
CFLAGS="$CFLAGS -Wno-unused-local-typedefs"
# On GCC 4.8 and above, we get the following compiler warning:
# chromium/src/base/memory/scoped_ptr.h:133:7: warning: declaration of class scoped_ptr<C> [enabled by default]
# Based on discussion at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54055,
# this is invalid code, but hasn't been fixed yet in chromium.
# Unfortunately, there also does not appear to be a flag for just disabling
# that warning, so we add Wno-error to override nginx's default -Werror
# option.
CFLAGS="$CFLAGS -Wno-error"
;;
esac
pagespeed_include="\
$mod_pagespeed_dir \
$mod_pagespeed_dir/third_party/chromium/src \
@@ -91,6 +119,7 @@ pagespeed_include="\
$mod_pagespeed_dir/third_party/protobuf/src \
$mod_pagespeed_dir/third_party/re2/src \
$mod_pagespeed_dir/out/$buildtype/obj/gen \
$mod_pagespeed_dir/out/$buildtype/obj/gen/protoc_out/instaweb \
$mod_pagespeed_dir/third_party/apr/src/include \
$mod_pagespeed_dir/third_party/aprutil/src/include \
$mod_pagespeed_dir/third_party/apr/gen/arch/$os_name/$arch_name/include \
@@ -139,34 +168,36 @@ if [ $ngx_found = yes ]; then
ps_src="$ngx_addon_dir/src"
ngx_addon_name=ngx_pagespeed
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ps_src/ngx_pagespeed.h \
$ps_src/ngx_fetch.h \
$ps_src/ngx_url_async_fetcher.h \
$ps_src/log_message_handler.h \
$ps_src/ngx_base_fetch.h \
$ps_src/ngx_server_context.h \
$ps_src/ngx_rewrite_options.h \
$ps_src/ngx_rewrite_driver_factory.h \
$ps_src/ngx_thread_system.h \
$ps_src/ngx_caching_headers.h \
$ps_src/ngx_fetch.h \
$ps_src/ngx_list_iterator.h \
$ps_src/ngx_message_handler.h \
$ps_src/pthread_shared_mem.h \
$ps_src/ngx_request_context.h \
$ps_src/log_message_handler.h"
$ps_src/ngx_pagespeed.h \
$ps_src/ngx_rewrite_driver_factory.h \
$ps_src/ngx_rewrite_options.h \
$ps_src/ngx_server_context.h \
$ps_src/ngx_url_async_fetcher.h"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ps_src/log_message_handler.cc \
$ps_src/ngx_base_fetch.cc \
$ps_src/ngx_caching_headers.cc \
$ps_src/ngx_fetch.cc \
$ps_src/ngx_list_iterator.cc \
$ps_src/ngx_message_handler.cc \
$ps_src/ngx_pagespeed.cc \
$ps_src/ngx_rewrite_driver_factory.cc \
$ps_src/ngx_rewrite_options.cc \
$ps_src/ngx_server_context.cc \
$ps_src/ngx_fetch.cc \
$ps_src/ngx_url_async_fetcher.cc \
$ps_src/ngx_base_fetch.cc \
$ps_src/ngx_thread_system.cc \
$ps_src/ngx_message_handler.cc \
$ps_src/pthread_shared_mem.cc \
$ps_src/ngx_request_context.cc \
$ps_src/log_message_handler.cc \
$mod_pagespeed_dir/net/instaweb/apache/add_headers_fetcher.cc \
$mod_pagespeed_dir/net/instaweb/apache/loopback_route_fetcher.cc \
$mod_pagespeed_dir/net/instaweb/apache/serf_url_async_fetcher.cc"
$mod_pagespeed_dir/out/$buildtype/obj/gen/data2c_out/instaweb/net/instaweb/apache/install/mod_pagespeed_example/mod_pagespeed_console_out.cc \
$mod_pagespeed_dir/out/$buildtype/obj/gen/data2c_out/instaweb/net/instaweb/apache/install/mod_pagespeed_example/mod_pagespeed_console_css_out.cc \
$mod_pagespeed_dir/out/$buildtype/obj/gen/data2c_out/instaweb/net/instaweb/apache/install/mod_pagespeed_example/mod_pagespeed_console_html_out.cc \
$mod_pagespeed_dir/net/instaweb/system/add_headers_fetcher.cc \
$mod_pagespeed_dir/net/instaweb/system/loopback_route_fetcher.cc \
$mod_pagespeed_dir/net/instaweb/system/serf_url_async_fetcher.cc"
# Make pagespeed run immediately before gzip.
HTTP_FILTER_MODULES=$(echo $HTTP_FILTER_MODULES |\
sed "s/$HTTP_GZIP_FILTER_MODULE/$HTTP_GZIP_FILTER_MODULE $ngx_addon_name/")
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
#
# Converts pagespeed_libraries.conf from Apache-format to Nginx-format,
# supporting the canonicalize_javascript_libraries filter.
# Inspired by https://github.com/pagespeed/ngx_pagespeed/issues/532
#
# Usage:
# scripts/pagespeed_libraries_generator.sh > pagespeed_libraries.conf
#
# Then have nginx include that configuration file and enable the filter
# canonicalize_javascript_libraries.
#
# Author: vid@zippykid.com (Vid Luther)
# jefftk@google.com (Jeff Kaufman)
URL="https://modpagespeed.googlecode.com/svn/trunk/src/"
URL+="net/instaweb/genfiles/conf/pagespeed_libraries.conf"
curl -s "$URL" \
| grep ModPagespeedLibrary \
| while read library size hash url ; do
echo " pagespeed Library $size $hash $url;"
done
+5
View File
@@ -63,11 +63,16 @@ rsync -arvz "$MOD_PAGESPEED_SRC/" "psol/include/" --prune-empty-dirs \
--include="apr_memcache2.c" \
--include="loopback_route_fetcher.cc" \
--include="add_headers_fetcher.cc" \
--include="console_css_out.cc" \
--include="console_out.cc" \
--include="dense_hash_map" \
--include="dense_hash_set" \
--include="sparse_hash_map" \
--include="sparse_hash_set" \
--include="sparsetable" \
--include="mod_pagespeed_console_out.cc" \
--include="mod_pagespeed_console_css_out.cc" \
--include="mod_pagespeed_console_html_out.cc" \
--exclude='*'
mkdir -p psol/lib/Debug/linux/ia32
mkdir -p psol/lib/Debug/linux/x64
-2
View File
@@ -98,8 +98,6 @@ namespace net_instaweb {
namespace log_message_handler {
const int kDebugLogLevel = -2;
void Install(ngx_log_t* log_in) {
log = log_in;
logging::SetLogMessageHandler(&LogMessageHandler);
+36 -71
View File
@@ -17,6 +17,7 @@
// Author: jefftk@google.com (Jeff Kaufman)
#include "ngx_base_fetch.h"
#include "ngx_list_iterator.h"
#include "ngx_pagespeed.h"
@@ -29,16 +30,18 @@ namespace net_instaweb {
NgxBaseFetch::NgxBaseFetch(ngx_http_request_t* r, int pipe_fd,
NgxServerContext* server_context,
const RequestContextPtr& request_ctx)
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers)
: AsyncFetch(request_ctx),
request_(r),
server_context_(server_context),
done_called_(false),
last_buf_sent_(false),
pipe_fd_(pipe_fd),
references_(2) {
references_(2),
handle_error_(true),
preserve_caching_headers_(preserve_caching_headers) {
if (pthread_mutex_init(&mutex_, NULL)) CHECK(0);
PopulateRequestHeaders();
}
NgxBaseFetch::~NgxBaseFetch() {
@@ -53,58 +56,6 @@ void NgxBaseFetch::Unlock() {
pthread_mutex_unlock(&mutex_);
}
void NgxBaseFetch::PopulateRequestHeaders() {
CopyHeadersFromTable<RequestHeaders>(&request_->headers_in.headers,
request_headers());
}
void NgxBaseFetch::PopulateResponseHeaders() {
CopyHeadersFromTable<ResponseHeaders>(&request_->headers_out.headers,
response_headers());
response_headers()->set_status_code(request_->headers_out.status);
// Manually copy over the content type because it's not included in
// request_->headers_out.headers.
response_headers()->Add(
HttpAttributes::kContentType,
ngx_psol::str_to_string_piece(request_->headers_out.content_type));
// TODO(oschaaf): ComputeCaching should be called in setupforhtml()?
response_headers()->ComputeCaching();
}
template<class HeadersT>
void NgxBaseFetch::CopyHeadersFromTable(ngx_list_t* headers_from,
HeadersT* headers_to) {
// http_version is the version number of protocol; 1.1 = 1001. See
// NGX_HTTP_VERSION_* in ngx_http_request.h
headers_to->set_major_version(request_->http_version / 1000);
headers_to->set_minor_version(request_->http_version % 1000);
// Standard nginx idiom for iterating over a list. See ngx_list.h
ngx_uint_t i;
ngx_list_part_t* part = &headers_from->part;
ngx_table_elt_t* header = static_cast<ngx_table_elt_t*>(part->elts);
for (i = 0 ; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = static_cast<ngx_table_elt_t*>(part->elts);
i = 0;
}
StringPiece key = ngx_psol::str_to_string_piece(header[i].key);
StringPiece value = ngx_psol::str_to_string_piece(header[i].value);
headers_to->Add(key, value);
}
}
bool NgxBaseFetch::HandleWrite(const StringPiece& sp,
MessageHandler* handler) {
Lock();
@@ -113,12 +64,18 @@ bool NgxBaseFetch::HandleWrite(const StringPiece& sp,
return true;
}
// should only be called in nginx thread
ngx_int_t NgxBaseFetch::CopyBufferToNginx(ngx_chain_t** link_ptr) {
if (done_called_ && last_buf_sent_) {
return NGX_DECLINED;
CHECK(!(done_called_ && last_buf_sent_))
<< "CopyBufferToNginx() was called after the last buffer was sent";
// there is no buffer to send
if (!done_called_ && buffer_.empty()) {
*link_ptr = NULL;
return NGX_AGAIN;
}
int rc = ngx_psol::string_piece_to_buffer_chain(
int rc = string_piece_to_buffer_chain(
request_->pool, buffer_, link_ptr, done_called_ /* send_last_buf */);
if (rc != NGX_OK) {
return rc;
@@ -129,31 +86,34 @@ ngx_int_t NgxBaseFetch::CopyBufferToNginx(ngx_chain_t** link_ptr) {
if (done_called_) {
last_buf_sent_ = true;
return NGX_OK;
}
return NGX_OK;
return NGX_AGAIN;
}
// There may also be a race condition if this is called between the last Write()
// and Done() such that we're sending an empty buffer with last_buf set, which I
// think nginx will reject.
ngx_int_t NgxBaseFetch::CollectAccumulatedWrites(ngx_chain_t** link_ptr) {
ngx_int_t rc;
Lock();
ngx_int_t rc = CopyBufferToNginx(link_ptr);
rc = CopyBufferToNginx(link_ptr);
Unlock();
if (rc == NGX_DECLINED) {
*link_ptr = NULL;
return NGX_OK;
}
return rc;
}
ngx_int_t NgxBaseFetch::CollectHeaders(ngx_http_headers_out_t* headers_out) {
Lock();
const ResponseHeaders* pagespeed_headers = response_headers();
Unlock();
return ngx_psol::copy_response_headers_to_ngx(request_, *pagespeed_headers);
// TODO(chaizhenhua): Add and check.
// if (content_length_known()) {
// headers_out->content_length = NULL;
// headers_out->content_length_n = content_length();
// }
return copy_response_headers_to_ngx(request_, *pagespeed_headers,
preserve_caching_headers_);
}
void NgxBaseFetch::RequestCollection() {
@@ -175,9 +135,14 @@ void NgxBaseFetch::RequestCollection() {
}
void NgxBaseFetch::HandleHeadersComplete() {
// 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);
int status_code = response_headers()->status_code();
bool status_ok = (status_code != 0) && (status_code < 400);
if (status_ok || handle_error_) {
// 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.
+8 -13
View File
@@ -57,15 +57,10 @@ class NgxBaseFetch : public AsyncFetch {
public:
NgxBaseFetch(ngx_http_request_t* r, int pipe_fd,
NgxServerContext* server_context,
const RequestContextPtr& request_ctx);
const RequestContextPtr& request_ctx,
PreserveCachingHeaders preserve_caching_headers);
virtual ~NgxBaseFetch();
// Copies the request headers out of request_->headers_in->headers.
void PopulateRequestHeaders();
// Copies the response headers out of request_->headers_out->headers.
void PopulateResponseHeaders();
// 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
@@ -84,6 +79,7 @@ class NgxBaseFetch : public AsyncFetch {
// Called by nginx when it's done with us.
void Release();
void set_handle_error(bool x) { handle_error_ = x; }
private:
virtual bool HandleWrite(const StringPiece& sp, MessageHandler* handler);
@@ -91,18 +87,15 @@ class NgxBaseFetch : public AsyncFetch {
virtual void HandleHeadersComplete();
virtual void HandleDone(bool success);
// Helper method for PopulateRequestHeaders and PopulateResponseHeaders.
template<class HeadersT>
void CopyHeadersFromTable(ngx_list_t* headers_from, HeadersT* headers_to);
// Indicate to nginx that we would like it to call
// CollectAccumulatedWrites().
void RequestCollection();
// Lock must be acquired first.
// Returns:
// NGX_DECLINED: nothing to send, short circuit. Buffer not allocated.
// NGX_OK, NGX_ERROR: success, failure
// NGX_ERROR: failure
// NGX_AGAIN: still has buffer to send, need to checkout link_ptr
// NGX_OK: done, HandleDone has been called
// Allocates an nginx buffer, copies our buffer_ contents into it, clears
// buffer_.
ngx_int_t CopyBufferToNginx(ngx_chain_t** link_ptr);
@@ -124,6 +117,8 @@ class NgxBaseFetch : public AsyncFetch {
// decremented once when Done() is called and once when Release() is called.
int references_;
pthread_mutex_t mutex_;
bool handle_error_;
PreserveCachingHeaders preserve_caching_headers_;
DISALLOW_COPY_AND_ASSIGN(NgxBaseFetch);
};
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: jefftk@google.com (Jeff Kaufman)
#include "ngx_caching_headers.h"
#include "ngx_list_iterator.h"
#include "ngx_pagespeed.h"
namespace net_instaweb {
bool NgxCachingHeaders::Lookup(const StringPiece& key,
StringPieceVector* values) {
ngx_table_elt_t* header;
NgxListIterator it(&(request_->headers_out.headers.part));
while ((header = it.Next()) != NULL) {
if (header->hash != 0 && key == str_to_string_piece(header->key)) {
// This will be called multiple times if there are multiple headers with
// this name. Each time it will append to values.
SplitStringPieceToVector(str_to_string_piece(header->value), ",", values,
true /* omit empty strings */);
}
}
if (values->size() == 0) {
// No header found with this name.
return false;
}
for (int i = 0, n = values->size(); i < n; ++i) {
TrimWhitespace(&((*values)[i]));
}
return true;
}
} // namespace net_instaweb
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: jefftk@google.com (Jeff Kaufman)
#ifndef NGX_CACHING_HEADERS_H_
#define NGX_CACHING_HEADERS_H_
extern "C" {
#include <ngx_http.h>
}
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/http/caching_headers.h"
namespace net_instaweb {
// Based off of ApacheCachingHeaders in net/instaweb/apache/header_util.cc
// Needed so ps_header_filter can call GenerateDisabledCacheControl().
class NgxCachingHeaders : public CachingHeaders {
public:
explicit NgxCachingHeaders(ngx_http_request_t* request)
: CachingHeaders(request->headers_out.status),
request_(request) {
}
virtual bool Lookup(const StringPiece& key, StringPieceVector* values);
virtual bool IsLikelyStaticResourceType() const {
DCHECK(false); // not called in our use-case.
return false;
}
virtual bool IsCacheableResourceStatusCode() const {
DCHECK(false); // not called in our use-case.
return false;
}
private:
ngx_http_request_t* request_;
DISALLOW_COPY_AND_ASSIGN(NgxCachingHeaders);
};
} // namespace net_instaweb
#endif // NGX_CACHING_HEADERS_H_
+28 -7
View File
@@ -24,6 +24,10 @@
// - The read handler parses the response. Add the response to the buffer at
// last.
extern "C" {
#include <nginx.h>
}
#include "ngx_fetch.h"
#include "net/instaweb/util/public/basictypes.h"
#include "base/logging.h"
@@ -164,7 +168,11 @@ namespace net_instaweb {
resolver_ctx_->data = this;
resolver_ctx_->name.data = url_.host.data;
resolver_ctx_->name.len = url_.host.len;
#if (nginx_version < 1005008)
resolver_ctx_->type = NGX_RESOLVE_A;
#endif
resolver_ctx_->handler = NgxFetchResolveDone;
resolver_ctx_->timeout = fetcher_->resolver_timeout_;
@@ -273,9 +281,7 @@ namespace net_instaweb {
url_.url.data += scheme_offset;
url_.url.len -= scheme_offset;
url_.default_port = port;
// TODO(oschaaf): no_resolve was set to 0, which is why url_.port
// would always be '0' after parsing it. See:
// http://lxr.evanmiller.org/http/source/core/ngx_inet.c#L875
// See: http://lxr.evanmiller.org/http/source/core/ngx_inet.c#L875
url_.no_resolve = 0;
url_.uri_part = 1;
@@ -301,9 +307,20 @@ namespace net_instaweb {
return;
}
ngx_memzero(&fetch->sin_, sizeof(fetch->sin_));
#if (nginx_version < 1005008)
fetch->sin_.sin_addr.s_addr = resolver_ctx->addrs[0];
#else
struct sockaddr_in *sin;
sin = reinterpret_cast<struct sockaddr_in *>(
resolver_ctx->addrs[0].sockaddr);
fetch->sin_.sin_family = sin->sin_family;
fetch->sin_.sin_addr.s_addr = sin->sin_addr.s_addr;
#endif
fetch->sin_.sin_family = AF_INET;
fetch->sin_.sin_port = htons(fetch->url_.port);
fetch->sin_.sin_addr.s_addr = resolver_ctx->addrs[0];
char* ip_address = inet_ntoa(fetch->sin_.sin_addr);
@@ -413,12 +430,16 @@ namespace net_instaweb {
pc.rcvbuf = -1;
int rc = ngx_event_connect_peer(&pc);
if (rc == NGX_ERROR || rc == NGX_DECLINED || rc == NGX_BUSY) {
return rc;
}
connection_ = pc.connection;
connection_->write->handler = NgxFetchWrite;
connection_->read->handler = NgxFetchRead;
connection_->data = this;
// TODO(junmin): set connect timeout when rc == NGX_AGAIN
// Timer set in Init() is still in effect.
return rc;
}
@@ -434,10 +455,10 @@ namespace net_instaweb {
if (n >= 0) {
out->pos += n;
} else if (n == NGX_AGAIN) {
// TODO(junmin): set write event timeout
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
fetch->CallbackDone(false);
}
// Timer set in Init() is still in effect.
return;
} else {
c->error = 1;
@@ -499,7 +520,7 @@ namespace net_instaweb {
fetch->CallbackDone(false);
}
// TODO(junmin): set read event timeout
// Timer set in Init() is still in effect.
}
// Parse the status line: "HTTP/1.1 200 OK\r\n"
+102 -106
View File
@@ -16,18 +16,16 @@
// Author: x.dinic@gmail.com (Junmin Xiong)
//
// The fetch is started by the main thread. It will fetch the remote resource
// from the specific url asynchronously.
// The fetch is started by the main thread. It will fetch the remote resource
// from the specific url asynchronously.
#ifndef NET_INSTAWEB_NGX_FETCHER_H_
#define NET_INSTAWEB_NGX_FETCHER_H_
#ifndef NET_INSTAWEB_NGX_FETCH_H_
#define NET_INSTAWEB_NGX_FETCH_H_
extern "C" {
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef bool (*response_handler_pt)(ngx_connection_t* c);
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
}
#include "ngx_url_async_fetcher.h"
@@ -35,117 +33,115 @@ extern "C" {
#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_pollable_async_fetcher.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"
namespace net_instaweb {
class NgxUrlAsyncFetcher;
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();
// Start the fetch
bool Start(NgxUrlAsyncFetcher* fetcher);
// Show the completed url, for logging purpose
const char* str_url();
// This fetch task is done. Call the done of async_fetch.
// It will copy the buffer to cache.
void CallbackDone(bool success);
typedef bool (*response_handler_pt)(ngx_connection_t* c);
// Show the bytes received
size_t bytes_received();
void bytes_received_add(int64 x);
int64 fetch_start_ms();
void set_fetch_start_ms(int64 start_ms);
int64 fetch_end_ms();
void set_fetch_end_ms(int64 end_ms);
MessageHandler* message_handler();
int get_major_version() {
return static_cast<int>(status_->http_version / 1000);
}
class NgxUrlAsyncFetcher;
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();
int get_minor_version() {
return static_cast<int>(status_->http_version % 1000);
}
// Start the fetch.
bool Start(NgxUrlAsyncFetcher* fetcher);
// Show the completed url, for logging purposes.
const char* str_url();
// This fetch task is done. Call Done() on the async_fetch. It will copy the
// buffer to cache.
void CallbackDone(bool success);
int get_status_code() {
return static_cast<int>(status_->code);
}
// Show the bytes received.
size_t bytes_received();
void bytes_received_add(int64 x);
int64 fetch_start_ms();
void set_fetch_start_ms(int64 start_ms);
int64 fetch_end_ms();
void set_fetch_end_ms(int64 end_ms);
MessageHandler* message_handler();
ngx_event_t* timeout_event() {
return timeout_event_;
};
void set_timeout_event(ngx_event_t* x) {
timeout_event_ = x;
};
int get_major_version() {
return static_cast<int>(status_->http_version / 1000);
}
int get_minor_version() {
return static_cast<int>(status_->http_version % 1000);
}
int get_status_code() {
return static_cast<int>(status_->code);
}
ngx_event_t* timeout_event() {
return timeout_event_;
}
void set_timeout_event(ngx_event_t* x) {
timeout_event_ = x;
}
private:
response_handler_pt response_handler;
// Do the initialized work and start the resolver work.
bool Init();
bool ParseUrl();
// Prepare the request and write it to remote server.
int InitRequest();
// Create the connection with remote server.
int Connect();
void set_response_handler(response_handler_pt handler) {
response_handler = handler;
}
// Only the Static functions could be used in callbacks.
static void NgxFetchResolveDone(ngx_resolver_ctx_t* ctx);
private:
response_handler_pt response_handler;
// Do the initialized work and start the resolver work.
bool Init();
bool ParseUrl();
// Prepare the request and write it to remote server.
int InitRequest();
// Create the connection with remote server.
int Connect();
void set_response_handler(response_handler_pt handler) {
response_handler = handler;
}
// Only the Static functions could be used in callbacks.
static void NgxFetchResolveDone(ngx_resolver_ctx_t* ctx);
// Write the request.
static void NgxFetchWrite(ngx_event_t* wev);
// Wait for the response.
static void NgxFetchRead(ngx_event_t* rev);
// Read and parse the first status line.
static bool NgxFetchHandleStatusLine(ngx_connection_t* c);
// Read and parse the HTTP headers.
static bool NgxFetchHandleHeader(ngx_connection_t* c);
// Read the response body.
static bool NgxFetchHandleBody(ngx_connection_t* c);
// Cancel the fetch when it's timeout.
static void NgxFetchTimeout(ngx_event_t* tev);
// Write the request
static void NgxFetchWrite(ngx_event_t* wev);
// Add the pagespeed User-Agent.
void FixUserAgent();
void FixHost();
// Wait for the response
static void NgxFetchRead(ngx_event_t* rev);
// Read and parse the first status line
static bool NgxFetchHandleStatusLine(ngx_connection_t* c);
// Read and parse the HTTP headers
static bool NgxFetchHandleHeader(ngx_connection_t* c);
// Read the response body
static bool NgxFetchHandleBody(ngx_connection_t* c);
const GoogleString str_url_;
ngx_url_t url_;
NgxUrlAsyncFetcher* fetcher_;
AsyncFetch* async_fetch_;
ResponseHeadersParser parser_;
MessageHandler* message_handler_;
size_t bytes_received_;
int64 fetch_start_ms_;
int64 fetch_end_ms_;
int64 timeout_ms_;
bool done_;
int64 content_length_;
// Cancel the fetch when it's timeout
static void NgxFetchTimeout(ngx_event_t* tev);
struct sockaddr_in sin_;
ngx_log_t* log_;
ngx_buf_t* out_;
ngx_buf_t* in_;
ngx_pool_t* pool_;
ngx_http_request_t* r_;
ngx_http_status_t* status_;
ngx_event_t* timeout_event_;
ngx_connection_t* connection_;
ngx_resolver_ctx_t* resolver_ctx_;
// Add the pagespeed User-Agent
void FixUserAgent();
void FixHost();
const GoogleString str_url_;
ngx_url_t url_;
NgxUrlAsyncFetcher* fetcher_;
AsyncFetch* async_fetch_;
ResponseHeadersParser parser_;
MessageHandler* message_handler_;
size_t bytes_received_;
int64 fetch_start_ms_;
int64 fetch_end_ms_;
int64 timeout_ms_;
bool done_;
int64 content_length_;
struct sockaddr_in sin_;
ngx_log_t* log_;
ngx_buf_t* out_;
ngx_buf_t* in_;
ngx_pool_t* pool_;
ngx_http_request_t* r_;
ngx_http_status_t* status_;
ngx_event_t* timeout_event_;
ngx_connection_t* connection_;
ngx_resolver_ctx_t* resolver_ctx_;
DISALLOW_COPY_AND_ASSIGN(NgxFetch);
};
DISALLOW_COPY_AND_ASSIGN(NgxFetch);
};
} // namespace net_instaweb
#endif // NET_INSTAWEB_NGX_FETCHER_H_
#endif // NET_INSTAWEB_NGX_FETCH_H_
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: jefftk@google.com (Jeff Kaufman)
#include "ngx_list_iterator.h"
namespace net_instaweb {
NgxListIterator::NgxListIterator(ngx_list_part_t* part) :
part_(part),
index_within_part_(0) {}
ngx_table_elt_t* NgxListIterator::Next() {
if (index_within_part_ >= part_->nelts) {
if (part_->next == NULL) {
return NULL;
}
part_ = part_->next;
index_within_part_ = 0;
}
ngx_table_elt_t* elts = static_cast<ngx_table_elt_t*>(part_->elts);
return &elts[index_within_part_++]; // Intentional post-increment.
}
} // namespace net_instaweb
@@ -15,32 +15,36 @@
*/
// Author: jefftk@google.com (Jeff Kaufman)
//
// Simplifies iteration over nginx lists.
//
//
#include "ngx_thread_system.h"
#ifndef NGX_LIST_ITERATOR_H_
#define NGX_LIST_ITERATOR_H_
#include "apr_thread_proc.h"
extern "C" {
#include <ngx_http.h>
}
#include "base/basictypes.h"
namespace net_instaweb {
class Timer;
class NgxListIterator {
public:
explicit NgxListIterator(ngx_list_part_t* part);
NgxThreadSystem::NgxThreadSystem() : may_start_threads_(false) {}
// Return the next element of the list if there is one, NULL otherwise.
ngx_table_elt_t* Next();
NgxThreadSystem::~NgxThreadSystem() {}
private:
ngx_list_part_t* part_;
ngx_uint_t index_within_part_;
void NgxThreadSystem::PermitThreadStarting() {
CHECK(!may_start_threads_);
may_start_threads_ = true;
}
void NgxThreadSystem::BeforeThreadRunHook() {
// We disable all signals here, since the nginx worker process is expecting to
// catch them and pagespeed doesn't use signals.
apr_setup_signal_thread();
// If this fails you can get a backtrace from gdb by setting a breakpoint on
// "pthread_create".
CHECK(may_start_threads_);
}
DISALLOW_COPY_AND_ASSIGN(NgxListIterator);
};
} // namespace net_instaweb
#endif // NGX_LIST_ITERATOR_H_
+1
View File
@@ -54,6 +54,7 @@ class NgxMessageHandler : public GoogleMessageHandler {
// Messages logged before that will be passed on to handler_;
void set_buffer(SharedCircularBuffer* buff);
void set_log(ngx_log_t* log) { log_ = log; }
ngx_log_t* log() { return log_; }
void SetPidString(const int64 pid) {
pid_string_ = StrCat("[", Integer64ToString(pid), "]");
+1226 -1133
View File
File diff suppressed because it is too large Load Diff
+40 -16
View File
@@ -43,10 +43,9 @@ class GzipInflater;
class NgxBaseFetch;
class ProxyFetch;
class RewriteDriver;
} // namespace net_instaweb
namespace ngx_psol {
class RequestHeaders;
class ResponseHeaders;
class InPlaceResourceRecorder;
// Allocate chain links and buffers from the supplied pool, and copy over the
// data from the string piece. If the string piece is empty, return
@@ -75,24 +74,49 @@ StringPiece str_to_string_piece(ngx_str_t s);
// Allocate memory out of the pool for the string piece, and copy the contents
// over. Returns NULL if we can't get memory.
char* string_piece_to_pool_string(ngx_pool_t* pool, StringPiece sp);
ngx_int_t copy_response_headers_to_ngx(
ngx_http_request_t* r,
const net_instaweb::ResponseHeaders& pagespeed_headers);
enum PreserveCachingHeaders {
kPreserveAllCachingHeaders, // Cache-Control, ETag, Last-Modified, etc
kPreserveOnlyCacheControl, // Only Cache-Control.
kDontPreserveHeaders,
};
typedef struct {
net_instaweb::ProxyFetch* proxy_fetch;
net_instaweb::NgxBaseFetch* base_fetch;
net_instaweb::RewriteDriver* driver;
bool data_received;
int pipe_fd;
NgxBaseFetch* base_fetch;
ngx_connection_t* pagespeed_connection;
ngx_http_request_t* r;
bool is_resource_fetch;
bool sent_headers;
bool html_rewrite;
bool in_place;
bool write_pending;
net_instaweb::GzipInflater* inflater_;
bool fetch_done;
PreserveCachingHeaders preserve_caching_headers;
// for html rewrite
ProxyFetch* proxy_fetch;
GzipInflater* inflater_;
// for in place resource
RewriteDriver* driver;
InPlaceResourceRecorder* recorder;
ResponseHeaders* ipro_response_headers;
} ps_request_ctx_t;
} // namespace ngx_psol
void copy_request_headers_from_ngx(const ngx_http_request_t* r,
RequestHeaders* headers);
void copy_response_headers_from_ngx(const ngx_http_request_t* r,
ResponseHeaders* headers);
ngx_int_t copy_response_headers_to_ngx(
ngx_http_request_t* r,
const ResponseHeaders& pagespeed_headers,
PreserveCachingHeaders preserve_caching_headers);
} // namespace net_instaweb
#endif // NGX_PAGESPEED_H_
-82
View File
@@ -1,82 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ngx_request_context.h"
extern "C" {
#include <ngx_http.h>
}
#include "ngx_pagespeed.h"
#include "base/logging.h"
#include "net/instaweb/http/public/meta_data.h"
namespace net_instaweb {
NgxRequestContext::NgxRequestContext(AbstractMutex* logging_mutex,
Timer* timer,
ngx_http_request_t* r)
: RequestContext(logging_mutex, timer),
local_port_(-1) {
// Note that at the time we create a RequestContext we have full
// access to the nginx internal request structure. However,
// due to Cloning and (I believe) Detaching, we can initiate fetches after
// http_http_request_t* has been retired. So deep-copy the bits we need
// at the time we create our RequestContext.
// Save our own IP as well, LoopbackRouteFetcher will need it.
// Based on ngx_http_variable_server_port.
bool port_set = false;
#if (NGX_HAVE_INET6)
if (r->connection->local_sockaddr->sa_family == AF_INET6) {
local_port_ = ntohs(reinterpret_cast<struct sockaddr_in6*>(
r->connection->local_sockaddr)->sin6_port);
port_set = true;
}
#endif
if (!port_set) {
local_port_ = ntohs(reinterpret_cast<struct sockaddr_in*>(
r->connection->local_sockaddr)->sin_port);
}
ngx_str_t s;
u_char addr[NGX_SOCKADDR_STRLEN];
s.len = NGX_SOCKADDR_STRLEN;
s.data = addr;
ngx_int_t rc = ngx_connection_local_sockaddr(r->connection, &s, 0);
if (rc != NGX_OK) {
s.len = 0;
}
local_ip_ = ngx_psol::str_to_string_piece(s).as_string();
}
NgxRequestContext::~NgxRequestContext() {
}
NgxRequestContext* NgxRequestContext::DynamicCast(RequestContext* rc) {
if (rc == NULL) {
return NULL;
}
NgxRequestContext* out = dynamic_cast<NgxRequestContext*>(rc);
DCHECK(out != NULL) << "Invalid request conversion. Do not rely on RTTI for "
<< "functional behavior. Ngx handling flows must use "
<< "NgxRequestContexts.";
return out;
}
} // namespace net_instaweb
-64
View File
@@ -1,64 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: oschaaf@google.com (Otto van der Schaaf)
//
// I tried to keep this as close to ApacheRequestContext as possible.
// Captures the NGINX request details in our request context, including
// the port (used for loopback fetches).
#ifndef NGX_REQUEST_CONTEXT_H_
#define NGX_REQUEST_CONTEXT_H_
#include "ngx_pagespeed.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"
namespace net_instaweb {
class AbstractMutex;
class Timer;
class NgxRequestContext : public RequestContext {
public:
NgxRequestContext(AbstractMutex* logging_mutex,
Timer* timer,
ngx_http_request_t* ps_request_context);
// Returns rc as an NgxRequestContext* if it is one and CHECK
// fails if it is not. Returns NULL if rc is NULL.
static NgxRequestContext* DynamicCast(RequestContext* rc);
int local_port() const { return local_port_; }
const GoogleString& local_ip() const { return local_ip_; }
protected:
virtual ~NgxRequestContext();
private:
int local_port_;
GoogleString local_ip_;
DISALLOW_COPY_AND_ASSIGN(NgxRequestContext);
};
} // namespace net_instaweb
#endif // NGX_REQUEST_CONTEXT_H_
+61 -207
View File
@@ -24,25 +24,25 @@
#include "ngx_message_handler.h"
#include "ngx_rewrite_options.h"
#include "ngx_server_context.h"
#include "ngx_thread_system.h"
#include "ngx_url_async_fetcher.h"
#include "pthread_shared_mem.h"
#include "net/instaweb/apache/serf_url_async_fetcher.h"
#include "net/instaweb/http/public/content_type.h"
#include "net/instaweb/http/public/fake_url_async_fetcher.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/rewriter/public/static_asset_manager.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/posix_timer.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"
@@ -50,6 +50,7 @@
#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/thread/pthread_shared_mem.h"
namespace net_instaweb {
@@ -65,33 +66,23 @@ class Writer;
const char NgxRewriteDriverFactory::kStaticAssetPrefix[] =
"/ngx_pagespeed_static/";
namespace {
const char kShutdownCount[] = "child_shutdown_count";
} // namespace
class SharedCircularBuffer;
NgxRewriteDriverFactory::NgxRewriteDriverFactory(
NgxThreadSystem* ngx_thread_system)
: SystemRewriteDriverFactory(ngx_thread_system),
ngx_thread_system_(ngx_thread_system),
// TODO(oschaaf): mod_pagespeed ifdefs this:
shared_mem_runtime_(new ngx::PthreadSharedMem()),
SystemThreadSystem* system_thread_system, StringPiece hostname, int port)
: SystemRewriteDriverFactory(system_thread_system,
NULL /* default shared memory runtime */, hostname, port),
main_conf_(NULL),
threads_started_(false),
use_per_vhost_statistics_(false),
is_root_process_(true),
ngx_message_handler_(new NgxMessageHandler(thread_system()->NewMutex())),
ngx_html_parse_message_handler_(
new NgxMessageHandler(thread_system()->NewMutex())),
install_crash_handler_(false),
message_buffer_size_(0),
shared_circular_buffer_(NULL),
statistics_frozen_(false),
ngx_url_async_fetcher_(NULL),
log_(NULL),
resolver_timeout_(NGX_CONF_UNSET_MSEC),
use_native_fetcher_(false) {
use_native_fetcher_(false),
ngx_shared_circular_buffer_(NULL) {
InitializeDefaultOptions();
default_options()->set_beacon_url("/ngx_pagespeed_beacon");
SystemRewriteOptions* system_options = dynamic_cast<SystemRewriteOptions*>(
@@ -100,61 +91,33 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
system_options->set_avoid_renaming_introspective_javascript(true);
set_message_handler(ngx_message_handler_);
set_html_parse_message_handler(ngx_html_parse_message_handler_);
// see https://code.google.com/p/modpagespeed/issues/detail?id=672
int thread_limit = 1;
caches_.reset(
new SystemCaches(this, shared_mem_runtime_.get(), thread_limit));
}
NgxRewriteDriverFactory::~NgxRewriteDriverFactory() {
ShutDown();
CHECK(uninitialized_server_contexts_.empty() || is_root_process_);
ngx_shared_circular_buffer_ = NULL;
STLDeleteElements(&uninitialized_server_contexts_);
shared_mem_statistics_.reset(NULL);
}
Hasher* NgxRewriteDriverFactory::NewHasher() {
return new MD5Hasher;
}
UrlFetcher* NgxRewriteDriverFactory::DefaultUrlFetcher() {
CHECK(false) << "Nothing should still be using DefaultUrlFetcher()";
return NULL;
}
UrlAsyncFetcher* NgxRewriteDriverFactory::DefaultAsyncUrlFetcher() {
const char* fetcher_proxy = "";
if (main_conf_ != NULL) {
fetcher_proxy = main_conf_->fetcher_proxy().c_str();
}
UrlAsyncFetcher* NgxRewriteDriverFactory::AllocateFetcher(
SystemRewriteOptions* config) {
if (use_native_fetcher_) {
net_instaweb::NgxUrlAsyncFetcher* fetcher =
new net_instaweb::NgxUrlAsyncFetcher(
fetcher_proxy,
log_,
resolver_timeout_,
25000,
resolver_,
thread_system(),
message_handler());
ngx_url_async_fetcher_ = fetcher;
NgxUrlAsyncFetcher* fetcher = new NgxUrlAsyncFetcher(
config->fetcher_proxy().c_str(),
log_,
resolver_timeout_,
config->blocking_fetch_timeout_ms(),
resolver_,
thread_system(),
message_handler());
ngx_url_async_fetchers_.push_back(fetcher);
return fetcher;
} else {
net_instaweb::SerfUrlAsyncFetcher* fetcher =
new net_instaweb::SerfUrlAsyncFetcher(
fetcher_proxy,
NULL,
thread_system(),
statistics(),
timer(),
2500,
message_handler());
// Make sure we don't block the nginx event loop
fetcher->set_force_threaded(true);
return fetcher;
return SystemRewriteDriverFactory::AllocateFetcher(config);
}
}
@@ -179,43 +142,25 @@ NamedLockManager* NgxRewriteDriverFactory::DefaultLockManager() {
return NULL;
}
void NgxRewriteDriverFactory::SetupCaches(ServerContext* server_context) {
caches_->SetupCaches(server_context);
server_context->set_enable_property_cache(true);
PropertyCache* pcache = server_context->page_property_cache();
if (pcache->GetCohort(RewriteDriver::kBeaconCohort) == NULL) {
pcache->AddCohort(RewriteDriver::kBeaconCohort);
}
if (pcache->GetCohort(RewriteDriver::kDomCohort) == NULL) {
pcache->AddCohort(RewriteDriver::kDomCohort);
}
}
RewriteOptions* NgxRewriteDriverFactory::NewRewriteOptions() {
NgxRewriteOptions* options = new NgxRewriteOptions();
NgxRewriteOptions* options = new NgxRewriteOptions(thread_system());
options->SetRewriteLevel(RewriteOptions::kCoreFilters);
return options;
}
void NgxRewriteDriverFactory::InitStaticAssetManager(
StaticAssetManager* static_asset_manager) {
static_asset_manager->set_library_url_prefix(kStaticAssetPrefix);
}
void NgxRewriteDriverFactory::PrintMemCacheStats(GoogleString* out) {
// TODO(morlovich): Port the client code to proper API, so it gets
// shm stats, too.
caches_->PrintCacheStats(SystemCaches::kIncludeMemcached, out);
}
bool NgxRewriteDriverFactory::InitNgxUrlAsyncFetcher() {
if (ngx_url_async_fetcher_ == NULL) {
return true;
}
bool NgxRewriteDriverFactory::InitNgxUrlAsyncFetchers() {
log_ = ngx_cycle->log;
return ngx_url_async_fetcher_->Init();
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() {
@@ -225,13 +170,9 @@ bool NgxRewriteDriverFactory::CheckResolver() {
return true;
}
void NgxRewriteDriverFactory::StopCacheActivity() {
RewriteDriverFactory::StopCacheActivity();
caches_->StopCacheActivity();
}
NgxServerContext* NgxRewriteDriverFactory::MakeNgxServerContext() {
NgxServerContext* server_context = new NgxServerContext(this);
NgxServerContext* NgxRewriteDriverFactory::MakeNgxServerContext(
StringPiece hostname, int port) {
NgxServerContext* server_context = new NgxServerContext(this, hostname, port);
uninitialized_server_contexts_.insert(server_context);
return server_context;
}
@@ -241,36 +182,21 @@ ServerContext* NgxRewriteDriverFactory::NewServerContext() {
return NULL;
}
void NgxRewriteDriverFactory::ShutDown() {
StopCacheActivity();
if (!is_root_process_) {
Variable* child_shutdown_count = statistics()->GetVariable(kShutdownCount);
child_shutdown_count->Add(1);
}
RewriteDriverFactory::ShutDown();
caches_->ShutDown(message_handler());
void NgxRewriteDriverFactory::ShutDownMessageHandlers() {
ngx_message_handler_->set_buffer(NULL);
ngx_html_parse_message_handler_->set_buffer(NULL);
if (is_root_process_) {
// Cleanup statistics.
// TODO(morlovich): This looks dangerous with async.
if (shared_mem_statistics_.get() != NULL) {
shared_mem_statistics_->GlobalCleanup(message_handler());
}
if (shared_circular_buffer_ != NULL) {
shared_circular_buffer_->GlobalCleanup(message_handler());
}
for (NgxMessageHandlerSet::iterator p =
server_context_message_handlers_.begin();
p != server_context_message_handlers_.end(); ++p) {
(*p)->set_buffer(NULL);
}
server_context_message_handlers_.clear();
}
void NgxRewriteDriverFactory::StartThreads() {
if (threads_started_) {
return;
}
ngx_thread_system_->PermitThreadStarting();
// TODO(jefftk): use a native nginx timer instead of running our own thread.
// See issue #111.
SchedulerThread* thread = new SchedulerThread(thread_system(), scheduler());
@@ -280,114 +206,42 @@ void NgxRewriteDriverFactory::StartThreads() {
threads_started_ = true;
}
void NgxRewriteDriverFactory::ParentOrChildInit(ngx_log_t* log) {
void NgxRewriteDriverFactory::LoggingInit(ngx_log_t* log) {
net_instaweb::log_message_handler::Install(log);
if (install_crash_handler_) {
NgxMessageHandler::InstallCrashHandler(log);
}
ngx_message_handler_->set_log(log);
ngx_html_parse_message_handler_->set_log(log);
SharedCircularBufferInit(is_root_process_);
}
// TODO(jmarantz): make this per-vhost.
void NgxRewriteDriverFactory::SharedCircularBufferInit(bool is_root) {
// Set buffer size to 0 means turning it off
if (shared_mem_runtime() != NULL && (message_buffer_size_ != 0)) {
// TODO(jmarantz): it appears that filename_prefix() is not actually
// established at the time of this construction, calling into question
// whether we are naming our shared-memory segments correctly.
shared_circular_buffer_.reset(new SharedCircularBuffer(
shared_mem_runtime(),
message_buffer_size_,
filename_prefix().as_string(),
"foo.com" /*hostname_identifier()*/));
if (shared_circular_buffer_->InitSegment(is_root, message_handler())) {
ngx_message_handler_->set_buffer(shared_circular_buffer_.get());
ngx_html_parse_message_handler_->set_buffer(
shared_circular_buffer_.get());
}
}
void NgxRewriteDriverFactory::SetCircularBuffer(
SharedCircularBuffer* buffer) {
ngx_shared_circular_buffer_ = buffer;
}
void NgxRewriteDriverFactory::RootInit(ngx_log_t* log) {
net_instaweb::log_message_handler::Install(log);
ParentOrChildInit(log);
// Let SystemCaches know about the various paths we have in configuration
// first, as well as the memcached instances.
for (NgxServerContextSet::iterator p = uninitialized_server_contexts_.begin(),
e = uninitialized_server_contexts_.end(); p != e; ++p) {
NgxServerContext* server_context = *p;
caches_->RegisterConfig(server_context->config());
}
caches_->RootInit();
}
void NgxRewriteDriverFactory::ChildInit(ngx_log_t* log) {
is_root_process_ = false;
ParentOrChildInit(log);
if (shared_mem_statistics_.get() != NULL) {
shared_mem_statistics_->Init(false, message_handler());
}
caches_->ChildInit();
for (NgxServerContextSet::iterator p = uninitialized_server_contexts_.begin(),
e = uninitialized_server_contexts_.end(); p != e; ++p) {
NgxServerContext* server_context = *p;
server_context->ChildInit();
}
uninitialized_server_contexts_.clear();
}
// Initializes global statistics object if needed, using factory to
// help with the settings if needed.
// Note: does not call set_statistics() on the factory.
Statistics* NgxRewriteDriverFactory::MakeGlobalSharedMemStatistics(
bool logging, int64 logging_interval_ms,
const GoogleString& logging_file_base) {
if (shared_mem_statistics_.get() == NULL) {
shared_mem_statistics_.reset(AllocateAndInitSharedMemStatistics(
"global", logging, logging_interval_ms, logging_file_base));
}
DCHECK(!statistics_frozen_);
statistics_frozen_ = true;
SetStatistics(shared_mem_statistics_.get());
return shared_mem_statistics_.get();
}
SharedMemStatistics* NgxRewriteDriverFactory::
AllocateAndInitSharedMemStatistics(
const StringPiece& name, const bool logging,
const int64 logging_interval_ms,
const GoogleString& logging_file_base) {
// Note that we create the statistics object in the parent process, and
// it stays around in the kids but gets reinitialized for them
// inside ChildInit(), called from pagespeed_child_init.
SharedMemStatistics* stats = new SharedMemStatistics(
logging_interval_ms, StrCat(logging_file_base, name), logging,
StrCat(filename_prefix(), name), shared_mem_runtime(), message_handler(),
file_system(), timer());
InitStats(stats);
stats->Init(true, message_handler());
return stats;
void NgxRewriteDriverFactory::SetServerContextMessageHandler(
ServerContext* server_context, ngx_log_t* log) {
NgxMessageHandler* handler = new NgxMessageHandler(
thread_system()->NewMutex());
handler->set_log(log);
// The ngx_shared_circular_buffer_ will be NULL if MessageBufferSize hasn't
// been raised from its default of 0.
handler->set_buffer(ngx_shared_circular_buffer_);
server_context_message_handlers_.insert(handler);
defer_cleanup(new Deleter<NgxMessageHandler>(handler));
server_context->set_message_handler(handler);
}
void NgxRewriteDriverFactory::InitStats(Statistics* statistics) {
// Init standard PSOL stats.
SystemRewriteDriverFactory::InitStats(statistics);
RewriteDriverFactory::InitStats(statistics);
RateController::InitStats(statistics);
// Init Ngx-specific stats.
NgxServerContext::InitStats(statistics);
SystemCaches::InitStats(statistics);
SerfUrlAsyncFetcher::InitStats(statistics);
PropertyCache::InitCohortStats(RewriteDriver::kBeaconCohort, statistics);
PropertyCache::InitCohortStats(RewriteDriver::kDomCohort, statistics);
statistics->AddVariable(kShutdownCount);
InPlaceResourceRecorder::InitStats(statistics);
}
} // namespace net_instaweb
+30 -73
View File
@@ -39,103 +39,62 @@ extern "C" {
namespace net_instaweb {
class AbstractSharedMem;
class NgxMessageHandler;
class NgxRewriteOptions;
class NgxServerContext;
class NgxThreadSystem;
class NgxUrlAsyncFetcher;
class SharedCircularBuffer;
class SharedMemRefererStatistics;
class SharedMemStatistics;
class SlowWorker;
class StaticAssetManager;
class Statistics;
class SystemCaches;
class SystemThreadSystem;
class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
public:
static const char kStaticAssetPrefix[];
// We take ownership of the thread system.
explicit NgxRewriteDriverFactory(NgxThreadSystem* ngx_thread_system);
explicit NgxRewriteDriverFactory(
SystemThreadSystem* system_thread_system, StringPiece hostname, int port);
virtual ~NgxRewriteDriverFactory();
virtual Hasher* NewHasher();
virtual UrlFetcher* DefaultUrlFetcher();
virtual UrlAsyncFetcher* DefaultAsyncUrlFetcher();
virtual UrlAsyncFetcher* AllocateFetcher(SystemRewriteOptions* config);
virtual MessageHandler* DefaultHtmlParseMessageHandler();
virtual MessageHandler* DefaultMessageHandler();
virtual FileSystem* DefaultFileSystem();
virtual Timer* DefaultTimer();
virtual NamedLockManager* DefaultLockManager();
virtual void SetupCaches(ServerContext* server_context);
// Create a new RewriteOptions. In this implementation it will be an
// NgxRewriteOptions.
virtual RewriteOptions* NewRewriteOptions();
// Initializes the StaticAssetManager.
virtual void InitStaticAssetManager(
StaticAssetManager* static_asset_manager);
// Print out details of all the connections to memcached servers.
void PrintMemCacheStats(GoogleString* out);
bool InitNgxUrlAsyncFetcher();
bool InitNgxUrlAsyncFetchers();
// Check resolver configured or not.
bool CheckResolver();
// Release all the resources. It also calls the base class ShutDown to
// release the base class resources.
// Initializes all the statistics objects created transitively by
// NgxRewriteDriverFactory, including nginx-specific and
// platform-independent statistics.
static void InitStats(Statistics* statistics);
virtual void ShutDown();
virtual void StopCacheActivity();
NgxServerContext* MakeNgxServerContext();
NgxServerContext* MakeNgxServerContext(StringPiece hostname, int port);
ServerContext* NewServerContext();
AbstractSharedMem* shared_mem_runtime() const {
return shared_mem_runtime_.get();
}
SystemCaches* caches() { return caches_.get(); }
// Starts pagespeed threads if they've not been started already. Must be
// called after the caller has finished any forking it intends to do.
void StartThreads();
// This helper method contains init procedures invoked by both RootInit()
// and ChildInit()
void ParentOrChildInit(ngx_log_t* log);
// For shared memory resources the general setup we follow is to have the
// first running process (aka the root) create the necessary segments and
// fill in their shared data structures, while processes created to actually
// handle requests attach to already existing shared data structures.
//
// During normal server startup[1], RootInit() is called from the nginx hooks
// in the root process for the first task, and then ChildInit() is called in
// any child process.
//
// Keep in mind, however, that when fork() is involved a process may
// effectively see both calls, in which case the 'ChildInit' call would
// come second and override the previous root status. Both calls are also
// invoked in the debug single-process mode.
//
// [1] Besides normal startup, nginx also uses a temporary process to
// syntax check the config file. That basically looks like a complete
// normal startup and shutdown to the code.
bool is_root_process() const { return is_root_process_; }
void RootInit(ngx_log_t* log);
void ChildInit(ngx_log_t* log);
void SharedCircularBufferInit(bool is_root);
// Build global shared-memory statistics. This is invoked if at least
// one server context (global or VirtualHost) enables statistics.
Statistics* MakeGlobalSharedMemStatistics(bool logging,
int64 logging_interval_ms,
const GoogleString& logging_file);
// Creates and ::Initializes a shared memory statistics object.
SharedMemStatistics* AllocateAndInitSharedMemStatistics(
const StringPiece& name, const bool logging,
const int64 logging_interval_ms, const GoogleString& logging_file);
void SetServerContextMessageHandler(ServerContext* server_context,
ngx_log_t* log);
NgxMessageHandler* ngx_message_handler() { return ngx_message_handler_; }
virtual void NonStaticInitStats(Statistics* statistics) {
InitStats(statistics);
}
void set_main_conf(NgxRewriteOptions* main_conf) { main_conf_ = main_conf; }
bool use_per_vhost_statistics() const {
@@ -150,12 +109,6 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
void set_install_crash_handler(bool x) {
install_crash_handler_ = x;
}
bool message_buffer_size() const {
return message_buffer_size_;
}
void set_message_buffer_size(int x) {
message_buffer_size_ = x;
}
void set_resolver(ngx_resolver_t* resolver) {
resolver_ = resolver;
}
@@ -169,6 +122,9 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
void set_use_native_fetcher(bool x) {
use_native_fetcher_ = x;
}
void set_rate_limit_background_fetches(bool x) {
rate_limit_background_fetches_ = x;
}
// We use a beacon handler to collect data for critical images,
// css, etc., so filters should be configured accordingly.
@@ -178,39 +134,40 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
return true;
}
void LoggingInit(ngx_log_t* log);
virtual void ShutDownMessageHandlers();
virtual void SetCircularBuffer(SharedCircularBuffer* buffer);
private:
NgxThreadSystem* ngx_thread_system_;
Timer* timer_;
scoped_ptr<AbstractSharedMem> shared_mem_runtime_;
// main_conf will have only options set in the main block. It may be NULL,
// and we do not take ownership.
NgxRewriteOptions* main_conf_;
typedef std::set<NgxServerContext*> NgxServerContextSet;
NgxServerContextSet uninitialized_server_contexts_;
// Manages all our caches & lock managers.
scoped_ptr<SystemCaches> caches_;
bool threads_started_;
// If true, we'll have a separate statistics object for each vhost
// (along with a global aggregate), rather than just a single object
// aggregating all of them.
bool use_per_vhost_statistics_;
bool is_root_process_;
NgxMessageHandler* ngx_message_handler_;
NgxMessageHandler* ngx_html_parse_message_handler_;
bool install_crash_handler_;
int message_buffer_size_;
scoped_ptr<SharedCircularBuffer> shared_circular_buffer_;
scoped_ptr<SharedMemStatistics> shared_mem_statistics_;
bool statistics_frozen_;
NgxUrlAsyncFetcher* ngx_url_async_fetcher_;
std::vector<NgxUrlAsyncFetcher*> ngx_url_async_fetchers_;
ngx_log_t* log_;
ngx_msec_t resolver_timeout_;
ngx_resolver_t* resolver_;
bool use_native_fetcher_;
bool rate_limit_background_fetches_;
typedef std::set<NgxMessageHandler*> NgxMessageHandlerSet;
NgxMessageHandlerSet server_context_message_handlers_;
// Owned by the superclass.
// TODO(jefftk): merge the nginx and apache ways of doing this.
SharedCircularBuffer* ngx_shared_circular_buffer_;
DISALLOW_COPY_AND_ASSIGN(NgxRewriteDriverFactory);
};
+88 -73
View File
@@ -35,9 +35,22 @@ extern "C" {
namespace net_instaweb {
namespace {
const char kNgxPagespeedStatisticsHandlerPath[] = "/ngx_pagespeed_statistics";
} // namespace
RewriteOptions::Properties* NgxRewriteOptions::ngx_properties_ = NULL;
NgxRewriteOptions::NgxRewriteOptions() {
NgxRewriteOptions::NgxRewriteOptions(const StringPiece& description,
ThreadSystem* thread_system)
: SystemRewriteOptions(description, thread_system) {
Init();
}
NgxRewriteOptions::NgxRewriteOptions(ThreadSystem* thread_system)
: SystemRewriteOptions(thread_system) {
Init();
}
@@ -45,21 +58,22 @@ void NgxRewriteOptions::Init() {
DCHECK(ngx_properties_ != NULL)
<< "Call NgxRewriteOptions::Initialize() before construction";
InitializeOptions(ngx_properties_);
// Nginx-specific default.
// TODO(sligocki): Get rid of this line and let both Apache and Nginx use
// /pagespeed_statistics as the handler.
statistics_handler_path_.set_default(kNgxPagespeedStatisticsHandlerPath);
}
void NgxRewriteOptions::AddProperties() {
// Nothing ngx-specific for now.
MergeSubclassProperties(ngx_properties_);
NgxRewriteOptions config;
config.InitializeSignaturesAndDefaults();
}
void NgxRewriteOptions::InitializeSignaturesAndDefaults() {
// Calls to foo_.DoNotUseForSignatureComputation() would go here.
// Set default header value.
set_default_x_header_value(kModPagespeedVersion);
// Default properties are global but to set them the current API requires
// a RewriteOptions instance and we're in a static method.
NgxRewriteOptions dummy_config(NULL);
dummy_config.set_default_x_header_value(kModPagespeedVersion);
}
void NgxRewriteOptions::Initialize() {
@@ -94,42 +108,48 @@ RewriteOptions::OptionSettingResult NgxRewriteOptions::ParseAndSetOptions0(
return RewriteOptions::kOptionOk;
}
RewriteOptions::OptionSettingResult
NgxRewriteOptions::ParseAndSetOptionFromEnum1(
OptionEnum directive, StringPiece arg,
NgxRewriteOptions::ParseAndSetOptionFromName1(
StringPiece name, StringPiece arg,
GoogleString* msg, MessageHandler* handler) {
// FileCachePath needs error checking.
if (directive == kFileCachePath) {
if (StringCaseEqual(name, kFileCachePath)) {
if (!StringCaseStartsWith(arg, "/")) {
*msg = "must start with a slash";
return RewriteOptions::kOptionValueInvalid;
}
}
// TODO(jefftk): port these (no enums for them yet, even!)
// DangerPermitFetchFromUnknownHosts, FetchWithGzip, ForceCaching
return SystemRewriteOptions::ParseAndSetOptionFromName1(
name, arg, msg, handler);
}
return SystemRewriteOptions::ParseAndSetOptionFromEnum1(
directive, arg, msg, handler);
template <class DriverFactoryT>
RewriteOptions::OptionSettingResult ParseAndSetOptionHelper(
StringPiece option_value,
DriverFactoryT* driver_factory,
void (DriverFactoryT::*set_option_method)(bool)) {
bool parsed_value;
if (StringCaseEqual(option_value, "on") ||
StringCaseEqual(option_value, "true")) {
parsed_value = true;
} else if (StringCaseEqual(option_value, "off") ||
StringCaseEqual(option_value, "false")) {
parsed_value = false;
} else {
return RewriteOptions::kOptionValueInvalid;
}
(driver_factory->*set_option_method)(parsed_value);
return RewriteOptions::kOptionOk;
}
// Very similar to apache/mod_instaweb::ParseDirective.
const char*
NgxRewriteOptions::ParseAndSetOptions(
const char* NgxRewriteOptions::ParseAndSetOptions(
StringPiece* args, int n_args, ngx_pool_t* pool, MessageHandler* handler,
NgxRewriteDriverFactory* driver_factory) {
CHECK_GE(n_args, 1);
int i;
fprintf(stderr, "Setting option from (");
for (i = 0 ; i < n_args ; i++) {
fprintf(stderr, "%s\"%s\"",
i == 0 ? "" : ", ",
args[i].as_string().c_str());
}
fprintf(stderr, ")\n");
StringPiece directive = args[0];
// Remove initial "ModPagespeed" if there is one.
@@ -147,51 +167,45 @@ NgxRewriteOptions::ParseAndSetOptions(
// TODO(morlovich): Remove these special hacks, and handle these via
// ParseAndSetOptionFromEnum1.
if (IsDirective(directive, "UsePerVHostStatistics")) {
// TODO(oschaaf): mod_pagespeed has a nicer way to do this.
if (IsDirective(arg, "on")) {
driver_factory->set_use_per_vhost_statistics(true);
result = RewriteOptions::kOptionOk;
} else if (IsDirective(arg, "off")) {
driver_factory->set_use_per_vhost_statistics(false);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
} else if (IsDirective(directive, "InstallCrashHandler")) {
// TODO(oschaaf): mod_pagespeed has a nicer way to do this.
if (IsDirective(arg, "on")) {
driver_factory->set_install_crash_handler(true);
result = RewriteOptions::kOptionOk;
} else if (IsDirective(arg, "off")) {
driver_factory->set_install_crash_handler(false);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
} else if (IsDirective(directive, "MessageBufferSize")) {
// TODO(oschaaf): mod_pagespeed has a nicer way to do this.
int message_buffer_size;
bool ok = StringToInt(arg.as_string(), &message_buffer_size);
if (ok && message_buffer_size >= 0) {
driver_factory->set_message_buffer_size(message_buffer_size);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
} else if (IsDirective(directive, "UseNativeFetcher")) {
// TODO(oschaaf): mod_pagespeed has a nicer way to do this.
if (IsDirective(arg, "on")) {
driver_factory->set_use_native_fetcher(true);
result = RewriteOptions::kOptionOk;
} else if (IsDirective(arg, "off")) {
driver_factory->set_use_native_fetcher(false);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory,
&NgxRewriteDriverFactory::set_use_per_vhost_statistics);
} else if (IsDirective(directive, "InstallCrashHandler")) {
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory,
&NgxRewriteDriverFactory::set_install_crash_handler);
} else if (IsDirective(directive, "MessageBufferSize")) {
int message_buffer_size;
bool ok = StringToInt(arg.as_string(), &message_buffer_size);
if (ok && message_buffer_size >= 0) {
driver_factory->set_message_buffer_size(message_buffer_size);
result = RewriteOptions::kOptionOk;
} else {
result = ParseAndSetOptionFromName1(directive, args[1], &msg, handler);
result = RewriteOptions::kOptionValueInvalid;
}
} else if (IsDirective(directive, "UseNativeFetcher")) {
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory,
&NgxRewriteDriverFactory::set_use_native_fetcher);
} else if (IsDirective(directive, "RateLimitBackgroundFetches")) {
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory,
&NgxRewriteDriverFactory::set_rate_limit_background_fetches);
} else if (IsDirective(directive, "ForceCaching")) {
result = ParseAndSetOptionHelper<SystemRewriteDriverFactory>(
arg, driver_factory,
&SystemRewriteDriverFactory::set_force_caching);
} else if (IsDirective(directive, "ListOutstandingUrlsOnError")) {
result = ParseAndSetOptionHelper<SystemRewriteDriverFactory>(
arg, driver_factory,
&SystemRewriteDriverFactory::list_outstanding_urls_on_error);
} else if (IsDirective(directive, "TrackOriginalContentLength")) {
result = ParseAndSetOptionHelper<SystemRewriteDriverFactory>(
arg, driver_factory,
&SystemRewriteDriverFactory::set_track_original_content_length);
} else {
result = ParseAndSetOptionFromName1(directive, args[1], &msg, handler);
}
} else if (n_args == 3) {
// Short-term special handling, until this moves to common code.
// TODO(morlovich): Clean this up.
@@ -227,7 +241,7 @@ NgxRewriteOptions::ParseAndSetOptions(
StrAppend(&full_directive, i == 0 ? "" : " ", args[i]);
}
StrAppend(&full_directive, "\": ", msg);
char* s = ngx_psol::string_piece_to_pool_string(pool, full_directive);
char* s = string_piece_to_pool_string(pool, full_directive);
if (s == NULL) {
return "failed to allocate memory";
}
@@ -240,7 +254,8 @@ NgxRewriteOptions::ParseAndSetOptions(
}
NgxRewriteOptions* NgxRewriteOptions::Clone() const {
NgxRewriteOptions* options = new NgxRewriteOptions();
NgxRewriteOptions* options = new NgxRewriteOptions(
StrCat("cloned from ", description()), thread_system());
options->Merge(*this);
return options;
}
+8 -9
View File
@@ -40,7 +40,8 @@ class NgxRewriteOptions : public SystemRewriteOptions {
static void Initialize();
static void Terminate();
NgxRewriteOptions();
NgxRewriteOptions(const StringPiece& description, ThreadSystem* thread_system);
explicit NgxRewriteOptions(ThreadSystem* thread_system);
virtual ~NgxRewriteOptions() { }
// args is an array of n_args StringPieces together representing a directive.
@@ -85,9 +86,8 @@ class NgxRewriteOptions : public SystemRewriteOptions {
OptionSettingResult ParseAndSetOptions0(
StringPiece directive, GoogleString* msg, MessageHandler* handler);
// These are called via RewriteOptions::ParseAndSetOptionFromName[123]
virtual OptionSettingResult ParseAndSetOptionFromEnum1(
OptionEnum name, StringPiece arg,
virtual OptionSettingResult ParseAndSetOptionFromName1(
StringPiece name, StringPiece arg,
GoogleString* msg, MessageHandler* handler);
// We may want to override 2- and 3-argument versions as well in the future,
@@ -102,15 +102,14 @@ class NgxRewriteOptions : public SystemRewriteOptions {
static Properties* ngx_properties_;
static void AddProperties();
void Init();
void InitializeSignaturesAndDefaults();
// Add an option to ngx_properties_
template<class RewriteOptionsSubclass, class OptionClass>
template<class OptionClass>
static void add_ngx_option(typename OptionClass::ValueType default_value,
OptionClass RewriteOptionsSubclass::*offset,
OptionClass NgxRewriteOptions::*offset,
const char* id,
OptionEnum option_enum) {
AddProperty(default_value, offset, id, option_enum, ngx_properties_);
StringPiece option_name) {
AddProperty(default_value, offset, id, option_name, ngx_properties_);
}
// Helper for ParseAndSetOptions. Returns whether the two directives equal,
+40 -101
View File
@@ -18,123 +18,62 @@
#include "ngx_server_context.h"
#include "ngx_request_context.h"
#include "ngx_rewrite_options.h"
extern "C" {
#include <ngx_http.h>
}
#include "ngx_pagespeed.h"
#include "ngx_message_handler.h"
#include "ngx_rewrite_driver_factory.h"
#include "net/instaweb/apache/add_headers_fetcher.h"
#include "net/instaweb/apache/loopback_route_fetcher.h"
#include "ngx_rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_stats.h"
#include "net/instaweb/system/public/system_caches.h"
#include "net/instaweb/util/public/shared_mem_statistics.h"
#include "net/instaweb/util/public/split_statistics.h"
#include "net/instaweb/util/public/statistics.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"
namespace net_instaweb {
const char kCacheFlushCount[] = "cache_flush_count";
const char kCacheFlushTimestampMs[] = "cache_flush_timestamp_ms";
// Statistics histogram names.
const char kHtmlRewriteTimeUsHistogram[] = "Html Time us Histogram";
NgxServerContext::NgxServerContext(NgxRewriteDriverFactory* factory)
: SystemServerContext(factory),
ngx_factory_(factory),
initialized_(false) {
NgxServerContext::NgxServerContext(
NgxRewriteDriverFactory* factory, StringPiece hostname, int port)
: SystemServerContext(factory, hostname, port) {
}
NgxServerContext::~NgxServerContext() {
}
NgxServerContext::~NgxServerContext() { }
NgxRewriteOptions* NgxServerContext::config() {
return NgxRewriteOptions::DynamicCast(global_options());
}
void NgxServerContext::ChildInit() {
DCHECK(!initialized_);
if (!initialized_) {
initialized_ = true;
set_lock_manager(ngx_factory_->caches()->GetLockManager(config()));
if (split_statistics_.get() != NULL) {
// Readjust the SHM stuff for the new process
local_statistics_->Init(false, message_handler());
// Create local stats for the ServerContext, and fill in its
// statistics() and rewrite_stats() using them; if we didn't do this here
// they would get set to the factory's by the InitServerContext call
// below.
set_statistics(split_statistics_.get());
local_rewrite_stats_.reset(new RewriteStats(
split_statistics_.get(), ngx_factory_->thread_system(),
ngx_factory_->timer()));
set_rewrite_stats(local_rewrite_stats_.get());
}
ngx_factory_->InitServerContext(this);
// TODO(oschaaf): in mod_pagespeed, the ServerContext owns
// the fetchers, and sets up the UrlAsyncFetcherStats here
SystemRequestContext* NgxServerContext::NewRequestContext(
ngx_http_request_t* r) {
// Based on ngx_http_variable_server_port.
bool port_set = false;
int local_port;
#if (NGX_HAVE_INET6)
if (r->connection->local_sockaddr->sa_family == AF_INET6) {
local_port = ntohs(reinterpret_cast<struct sockaddr_in6*>(
r->connection->local_sockaddr)->sin6_port);
port_set = true;
}
}
void NgxServerContext::CreateLocalStatistics(
Statistics* global_statistics) {
local_statistics_ =
ngx_factory_->AllocateAndInitSharedMemStatistics(
hostname_identifier(),
config()->statistics_logging_enabled(),
config()->statistics_logging_interval_ms(),
config()->statistics_logging_file());
split_statistics_.reset(new SplitStatistics(
ngx_factory_->thread_system(), local_statistics_, global_statistics));
// local_statistics_ was ::InitStat'd by AllocateAndInitSharedMemStatistics,
// but we need to take care of split_statistics_.
NgxRewriteDriverFactory::InitStats(split_statistics_.get());
}
void NgxServerContext::InitStats(Statistics* statistics) {
// TODO(oschaaf): we need to port the cache flush mechanism
statistics->AddVariable(kCacheFlushCount);
statistics->AddVariable(kCacheFlushTimestampMs);
Histogram* html_rewrite_time_us_histogram =
statistics->AddHistogram(kHtmlRewriteTimeUsHistogram);
// We set the boundary at 2 seconds which is about 2 orders of magnitude
// worse than anything we have reasonably seen, to make sure we don't
// cut off actual samples.
html_rewrite_time_us_histogram->SetMaxValue(2 * Timer::kSecondUs);
// TODO(oschaaf): Once the ServerContext owns the fetchers,
// initialise UrlAsyncFetcherStats here
}
void NgxServerContext::ApplySessionFetchers(
const RequestContextPtr& request, RewriteDriver* driver) {
const NgxRewriteOptions* conf = NgxRewriteOptions::DynamicCast(
driver->options());
CHECK(conf != NULL);
NgxRequestContext* ngx_request = NgxRequestContext::DynamicCast(
request.get());
if (ngx_request == NULL) {
return; // decoding_driver has a null RequestContext.
#endif
if (!port_set) {
local_port = ntohs(reinterpret_cast<struct sockaddr_in*>(
r->connection->local_sockaddr)->sin_port);
}
// Note that these fetchers are applied in the opposite order of how they are
// added
// TODO(oschaaf): in mod_pagespeed, LoopbackRouteFetcher is not added when
// one of these is set: disable_loopback_routing, slurping_enabled, or
// test_proxy.
// Note the port here is our port, not from the request, since
// LoopbackRouteFetcher may decide we should be talking to ourselves.
driver->SetSessionFetcher(new LoopbackRouteFetcher(
driver->options(), ngx_request->local_ip(),
ngx_request->local_port(), driver->async_fetcher()));
if (driver->options()->num_custom_fetch_headers() > 0) {
driver->SetSessionFetcher(new AddHeadersFetcher(driver->options(),
driver->async_fetcher()));
ngx_str_t local_ip;
u_char addr[NGX_SOCKADDR_STRLEN];
local_ip.len = NGX_SOCKADDR_STRLEN;
local_ip.data = addr;
ngx_int_t rc = ngx_connection_local_sockaddr(r->connection, &local_ip, 0);
if (rc != NGX_OK) {
local_ip.len = 0;
}
return new SystemRequestContext(thread_system()->NewMutex(),
timer(),
local_port,
str_to_string_piece(local_ip));
}
} // namespace net_instaweb
+14 -28
View File
@@ -21,19 +21,23 @@
#ifndef NGX_SERVER_CONTEXT_H_
#define NGX_SERVER_CONTEXT_H_
#include "ngx_message_handler.h"
#include "net/instaweb/system/public/system_server_context.h"
extern "C" {
#include <ngx_http.h>
}
namespace net_instaweb {
class NgxRewriteDriverFactory;
class NgxRewriteOptions;
class RewriteStats;
class SharedMemStatistics;
class Statistics;
class SystemRequestContext;
class NgxServerContext : public SystemServerContext {
public:
explicit NgxServerContext(NgxRewriteDriverFactory* factory);
NgxServerContext(
NgxRewriteDriverFactory* factory, StringPiece hostname, int port);
virtual ~NgxServerContext();
// We expect to use ProxyFetch with HTML.
@@ -43,34 +47,16 @@ class NgxServerContext : public SystemServerContext {
// nginx-specific behavior, call global_options() instead which doesn't
// downcast.
NgxRewriteOptions* config();
// Should be called after the child process is forked.
void ChildInit();
// Initialize this ServerContext to have its own statistics domain.
// Must be called after global_statistics has been created and had
// ::Initialize called on it.
void CreateLocalStatistics(Statistics* global_statistics);
static void InitStats(Statistics* statistics);
virtual void ApplySessionFetchers(const RequestContextPtr& req,
RewriteDriver* driver);
bool initialized() const { return initialized_; }
GoogleString hostname_identifier() { return hostname_identifier_; }
void set_hostname_identifier(GoogleString x) { hostname_identifier_ = x; }
NgxRewriteDriverFactory* ngx_rewrite_driver_factory() { return ngx_factory_; }
SystemRequestContext* NewRequestContext(ngx_http_request_t* r);
NgxMessageHandler* ngx_message_handler() {
return dynamic_cast<NgxMessageHandler*>(message_handler());
}
private:
NgxRewriteDriverFactory* ngx_factory_;
// hostname_identifier_ is used to distinguish the name of shared memory
// segments associated with this ServerContext
GoogleString hostname_identifier_;
bool initialized_;
// Non-NULL if we have per-vhost stats.
scoped_ptr<Statistics> split_statistics_;
// May be NULL. Owned by *split_statistics_.
SharedMemStatistics* local_statistics_;
// These are non-NULL if we have per-vhost stats.
scoped_ptr<RewriteStats> local_rewrite_stats_;
DISALLOW_COPY_AND_ASSIGN(NgxServerContext);
};
-56
View File
@@ -1,56 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: jefftk@google.com (Jeff Kaufman)
//
// See ApacheThreadSystem.
//
//
#ifndef NGX_THREAD_SYSTEM_H_
#define NGX_THREAD_SYSTEM_H_
#include "base/logging.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/pthread_thread_system.h"
namespace net_instaweb {
class Timer;
class NgxThreadSystem : public PthreadThreadSystem {
public:
NgxThreadSystem();
virtual ~NgxThreadSystem();
// In nginx we may only start threads after forking a worker process. In
// order to enforce this, we call PermitThreadStarting() in the worker process
// right after forking, and CHECK-fail if something tries to start a thread
// before then.
void PermitThreadStarting();
protected:
virtual void BeforeThreadRunHook();
private:
bool may_start_threads_;
DISALLOW_COPY_AND_ASSIGN(NgxThreadSystem);
};
} // namespace net_instaweb
#endif // NGX_THREAD_SYSTEM_H_
+1 -1
View File
@@ -33,11 +33,11 @@ extern "C" {
}
#include <vector>
#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 "net/instaweb/http/public/url_pollable_async_fetcher.h"
namespace net_instaweb {
-257
View File
@@ -1,257 +0,0 @@
// Copyright 2011 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: morlovich@google.com (Maksim Orlovich)
#include "pthread_shared_mem.h"
#include <fcntl.h>
#include <pthread.h>
#include <sys/mman.h>
#include <unistd.h>
#include <cerrno>
#include <cstddef>
#include <map>
#include <utility>
#include "net/instaweb/util/public/abstract_shared_mem.h"
#include "net/instaweb/util/public/abstract_mutex.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/string.h"
namespace net_instaweb {
namespace ngx {
namespace {
// This implementation relies on readonly copies of old memory and shared R/W
// mappings being kept across a fork. It simply stashes addresses of
// shared mmap segments into a map where kid processes can pick them up.
// close() a fd logging failure and dealing with EINTR.
void CheckedClose(int fd, MessageHandler* message_handler) {
while (close(fd) != 0) {
if (errno != EINTR) {
message_handler->Message(kWarning, "Problem closing SHM segment fd:%d",
errno);
return;
}
}
}
// Unlike PthreadMutex this doesn't own the lock, but rather refers to an
// external one.
class PthreadSharedMemMutex : public AbstractMutex {
public:
explicit PthreadSharedMemMutex(pthread_mutex_t* external_mutex)
: external_mutex_(external_mutex) {}
virtual bool TryLock() {
return (pthread_mutex_trylock(external_mutex_) == 0);
}
virtual void Lock() {
pthread_mutex_lock(external_mutex_);
}
virtual void Unlock() {
pthread_mutex_unlock(external_mutex_);
}
private:
pthread_mutex_t* external_mutex_;
DISALLOW_COPY_AND_ASSIGN(PthreadSharedMemMutex);
};
class PthreadSharedMemSegment : public AbstractSharedMemSegment {
public:
// We will be representing memory mapped in the [base, base + size) range.
PthreadSharedMemSegment(char* base, size_t size, MessageHandler* handler)
: base_(base),
size_(size) {
}
virtual ~PthreadSharedMemSegment() {
}
virtual volatile char* Base() {
return base_;
}
virtual size_t SharedMutexSize() const {
return sizeof(pthread_mutex_t);
}
virtual bool InitializeSharedMutex(size_t offset, MessageHandler* handler) {
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0) {
handler->Message(kError, "pthread_mutexattr_init failed with errno:%d",
errno);
return false;
}
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0) {
pthread_mutexattr_destroy(&attr);
handler->Message(
kError, "pthread_mutexattr_setpshared failed with errno:%d", errno);
return false;
}
if (pthread_mutex_init(MutexPtr(offset), &attr) != 0) {
pthread_mutexattr_destroy(&attr);
handler->Message(kError, "pthread_mutex_init failed with errno:%d",
errno);
return false;
}
pthread_mutexattr_destroy(&attr);
return true;
}
virtual AbstractMutex* AttachToSharedMutex(size_t offset) {
return new PthreadSharedMemMutex(MutexPtr(offset));
}
private:
pthread_mutex_t* MutexPtr(size_t offset) {
return reinterpret_cast<pthread_mutex_t*>(base_ + offset);
}
char* const base_;
const size_t size_;
DISALLOW_COPY_AND_ASSIGN(PthreadSharedMemSegment);
};
pthread_mutex_t segment_bases_lock = PTHREAD_MUTEX_INITIALIZER;
} // namespace
size_t PthreadSharedMem::s_instance_count_ = 0;
PthreadSharedMem::SegmentBaseMap* PthreadSharedMem::segment_bases_ = NULL;
PthreadSharedMem::PthreadSharedMem() {
instance_number_ = ++s_instance_count_;
}
PthreadSharedMem::~PthreadSharedMem() {
}
size_t PthreadSharedMem::SharedMutexSize() const {
return sizeof(pthread_mutex_t);
}
AbstractSharedMemSegment* PthreadSharedMem::CreateSegment(
const GoogleString& name, size_t size, MessageHandler* handler) {
GoogleString prefixed_name = PrefixSegmentName(name);
// Create the memory
int fd = open("/dev/zero", O_RDWR);
if (fd == -1) {
handler->Message(kError, "Unable to create SHM segment %s, errno=%d.",
prefixed_name.c_str(), errno);
return NULL;
}
// map it
char* base = reinterpret_cast<char*>(
mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
CheckedClose(fd, handler);
if (base == MAP_FAILED) {
return NULL;
}
SegmentBaseMap* bases = AcquireSegmentBases();
(*bases)[prefixed_name] = base;
UnlockSegmentBases();
return new PthreadSharedMemSegment(base, size, handler);
}
AbstractSharedMemSegment* PthreadSharedMem::AttachToSegment(
const GoogleString& name, size_t size, MessageHandler* handler) {
GoogleString prefixed_name = PrefixSegmentName(name);
SegmentBaseMap* bases = AcquireSegmentBases();
SegmentBaseMap::const_iterator i = bases->find(prefixed_name);
if (i == bases->end()) {
handler->Message(kError, "Unable to find SHM segment %s to attach to.",
prefixed_name.c_str());
UnlockSegmentBases();
return NULL;
}
char* base = i->second;
UnlockSegmentBases();
return new PthreadSharedMemSegment(base, size, handler);
}
void PthreadSharedMem::DestroySegment(const GoogleString& name,
MessageHandler* handler) {
GoogleString prefixed_name = PrefixSegmentName(name);
// Note that in the process state children will not see any mutations
// we make here, so it acts mostly for checking in that case.
SegmentBaseMap* bases = AcquireSegmentBases();
SegmentBaseMap::iterator i = bases->find(prefixed_name);
if (i != bases->end()) {
bases->erase(i);
if (bases->empty()) {
delete segment_bases_;
segment_bases_ = NULL;
}
} else {
handler->Message(kError, "Attempt to destroy unknown SHM segment %s.",
prefixed_name.c_str());
}
UnlockSegmentBases();
}
PthreadSharedMem::SegmentBaseMap* PthreadSharedMem::AcquireSegmentBases() {
PthreadSharedMemMutex lock(&segment_bases_lock);
lock.Lock();
if (segment_bases_ == NULL) {
segment_bases_ = new SegmentBaseMap();
}
return segment_bases_;
}
void PthreadSharedMem::UnlockSegmentBases() {
PthreadSharedMemMutex lock(&segment_bases_lock);
lock.Unlock();
}
GoogleString PthreadSharedMem::PrefixSegmentName(const GoogleString& name) {
GoogleString res;
StrAppend(&res, "[", IntegerToString(instance_number_), "]", name);
return res;
}
void PthreadSharedMem::Terminate() {
// Clean up the local memory associated with the maps to shared memory
// storage.
PthreadSharedMemMutex lock(&segment_bases_lock);
lock.Lock();
if (segment_bases_ != NULL) {
delete segment_bases_;
segment_bases_ = NULL;
}
lock.Unlock();
}
} // namespace ngx
} // namespace net_instaweb
-88
View File
@@ -1,88 +0,0 @@
// Copyright 2011 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: morlovich@google.com (Maksim Orlovich)
#ifndef NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
#define NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
#include <cstddef>
#include <map>
#include "net/instaweb/util/public/abstract_shared_mem.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/string.h"
namespace net_instaweb {
class MessageHandler;
namespace ngx {
// POSIX shared memory support, using mmap/pthread_mutexattr_setpshared
// Supports both processes and threads, but processes that want to access it
// must be results of just fork (without exec), and all the CreateSegment
// calls must occur before the fork.
//
// This implementation is also not capable of deallocating segments except
// at exit, so it should not be used when the set of segments may be dynamic.
class PthreadSharedMem : public AbstractSharedMem {
public:
PthreadSharedMem();
virtual ~PthreadSharedMem();
virtual size_t SharedMutexSize() const;
virtual AbstractSharedMemSegment* CreateSegment(
const GoogleString& name, size_t size, MessageHandler* handler);
virtual AbstractSharedMemSegment* AttachToSegment(
const GoogleString& name, size_t size, MessageHandler* handler);
virtual void DestroySegment(const GoogleString& name,
MessageHandler* handler);
// Frees all lazy-initialized memory used to track shared-memory segments.
static void Terminate();
private:
typedef std::map<GoogleString, char*> SegmentBaseMap;
// Accessor for below. Note that the segment_bases_lock will be held at exit.
static SegmentBaseMap* AcquireSegmentBases();
static void UnlockSegmentBases();
// Prefixes the passed in segment name with the current instance number.
GoogleString PrefixSegmentName(const GoogleString& name);
// The root process stores segment locations here. Child processes will
// inherit a readonly copy of this map after the fork. Note that this is
// initialized in a thread-unsafe manner, given the above assumptions.
static SegmentBaseMap* segment_bases_;
// Holds the number of times a PthreadSharedMem has been created.
static size_t s_instance_count_;
// Used to prefix segment names, so that when two runtimes are active at the
// same moment they will not have overlapping segment names. This occurs in
// ngx_pagespeed during a configuration reload, where first a new factory is
// created, before destroying the old one.
size_t instance_number_;
DISALLOW_COPY_AND_ASSIGN(PthreadSharedMem);
};
} // namespace ngx
} // namespace net_instaweb
#endif // NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
+754 -217
View File
File diff suppressed because it is too large Load Diff
+264 -3
View File
@@ -7,7 +7,7 @@ worker_processes 1;
daemon @@DAEMON@@;
master_process @@MASTER_PROCESS@@;
error_log "@@TEST_TMP@@/error.log" debug;
error_log "@@ERROR_LOG@@" debug;
pid "@@TEST_TMP@@/nginx.pid";
events {
@@ -16,12 +16,22 @@ events {
http {
access_log "@@TEST_TMP@@/access.log";
server_names_hash_bucket_size 128;
log_format cache '$time_local '
'$upstream_cache_status '
'$http_host $request ($status) '
'"$http_user_agent"';
access_log "@@ACCESS_LOG@@" cache;
proxy_cache_path "@@PROXY_CACHE@@" levels=1:2 keys_zone=htmlcache:60m inactive=90m max_size=50m;
proxy_temp_path "@@TMP_PROXY_CACHE@@";
root "@@SERVER_ROOT@@";
pagespeed UsePerVHostStatistics on;
pagespeed InPlaceResourceOptimization on;
pagespeed CreateSharedMemoryMetadataCache "@@SHM_CACHE@@" 8192;
pagespeed PreserveUrlRelativity on;
# CriticalImagesBeaconEnabled is now on by default, but we disable in testing.
# With this option enabled, the inline image system test will currently fail.
@@ -30,6 +40,10 @@ http {
# critical images to be inlined, so we just disable the option here.
pagespeed CriticalImagesBeaconEnabled false;
pagespeed Statistics on;
pagespeed StatisticsLogging on;
pagespeed LogDir "@@TEST_TMP@@/logdir";
server {
# Sets up a logical home-page server on
# max-cacheable-content-length.example.com. This server is only used to
@@ -49,6 +63,70 @@ http {
pagespeed UseNativeFetcher "@@NATIVE_FETCHER@@";
@@RESOLVER@@
server {
# This server represents the external caching layer server which
# receives user requests and proxies them to the upstream server
# running on the PRIMARY_PORT when the response is not available in
# the cache. It also services purge requests from the upstream server.
listen @@SECONDARY_PORT@@;
server_name proxy_cache.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed off;
set $ua_dependent_ps_capability_list "";
set $bypass_cache 1;
if ($http_user_agent ~* "Chrome/|Firefox/|MSIE |Safari|Wget") {
# User Agents that support lazyload-images (ll), inline-images (ii) and
# defer-javascript (dj).
set $ua_dependent_ps_capability_list "ll,ii,dj:";
set $bypass_cache 0;
}
if ($http_user_agent ~*
"Chrome/[2][3-9]+\.|Chrome/[[3-9][0-9]+\.|Chrome/[0-9]{3,}\.") {
# User Agents that support lazyload-images (ll), inline-images (ii),
# defer-javascript (dj), webp (jw) and webp-lossless (ws).
set $ua_dependent_ps_capability_list "ll,ii,dj,jw,ws:";
set $bypass_cache 0;
}
# All User Agents that represent
# 1) mobiles
# 2) tablets
# 3) desktop browsers that do not have defer-javascript capability at a minimum
# are made to go to the pagespeed server directly bypassing the proxy_cache.
if ($http_user_agent ~* "Firefox/[1-2]\.|MSIE [5-8]\.") {
set $ua_dependent_ps_capability_list "";
set $bypass_cache 1;
}
if ($http_user_agent ~* "Mozilla.*Android.*Mobile*|iPhone|BlackBerry|Opera Mobi|Opera Mini|SymbianOS|UP.Browser|J-PHONE|Profile/MIDP|portalmmm|DoCoMo|Obigo") {
# These are Mobile User Agents. We don't cache responses for these.
set $ua_dependent_ps_capability_list "";
set $bypass_cache 1;
}
if ($http_user_agent ~* "Android|iPad|TouchPad|Silk-Accelerated|Kindle Fire") {
# These are Tablet User Agents. We don't cache responses for these.
set $ua_dependent_ps_capability_list "";
set $bypass_cache 1;
}
location ~ /purge(/.*) {
allow all;
proxy_cache_purge htmlcache $ua_dependent_ps_capability_list$1$is_args$args;
}
location /mod_pagespeed_test/cachable_rewritten_html/ {
proxy_pass http://localhost:@@PRIMARY_PORT@@;
proxy_set_header Host $host;
proxy_cache_valid 200 30s;
proxy_cache htmlcache;
proxy_ignore_headers Cache-Control;
add_header X-Cache $upstream_cache_status;
proxy_cache_key $ua_dependent_ps_capability_list$uri$is_args$args;
proxy_cache_bypass $bypass_cache;
}
}
server {
listen @@SECONDARY_PORT@@;
server_name mpd.example.com;
@@ -122,6 +200,16 @@ http {
pagespeed CriticalImagesBeaconEnabled true;
}
server {
listen @@SECONDARY_PORT@@;
server_name renderedimagebeacon.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters resize_rendered_image_dimensions;
pagespeed CriticalImagesBeaconEnabled true;
}
server {
# Sets up a virtual host where we can specify forbidden filters without
# affecting any other hosts.
@@ -140,6 +228,21 @@ http {
pagespeed DisableFilters inline_css;
}
server {
listen @@SECONDARY_PORT@@;
server_name client-domain-rewrite.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
# Don't actually try to rewrite any resources; the ones in
# rewrite_domains.html don't actually exist.
pagespeed RewriteLevel PassThrough;
pagespeed MapRewriteDomain http://client-domain-rewrite.example.com
http://src.example.com;
pagespeed ClientDomainRewrite true;
pagespeed EnableFilters rewrite_domains;
}
server {
listen @@SECONDARY_PORT@@;
server_name url-attribute.example.com;
@@ -159,6 +262,9 @@ http {
pagespeed UrlValuedAttribute custom a Image;
pagespeed UrlValuedAttribute custom b otherResource;
pagespeed UrlValuedAttribute custom c hyperlink;
pagespeed UrlValuedAttribute img alt-src Image;
pagespeed UrlValuedAttribute video alt-a Image;
pagespeed UrlValuedAttribute video alt-b Image;
}
server {
@@ -390,6 +496,125 @@ http {
pagespeed EnableFilters rewrite_images;
}
server {
listen @@SECONDARY_PORT@@;
server_name keepalive-html.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
pagespeed RewriteLevel CoreFilters;
error_log "@@TEST_TMP@@/keepalive-html.example.com.error.log" warn;
}
server {
listen @@SECONDARY_PORT@@;
server_name keepalive-resource.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
error_log "@@TEST_TMP@@/keepalive-resource.example.com.error.log" warn;
}
server {
listen @@SECONDARY_PORT@@;
server_name keepalive-beacon-get.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
error_log "@@TEST_TMP@@/keepalive-beacon-get.example.com.error.log" warn;
}
server {
listen @@SECONDARY_PORT@@;
server_name keepalive-beacon-post.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
error_log "@@TEST_TMP@@/keepalive-beacon-post.example.com.error.log" warn;
}
server {
listen @@SECONDARY_PORT@@;
server_name keepalive-static.example.com;
pagespeed FileCachePath "@@FILE_CACHE@@";
error_log "@@TEST_TMP@@/keepalive-static.example.com.error.log" warn;
}
server {
listen @@SECONDARY_PORT@@;
server_name response-header-filters.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed RewriteLevel PassThrough;
pagespeed on;
add_header PageSpeedFilters add_instrumentation;
}
server {
listen @@SECONDARY_PORT@@;
server_name response-header-disable.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters add_instrumentation;
pagespeed on;
add_header PageSpeed off;
}
server {
listen @@SECONDARY_PORT@@;
server_name ipro.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed on;
pagespeed InPlaceResourceOptimization on;
location /mod_pagespeed_test/ipro/nocache/test_image_dont_reuse.png {
add_header Cache-Control no-cache;
}
}
# Test hosts to cover all possible cache configurations. L1 will be filecache
# or memcache depending on the setting of MEMCACHED_TEST. These four hosts
# are for the four settings for the L2 cache.
# 1. L2_d=LRU, L2_m=LRU
server {
listen @@SECONDARY_PORT@@;
server_name lrud-lrum.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@_lrud_lrum";
pagespeed LRUCacheKbPerProcess 1024;
pagespeed LRUCacheByteLimit 2000;
pagespeed EnableFilters rewrite_images;
pagespeed CriticalImagesBeaconEnabled false;
}
# 2. L2_d=LRU, L2_m=SHM
pagespeed CreateSharedMemoryMetadataCache
"@@SECONDARY_CACHE@@_lrud_shmm" 8192;
server {
listen @@SECONDARY_PORT@@;
server_name lrud-shmm.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@_lrud_shmm";
pagespeed LRUCacheKbPerProcess 1024;
pagespeed LRUCacheByteLimit 2000;
pagespeed EnableFilters rewrite_images;
pagespeed CriticalImagesBeaconEnabled false;
}
# 3. L2_d=none, L2_m=SHM
pagespeed CreateSharedMemoryMetadataCache
"@@SECONDARY_CACHE@@_noned_shmm" 8192;
server {
listen @@SECONDARY_PORT@@;
server_name noned-shmm.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@_noned_shmm";
pagespeed EnableFilters rewrite_images;
pagespeed CriticalImagesBeaconEnabled false;
}
# 4. L2_d=none, L2_m=none
server {
listen @@SECONDARY_PORT@@;
server_name noned-nonem.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@_noned_nonem";
pagespeed EnableFilters rewrite_images;
pagespeed CriticalImagesBeaconEnabled false;
}
server {
listen @@PRIMARY_PORT@@;
server_name localhost;
@@ -399,6 +624,26 @@ http {
add_header "" "";
}
location /mod_pagespeed_test/cachable_rewritten_html/ {
# This location has the html files that will be configured to be stored
# in the proxy_cache layer.
pagespeed DownstreamCachePurgeMethod "GET";
pagespeed DownstreamCachePurgeLocationPrefix "http://localhost:@@SECONDARY_PORT@@/purge";
# We use a very small deadline here to force the rewriting to not complete
# in the very first attempt.
pagespeed RewriteDeadlinePerFlushMs 1;
pagespeed RewriteLevel PassThrough;
pagespeed EnableFilters collapse_whitespace,extend_cache,recompress_images,convert_jpeg_to_webp,defer_javascript;
}
location /mod_pagespeed_test/disable_no_transform/index.html {
pagespeed DisableRewriteOnNoTransform off;
}
location /mod_pagespeed_test/disable_no_transform/disable_no_transform.css {
add_header 'Cache-Control' 'no-transform';
}
# uncomment the following two lines if you're testing memcached
#pagespeed MemcachedServers "localhost:11211";
#pagespeed MemcachedThreads 1;
@@ -444,6 +689,12 @@ http {
# As opposed to mod_pagespeed, our default for aris is 'on'
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";
}
location /mod_pagespeed_test/forbid_all_disabled/disabled {
# Prevent the enabling of these filters for files in this directory
# -and- all subdirectories.
@@ -512,6 +763,12 @@ http {
add_header Cache-Control "private, max-age=3000";
}
location /mod_pagespeed_test/retain_cache_control_with_downstream_caching/ {
pagespeed ModifyCachingHeaders on;
pagespeed DownstreamCachePurgeLocationPrefix "http://localhost:8020/";
add_header Cache-Control "private, max-age=3000";
}
location /mod_pagespeed_test/avoid_renaming_introspective_javascript__on/ {
pagespeed AvoidRenamingIntrospectiveJavascript on;
}
@@ -520,6 +777,10 @@ http {
pagespeed DisableFilters convert_jpeg_to_progressive;
}
location /mod_pagespeed_test/ipro/test_image_dont_reuse.png {
expires 5m;
}
pagespeed EnableFilters remove_comments;
# Test LoadFromFile mapping by mapping one dir to another.