Compare commits

...

39 Commits

Author SHA1 Message Date
Jeffrey Crowell 79f98b197e release version 1.9.32.10 -> 1.9.32.11 2015-12-10 10:05:43 -05:00
Jeffrey Crowell 4103004cee update config for 1.9.32.10 2015-10-08 17:26:44 -04:00
Jeff Kaufman 0f3f268b36 Revert "Revert "Handle DoneAndSetHeaders() new second argument that wants to know whether the response is complete.""
Needed for 1.9.32.6 to build.

This reverts commit 19ebf69bad.
2015-07-30 07:27:19 -04:00
Jeffrey Crowell 30fdd02d0c Merge pull request #999 from pagespeed/release-1.9.32.6-beta
release: version 1.9.32.4 -> 1.9.32.6
2015-07-29 16:07:45 -04:00
Jeffrey Crowell 0572a5bebf release: version 1.9.32.4 -> 1.9.32.6 2015-07-29 14:33:57 -04:00
Jeff Kaufman 4bd5b7c663 Merge pull request #997 from pagespeed/jefftk-backport-864-fix
backport #864 fix for bugfix release
2015-07-28 13:26:45 -04:00
Otto van der Schaaf a9c292d8dc server-header: improve handling of server header
- Fixes an issue in the html flow that would prevent overriding the
value of the 'Server' response-header.
- Add tests that ensure we emit a single and correct server header
in all flows when not overriding it.
- Add tests that ensure overriding the 'Server' response header
works. The resource and IPRO flow are added to the expected failures
as those are not working yet (and will be adressed in a follow-up).

Fixed https://github.com/pagespeed/ngx_pagespeed/issues/864 (html flow)
2015-07-28 11:32:55 -04:00
Jeffrey Crowell 907c57a217 add test servers for sending x-sendfile and x-accel-redirect 2015-07-23 17:36:54 -04:00
Jan-Willem Maessen a7bef40eac Fix pagespeed_libraries_generator.sh to fetch pagespeed_libraries.conf from github rather than svn. 2015-07-09 10:19:37 -04:00
Jeffrey Crowell af5c568a92 Merge remote-tracking branch 'origin/release-1.9.32.4-beta' 2015-06-17 14:15:19 -04:00
Jeffrey Crowell 5cc1ffb352 release: version 1.9.32.3 -> 1.9.32.4 2015-06-17 14:08:47 -04:00
Jeffrey Crowell d01093ba9b release: version 1.9.32.3 -> 1.9.32.4 2015-06-17 11:40:05 -04:00
Jeffrey Crowell a578057e2f fix tab/space. 2015-06-10 13:01:26 -04:00
Jeffrey Crowell 5bd43dce9a fix backport of fix for #965
was missing
ctx->base_fetch->SetRequestHeadersTakingOwnership(request_headers).
2015-06-10 11:44:46 -04:00
Jeffrey Crowell 19ebf69bad Revert "Handle DoneAndSetHeaders() new second argument that wants to know whether the response is complete."
This reverts commit 4df7460d62.
2015-06-10 11:33:05 -04:00
Jeff Kaufman 4df7460d62 Handle DoneAndSetHeaders() new second argument that wants to know whether the response is complete. 2015-05-15 11:30:04 -04:00
Jeffrey Crowell c5c443f256 add psol tar.gz to gitignore 2015-05-13 11:56:56 -04:00
Jeffrey Crowell b9ca5d865d backport @oschaff fix of #965
fix issue of PageSpeed silently crashing returning partial web pages

backported from commit a5411a1c7c
2015-05-13 11:48:43 -04:00
Jeffrey Crowell 0cf3f1c6d7 Merge pull request #951 from pagespeed/crowell-build_clang
initialize uninitialized variables.
2015-04-01 15:44:56 -04:00
Jeffrey Crowell 7857bab7fb Merge pull request #949 from pagespeed/crowell-with_threads
add support for nginx 1.7.11 --with-threads
2015-04-01 15:09:49 -04:00
Jeffrey Crowell b11ab687c1 initialize uninitialized variables. 2015-04-01 14:49:31 -04:00
Jeffrey Crowell a81cc997a9 add support for nginx 1.7.11 --with-threads 2015-04-01 14:11:00 -04:00
Otto van der Schaaf 4c9298446c Merge pull request #916 from pagespeed/oschaaf-date-header-32-bits-issue
date-header: fix 32 bits issue
2015-02-17 15:25:37 +01:00
Otto van der Schaaf 7355f2e207 date-header: fix 32 bits issue
Should fix https://github.com/pagespeed/ngx_pagespeed/issues/913
2015-02-16 23:42:54 +01:00
Jeffrey Crowell 9da85bb9d5 Replace CHECK with return failure and log.
Fixes #888 along with
https://code.google.com/p/modpagespeed/source/detail?r=4533
2015-01-30 10:29:05 -05:00
Otto van der Schaaf 90ac91fe9e Merge pull request #816 from pagespeed/oschaaf-gzip-vs-etag
gzip-vs-etag: Don't rename the ETag when gzip isn't ./configured
2015-01-08 18:00:42 +01:00
Jeffrey Crowell da466c1487 release: 1.9.32.2 -> 1.9.32.3 2014-12-22 10:10:05 -05:00
Jeff Kaufman 2a409777dc Merge pull request #859 from We-Amp/keesspoelstra-gzip-init-fix
NgxGZipSetter fix, at config reload Init did not work as expected (Issue 844)
2014-12-10 07:44:46 -05:00
keesspoelstra c3f41512cf NgxGZipSetter fix, at config reload Init did not work as expected (Issue 844) 2014-12-09 20:47:48 +01:00
Jeff Kaufman 0980633dd2 Merge pull request #858 from vlajos/typofixes-vlajos-20141204
typofixes - https://github.com/vlajos/misspell_fixer
2014-12-05 08:28:55 -05:00
Veres Lajos c1c83aa69b typofixes - https://github.com/vlajos/misspell_fixer 2014-12-04 22:56:03 +00:00
Otto van der Schaaf b037cc2b3e gzip-vs-etag: Don't rename the ETag when gzip isn't ./configured
We should not rename the ETag header to work around the gzip module
clearing it, when the gzip module actually isn't built. In that case
we will fail to inject the header filter that renames the header back
to 'ETag' before it gets send out.

Fixes https://github.com/pagespeed/ngx_pagespeed/issues/770
2014-11-14 10:42:49 +01:00
Otto van der Schaaf 4885d44f69 native-fetcher: remove a DCHECK that possibly fires on shutdown. 2014-11-10 13:24:17 -05:00
Otto van der Schaaf 7b84f92adf Merge pull request #838 from pagespeed/oschaaf-gzip-rollback-message
gzip-rollback-message: Demote a log message from info to debug
2014-10-30 09:48:50 +01:00
Jeffrey Crowell a403e62074 Check type of resolver_ctx->addrs.
Check the type of resolver_ctx->addrs and make sure that it is
ngx_addr_t* instead of in_addr_t*. addresses issue #839
2014-10-29 15:14:22 -04:00
Jeffrey Crowell b5dc1083f4 Readd pthread_mutex.h include on ngx_fetch.cc.
Messed up the merge of 0290f52a88 originally, add the include back.
2014-10-27 14:51:45 -04:00
Otto van der Schaaf ab9929e5a5 native fetcher: Support http keep-alive
Based on @dinic his work, add keep-alive support for the native fetcher.
Adds a new option, usable at the http{} level in configuration:

pagespeed NativeFetcherMaxKeepaliveRequests 50;

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

Most notable changes:
- Request keep-alive by adding the appropriate request header
- Fixes connections getting reused while they are servicing other requests:
- Remove connection from the pool of available connections for keepalive when applicable
- Disable keepalive in more appropriate situations
- Response parsing fixes
- Remove connections that timeout from the k.a. pool
- Add a few sanity (D)CHECKS
- Emit debug messages for traceability
- Fix for ignoring ipv6 addresses returned from dns queries when ipv6 is enabled.
- Bump the fetch timeout in test configuration to deflake tests that require dns
  lookups (which will be done via 8.8.8.8 currently for the native fetcher)

Conflicts:
	src/ngx_fetch.cc
2014-10-24 16:23:45 -04:00
Jeffrey Crowell 9832a049fe release: version 1.9.32.1 -> 1.9.32.2 2014-10-24 15:49:48 -04:00
Otto van der Schaaf 14822570c4 gzip-rollback-message: Demote a log message from info to debug
Fixes https://github.com/pagespeed/ngx_pagespeed/issues/832
2014-10-21 05:57:25 +02:00
18 changed files with 1020 additions and 540 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
test/tmp test/tmp
psol/ psol/
psol-*.tar.gz psol-*.tar.gz
*.*.*.*.tar.gz
+3 -3
View File
@@ -27,8 +27,8 @@ if [ "$mod_pagespeed_dir" = "unset" ] ; then
echo " You need to separately download the pagespeed library:" echo " You need to separately download the pagespeed library:"
echo "" echo ""
echo " $ cd /path/to/ngx_pagespeed" echo " $ cd /path/to/ngx_pagespeed"
echo " $ wget https://dl.google.com/dl/page-speed/psol/1.9.32.1.tar.gz" echo " $ wget https://dl.google.com/dl/page-speed/psol/1.9.32.11.tar.gz"
echo " $ tar -xzvf 1.9.32.1.tar.gz # expands to psol/" echo " $ tar -xzvf 1.9.32.11.tar.gz # expands to psol/"
echo "" echo ""
echo " Or see the installation instructions:" echo " Or see the installation instructions:"
echo " https://github.com/pagespeed/ngx_pagespeed#how-to-build" echo " https://github.com/pagespeed/ngx_pagespeed#how-to-build"
@@ -205,7 +205,7 @@ if [ $ngx_found = yes ]; then
else else
cat << END cat << END
$0: error: module ngx_pagespeed requires the pagespeed optimization library. $0: error: module ngx_pagespeed requires the pagespeed optimization library.
Look in obj/autoconf.err for more details. Look in objs/autoconf.err for more details.
END END
exit 1 exit 1
fi fi
+2 -2
View File
@@ -13,9 +13,9 @@
# Author: vid@zippykid.com (Vid Luther) # Author: vid@zippykid.com (Vid Luther)
# jefftk@google.com (Jeff Kaufman) # jefftk@google.com (Jeff Kaufman)
URL="https://modpagespeed.googlecode.com/svn/trunk/src/" URL="https://github.com/pagespeed/mod_pagespeed/raw/master/"
URL+="net/instaweb/genfiles/conf/pagespeed_libraries.conf" URL+="net/instaweb/genfiles/conf/pagespeed_libraries.conf"
curl -s "$URL" \ curl -L -s -S "$URL" \
| grep ModPagespeedLibrary \ | grep ModPagespeedLibrary \
| while read library size hash url ; do | while read library size hash url ; do
echo " pagespeed Library $size $hash $url;" echo " pagespeed Library $size $hash $url;"
+1 -1
View File
@@ -144,7 +144,7 @@ void NgxBaseFetch::HandleHeadersComplete() {
} }
} }
// For the IPRO lookup, supress notification of the nginx side here. // For the IPRO lookup, suppress notification of the nginx side here.
// If we send both this event and the one from done, nasty stuff will happen // If we send both this event and the one from done, nasty stuff will happen
// if we loose the race with with the nginx side destructing this base fetch // if we loose the race with with the nginx side destructing this base fetch
// instance (and thereby clearing the byte and its pending extraneous event. // instance (and thereby clearing the byte and its pending extraneous event.
+816 -476
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -51,12 +51,13 @@ namespace net_instaweb {
typedef bool (*response_handler_pt)(ngx_connection_t* c); typedef bool (*response_handler_pt)(ngx_connection_t* c);
class NgxUrlAsyncFetcher; class NgxUrlAsyncFetcher;
class NgxConnection;
class NgxFetch : public PoolElement<NgxFetch> { class NgxFetch : public PoolElement<NgxFetch> {
public: public:
NgxFetch(const GoogleString& url, NgxFetch(const GoogleString& url,
AsyncFetch* async_fetch, AsyncFetch* async_fetch,
MessageHandler* message_handler, MessageHandler* message_handler,
ngx_msec_t timeout_ms,
ngx_log_t* log); ngx_log_t* log);
~NgxFetch(); ~NgxFetch();
@@ -112,19 +113,19 @@ class NgxFetch : public PoolElement<NgxFetch> {
response_handler = handler; response_handler = handler;
} }
// Only the Static functions could be used in callbacks. // Only the Static functions could be used in callbacks.
static void NgxFetchResolveDone(ngx_resolver_ctx_t* ctx); static void ResolveDoneHandler(ngx_resolver_ctx_t* ctx);
// Write the request. // Write the request.
static void NgxFetchWrite(ngx_event_t* wev); static void ConnectionWriteHandler(ngx_event_t* wev);
// Wait for the response. // Wait for the response.
static void NgxFetchRead(ngx_event_t* rev); static void ConnectionReadHandler(ngx_event_t* rev);
// Read and parse the first status line. // Read and parse the first status line.
static bool NgxFetchHandleStatusLine(ngx_connection_t* c); static bool HandleStatusLine(ngx_connection_t* c);
// Read and parse the HTTP headers. // Read and parse the HTTP headers.
static bool NgxFetchHandleHeader(ngx_connection_t* c); static bool HandleHeader(ngx_connection_t* c);
// Read the response body. // Read the response body.
static bool NgxFetchHandleBody(ngx_connection_t* c); static bool HandleBody(ngx_connection_t* c);
// Cancel the fetch when it's timeout. // Cancel the fetch when it's timeout.
static void NgxFetchTimeout(ngx_event_t* tev); static void TimeoutHandler(ngx_event_t* tev);
// Add the pagespeed User-Agent. // Add the pagespeed User-Agent.
void FixUserAgent(); void FixUserAgent();
@@ -139,7 +140,6 @@ class NgxFetch : public PoolElement<NgxFetch> {
int64 bytes_received_; int64 bytes_received_;
int64 fetch_start_ms_; int64 fetch_start_ms_;
int64 fetch_end_ms_; int64 fetch_end_ms_;
int64 timeout_ms_;
bool done_; bool done_;
int64 content_length_; int64 content_length_;
bool content_length_known_; bool content_length_known_;
@@ -152,7 +152,7 @@ class NgxFetch : public PoolElement<NgxFetch> {
ngx_http_request_t* r_; ngx_http_request_t* r_;
ngx_http_status_t* status_; ngx_http_status_t* status_;
ngx_event_t* timeout_event_; ngx_event_t* timeout_event_;
ngx_connection_t* connection_; NgxConnection* connection_;
ngx_resolver_ctx_t* resolver_ctx_; ngx_resolver_ctx_t* resolver_ctx_;
DISALLOW_COPY_AND_ASSIGN(NgxFetch); DISALLOW_COPY_AND_ASSIGN(NgxFetch);
+15 -4
View File
@@ -70,7 +70,7 @@ extern "C" {
} }
} }
NgxGZipSetter::NgxGZipSetter() : enabled_(0) { } NgxGZipSetter::NgxGZipSetter() : enabled_(false), initialized_(false) { }
NgxGZipSetter::~NgxGZipSetter() { } NgxGZipSetter::~NgxGZipSetter() { }
// Helper functions to determine signature. // Helper functions to determine signature.
@@ -95,7 +95,7 @@ bool IsNgxBitmaskCommand(ngx_command_t* command) {
HasLocalConfig(command)); HasLocalConfig(command));
} }
// Initialize the NgxGzipSetter. // Initialize the NgxGZipSetter.
// Find the gzip, gzip_vary, gzip_http_version and gzip_types commands in the // Find the gzip, gzip_vary, gzip_http_version and gzip_types commands in the
// gzip module. Enable if the signature of the zip command matches with what we // gzip module. Enable if the signature of the zip command matches with what we
// trust. Also sets up redirects for the configurations. These redirect handle // trust. Also sets up redirects for the configurations. These redirect handle
@@ -105,6 +105,16 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
#if (NGX_HTTP_GZIP) #if (NGX_HTTP_GZIP)
bool gzip_signature_mismatch = false; bool gzip_signature_mismatch = false;
bool other_signature_mismatch = false; bool other_signature_mismatch = false;
// If we initialized already we don't have to scan again.
if (initialized_) {
// Config might have changed, so re-enable if we have gzip.
if (gzip_command_.command_ != NULL) {
enabled_ = true;
} else {
enabled_ = false;
}
return;
}
for (int m = 0; ngx_modules[m] != NULL; m++) { for (int m = 0; ngx_modules[m] != NULL; m++) {
if (ngx_modules[m]->commands != NULL) { if (ngx_modules[m]->commands != NULL) {
for (int c = 0; ngx_modules[m]->commands[c].name.len; c++) { for (int c = 0; ngx_modules[m]->commands[c].name.len; c++) {
@@ -122,7 +132,7 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
current_command->set = ngx_gzip_redirect_conf_set_flag_slot; current_command->set = ngx_gzip_redirect_conf_set_flag_slot;
gzip_command_.command_ = current_command; gzip_command_.command_ = current_command;
gzip_command_.module_ = ngx_modules[m]; gzip_command_.module_ = ngx_modules[m];
enabled_ = 1; enabled_ = true;
} else { } else {
ngx_conf_log_error( ngx_conf_log_error(
NGX_LOG_WARN, cf, 0, NGX_LOG_WARN, cf, 0,
@@ -189,6 +199,7 @@ void NgxGZipSetter::Init(ngx_conf_t* cf) {
} }
} }
} }
initialized_ = true;
if (gzip_signature_mismatch) { if (gzip_signature_mismatch) {
return; // Already logged error. return; // Already logged error.
} else if (!enabled_) { } else if (!enabled_) {
@@ -381,7 +392,7 @@ void NgxGZipSetter::AddGZipHTTPTypes(ngx_conf_t* cf) {
} }
void NgxGZipSetter::RollBackAndDisable(ngx_conf_t* cf) { void NgxGZipSetter::RollBackAndDisable(ngx_conf_t* cf) {
ngx_conf_log_error(NGX_LOG_INFO, cf, 0, ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0,
"pagespeed: rollback gzip, explicit configuration"); "pagespeed: rollback gzip, explicit configuration");
for (std::vector<ngx_flag_t*>::iterator i = ngx_flags_set_.begin(); for (std::vector<ngx_flag_t*>::iterator i = ngx_flags_set_.begin();
i != ngx_flags_set_.end(); ++i) { i != ngx_flags_set_.end(); ++i) {
+1
View File
@@ -91,6 +91,7 @@ class NgxGZipSetter {
ngx_command_ctx gzip_vary_command_; ngx_command_ctx gzip_vary_command_;
ngx_command_ctx gzip_http_version_command_; ngx_command_ctx gzip_http_version_command_;
bool enabled_; bool enabled_;
bool initialized_;
public: public:
NgxGZipSetter(); NgxGZipSetter();
+4
View File
@@ -18,6 +18,10 @@
#define NGX_MESSAGE_HANDLER_H_ #define NGX_MESSAGE_HANDLER_H_
extern "C" { extern "C" {
#include <ngx_auto_config.h>
#if (NGX_THREADS)
#include <ngx_thread.h>
#endif
#include <ngx_core.h> #include <ngx_core.h>
#include <ngx_log.h> #include <ngx_log.h>
} }
+42 -36
View File
@@ -295,7 +295,8 @@ void copy_response_headers_from_ngx(const ngx_http_request_t* r,
// When we don't have a date header, set one with the current time. // When we don't have a date header, set one with the current time.
if (headers->Lookup1(HttpAttributes::kDate) == NULL) { if (headers->Lookup1(HttpAttributes::kDate) == NULL) {
headers->SetDate(ngx_current_msec); PosixTimer timer;
headers->SetDate(timer.NowMs());
} }
// TODO(oschaaf): ComputeCaching should be called in setupforhtml()? // TODO(oschaaf): ComputeCaching should be called in setupforhtml()?
@@ -342,10 +343,17 @@ ngx_int_t copy_response_headers_to_ngx(
ngx_str_t name, value; ngx_str_t name, value;
// If the gzip module is not configured, we must not rename the header,
// because we will fail to inject the header filter that will rename the
// header back.
bool gzip_enabled = false;
#if (NGX_HTTP_GZIP)
gzip_enabled = true;
#endif
// To prevent the gzip module from clearing weak etags, we output them // To prevent the gzip module from clearing weak etags, we output them
// using a different name here. The etag header filter module runs behind // using a different name here. The etag header filter module runs behind
// the gzip compressors header filter, and will rename it to 'ETag' // the gzip compressors header filter, and will rename it to 'ETag'
if (StringCaseEqual(name_gs, "etag") if (gzip_enabled && StringCaseEqual(name_gs, "etag")
&& StringCaseStartsWith(value_gs, "W/")) { && StringCaseStartsWith(value_gs, "W/")) {
name.len = strlen(kInternalEtagName); name.len = strlen(kInternalEtagName);
name.data = reinterpret_cast<u_char*>( name.data = reinterpret_cast<u_char*>(
@@ -354,6 +362,7 @@ ngx_int_t copy_response_headers_to_ngx(
name.len = name_gs.length(); name.len = name_gs.length();
name.data = reinterpret_cast<u_char*>(const_cast<char*>(name_gs.data())); name.data = reinterpret_cast<u_char*>(const_cast<char*>(name_gs.data()));
} }
value.len = value_gs.length(); value.len = value_gs.length();
value.data = reinterpret_cast<u_char*>(const_cast<char*>(value_gs.data())); value.data = reinterpret_cast<u_char*>(const_cast<char*>(value_gs.data()));
@@ -401,8 +410,6 @@ ngx_int_t copy_response_headers_to_ngx(
continue; continue;
} else if (STR_EQ_LITERAL(name, "Transfer-Encoding")) { } else if (STR_EQ_LITERAL(name, "Transfer-Encoding")) {
continue; continue;
} else if (STR_EQ_LITERAL(name, "Server")) {
continue;
} }
u_char* name_s = ngx_pstrdup(r->pool, &name); u_char* name_s = ngx_pstrdup(r->pool, &name);
@@ -1630,7 +1637,8 @@ void ps_release_base_fetch(ps_request_ctx_t* ctx) {
// TODO(chaizhenhua): merge into NgxBaseFetch ctor // TODO(chaizhenhua): merge into NgxBaseFetch ctor
ngx_int_t ps_create_base_fetch(ps_request_ctx_t* ctx, ngx_int_t ps_create_base_fetch(ps_request_ctx_t* ctx,
RequestContextPtr request_context) { RequestContextPtr request_context,
RequestHeaders* request_headers) {
ngx_http_request_t* r = ctx->r; ngx_http_request_t* r = ctx->r;
ps_srv_conf_t* cfg_s = ps_get_srv_config(r); ps_srv_conf_t* cfg_s = ps_get_srv_config(r);
int file_descriptors[2]; int file_descriptors[2];
@@ -1673,6 +1681,7 @@ ngx_int_t ps_create_base_fetch(ps_request_ctx_t* ctx,
ctx->base_fetch = new NgxBaseFetch( ctx->base_fetch = new NgxBaseFetch(
r, file_descriptors[1], cfg_s->server_context, r, file_descriptors[1], cfg_s->server_context,
request_context, ctx->preserve_caching_headers); request_context, ctx->preserve_caching_headers);
ctx->base_fetch->SetRequestHeadersTakingOwnership(request_headers);
return NGX_OK; return NGX_OK;
} }
@@ -1700,8 +1709,8 @@ void ps_release_request_context(void* data) {
} }
if (ctx->recorder != NULL) { if (ctx->recorder != NULL) {
ctx->recorder->Fail(); // Deletes recorder.
ctx->recorder->DoneAndSetHeaders(NULL); // Deletes recorder. ctx->recorder->DoneAndSetHeaders(NULL, false /* incomplete response */);
ctx->recorder = NULL; ctx->recorder = NULL;
} }
@@ -1808,7 +1817,10 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
GoogleString url_string = ps_determine_url(r); GoogleString url_string = ps_determine_url(r);
GoogleUrl url(url_string); GoogleUrl url(url_string);
CHECK(url.IsWebValid()); if (!url.IsWebValid()) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "invalid url");
return NGX_DECLINED;
}
scoped_ptr<RequestHeaders> request_headers(new RequestHeaders); scoped_ptr<RequestHeaders> request_headers(new RequestHeaders);
scoped_ptr<ResponseHeaders> response_headers(new ResponseHeaders); scoped_ptr<ResponseHeaders> response_headers(new ResponseHeaders);
@@ -1923,35 +1935,17 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
ngx_http_set_ctx(r, ctx, ngx_pagespeed); ngx_http_set_ctx(r, ctx, ngx_pagespeed);
} }
if (ps_create_base_fetch(ctx, request_context) != NGX_OK) {
// Do not need to release request context 'ctx'.
// http_pool_cleanup will call ps_release_request_context
return NGX_ERROR;
}
ctx->base_fetch->SetRequestHeadersTakingOwnership(request_headers.release());
bool page_callback_added = false;
scoped_ptr<ProxyFetchPropertyCallbackCollector>
property_callback(
ProxyFetchFactory::InitiatePropertyCacheLookup(
!html_rewrite /* is_resource_fetch */,
url,
cfg_s->server_context,
options,
ctx->base_fetch,
false /* requires_blink_cohort (no longer unused) */,
&page_callback_added));
if (pagespeed_resource) { if (pagespeed_resource) {
// TODO(jefftk): Set using_spdy appropriately. See // TODO(jefftk): Set using_spdy appropriately. See
// ProxyInterface::ProxyRequestCallback // ProxyInterface::ProxyRequestCallback
ps_create_base_fetch(ctx, request_context, request_headers.release());
ResourceFetch::Start( ResourceFetch::Start(
url, url,
custom_options.release() /* null if there aren't custom options */, custom_options.release() /* null if there aren't custom options */,
false /* using_spdy */, cfg_s->server_context, ctx->base_fetch); false /* using_spdy */, cfg_s->server_context, ctx->base_fetch);
return ps_async_wait_response(r); return ps_async_wait_response(r);
} else if (is_an_admin_handler) { } else if (is_an_admin_handler) {
ps_create_base_fetch(ctx, request_context, request_headers.release());
QueryParams query_params; QueryParams query_params;
query_params.ParseFromUrl(url); query_params.ParseFromUrl(url);
@@ -1995,6 +1989,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
} }
if (html_rewrite) { if (html_rewrite) {
ps_create_base_fetch(ctx, request_context, request_headers.release());
// Do not store driver in request_context, it's not safe. // Do not store driver in request_context, it's not safe.
RewriteDriver* driver; RewriteDriver* driver;
@@ -2021,12 +2016,22 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
driver->set_pagespeed_option_cookies(pagespeed_option_cookies); driver->set_pagespeed_option_cookies(pagespeed_option_cookies);
// TODO(jefftk): FlushEarlyFlow would go here. // TODO(jefftk): FlushEarlyFlow would go here.
bool page_callback_added = false;
ProxyFetchPropertyCallbackCollector* property_callback =
ProxyFetchFactory::InitiatePropertyCacheLookup(
!html_rewrite /* is_resource_fetch */,
url,
cfg_s->server_context,
options,
ctx->base_fetch,
false /* requires_blink_cohort (no longer unused) */,
&page_callback_added);
// Will call StartParse etc. The rewrite driver will take care of deleting // Will call StartParse etc. The rewrite driver will take care of deleting
// itself if necessary. // itself if necessary.
ctx->proxy_fetch = cfg_s->proxy_fetch_factory->CreateNewProxyFetch( ctx->proxy_fetch = cfg_s->proxy_fetch_factory->CreateNewProxyFetch(
url_string, ctx->base_fetch, driver, url_string, ctx->base_fetch, driver,
property_callback.release(), property_callback,
NULL /* original_content_fetch */); NULL /* original_content_fetch */);
return NGX_OK; return NGX_OK;
} }
@@ -2034,6 +2039,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
if (options->in_place_rewriting_enabled() && if (options->in_place_rewriting_enabled() &&
options->enabled() && options->enabled() &&
options->IsAllowed(url.Spec())) { options->IsAllowed(url.Spec())) {
ps_create_base_fetch(ctx, request_context, request_headers.release());
// Do not store driver in request_context, it's not safe. // Do not store driver in request_context, it's not safe.
RewriteDriver* driver; RewriteDriver* driver;
if (custom_options.get() == NULL) { if (custom_options.get() == NULL) {
@@ -2073,8 +2079,7 @@ ngx_int_t ps_resource_handler(ngx_http_request_t* r,
"Passing on content handling for non-pagespeed resource '%s'", "Passing on content handling for non-pagespeed resource '%s'",
url_string.c_str()); url_string.c_str());
ctx->base_fetch->Done(false); CHECK(ctx->base_fetch == NULL);
ps_release_base_fetch(ctx);
// set html_rewrite flag. // set html_rewrite flag.
ctx->html_rewrite = true; ctx->html_rewrite = true;
return NGX_DECLINED; return NGX_DECLINED;
@@ -2279,14 +2284,13 @@ ngx_int_t ps_html_rewrite_header_filter(ngx_http_request_t* r) {
if (!ps_has_stacked_content_encoding(r)) { if (!ps_has_stacked_content_encoding(r)) {
StringPiece content_encoding = StringPiece content_encoding =
str_to_string_piece(r->headers_out.content_encoding->value); str_to_string_piece(r->headers_out.content_encoding->value);
GzipInflater::InflateType inflate_type; GzipInflater::InflateType inflate_type = GzipInflater::kGzip;
bool is_encoded = false; bool is_encoded = false;
if (StringCaseEqual(content_encoding, "deflate")) { if (StringCaseEqual(content_encoding, "deflate")) {
is_encoded = true; is_encoded = true;
inflate_type = GzipInflater::kDeflate; inflate_type = GzipInflater::kDeflate;
} else if (StringCaseEqual(content_encoding, "gzip")) { } else if (StringCaseEqual(content_encoding, "gzip")) {
is_encoded = true; is_encoded = true;
inflate_type = GzipInflater::kGzip;
} }
if (is_encoded) { if (is_encoded) {
@@ -2502,7 +2506,9 @@ ngx_int_t ps_in_place_body_filter(ngx_http_request_t* r, ngx_chain_t* in) {
if (cl->buf->last_buf || recorder->failed()) { if (cl->buf->last_buf || recorder->failed()) {
ResponseHeaders response_headers; ResponseHeaders response_headers;
copy_response_headers_from_ngx(r, &response_headers); copy_response_headers_from_ngx(r, &response_headers);
ctx->recorder->DoneAndSetHeaders(&response_headers); ctx->recorder->DoneAndSetHeaders(
&response_headers,
cl->buf->last_buf /* response is complete if last_buf is set */);
ctx->recorder = NULL; ctx->recorder = NULL;
break; break;
} }
@@ -2699,8 +2705,8 @@ bool ps_request_body_to_string_piece(
if (ret < 0) { if (ret < 0) {
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"ps_request_body_to_string_piece: " "ps_request_body_to_string_piece: "
"error reading post body."); "error reading post body.");
return false; return false;
} }
+3
View File
@@ -78,6 +78,8 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(
log_(NULL), log_(NULL),
resolver_timeout_(NGX_CONF_UNSET_MSEC), resolver_timeout_(NGX_CONF_UNSET_MSEC),
use_native_fetcher_(false), use_native_fetcher_(false),
// 100 Aligns to nginx's server-side default.
native_fetcher_max_keepalive_requests_(100),
ngx_shared_circular_buffer_(NULL), ngx_shared_circular_buffer_(NULL),
hostname_(hostname.as_string()), hostname_(hostname.as_string()),
port_(port), port_(port),
@@ -112,6 +114,7 @@ UrlAsyncFetcher* NgxRewriteDriverFactory::AllocateFetcher(
resolver_timeout_, resolver_timeout_,
config->blocking_fetch_timeout_ms(), config->blocking_fetch_timeout_ms(),
resolver_, resolver_,
native_fetcher_max_keepalive_requests_,
thread_system(), thread_system(),
message_handler()); message_handler());
ngx_url_async_fetchers_.push_back(fetcher); ngx_url_async_fetchers_.push_back(fetcher);
+12
View File
@@ -20,6 +20,10 @@
#define NGX_REWRITE_DRIVER_FACTORY_H_ #define NGX_REWRITE_DRIVER_FACTORY_H_
extern "C" { extern "C" {
#include <ngx_auto_config.h>
#if (NGX_THREADS)
#include <ngx_thread.h>
#endif
#include <ngx_core.h> #include <ngx_core.h>
#include <ngx_http.h> #include <ngx_http.h>
#include <ngx_config.h> #include <ngx_config.h>
@@ -105,6 +109,12 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
void set_use_native_fetcher(bool x) { void set_use_native_fetcher(bool x) {
use_native_fetcher_ = x; use_native_fetcher_ = x;
} }
int native_fetcher_max_keepalive_requests() {
return native_fetcher_max_keepalive_requests_;
}
void set_native_fetcher_max_keepalive_requests(int x) {
native_fetcher_max_keepalive_requests_ = x;
}
bool process_script_variables() { bool process_script_variables() {
return process_script_variables_; return process_script_variables_;
} }
@@ -140,6 +150,8 @@ class NgxRewriteDriverFactory : public SystemRewriteDriverFactory {
ngx_msec_t resolver_timeout_; ngx_msec_t resolver_timeout_;
ngx_resolver_t* resolver_; ngx_resolver_t* resolver_;
bool use_native_fetcher_; bool use_native_fetcher_;
int native_fetcher_max_keepalive_requests_;
typedef std::set<NgxMessageHandler*> NgxMessageHandlerSet; typedef std::set<NgxMessageHandler*> NgxMessageHandlerSet;
NgxMessageHandlerSet server_context_message_handlers_; NgxMessageHandlerSet server_context_message_handlers_;
+14 -2
View File
@@ -72,12 +72,14 @@ const char* const server_only_options[] = {
"LoadFromFileMatch", "LoadFromFileMatch",
"LoadFromFileRule", "LoadFromFileRule",
"LoadFromFileRuleMatch", "LoadFromFileRuleMatch",
"UseNativeFetcher" "UseNativeFetcher",
"NativeFetcherMaxKeepaliveRequests"
}; };
// Options that can only be used in the main (http) option scope. // Options that can only be used in the main (http) option scope.
const char* const main_only_options[] = { const char* const main_only_options[] = {
"UseNativeFetcher" "UseNativeFetcher",
"NativeFetcherMaxKeepaliveRequests"
}; };
} // namespace } // namespace
@@ -343,6 +345,16 @@ const char* NgxRewriteOptions::ParseAndSetOptions(
result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>( result = ParseAndSetOptionHelper<NgxRewriteDriverFactory>(
arg, driver_factory, arg, driver_factory,
&NgxRewriteDriverFactory::set_use_native_fetcher); &NgxRewriteDriverFactory::set_use_native_fetcher);
} else if (IsDirective(directive, "NativeFetcherMaxKeepaliveRequests")) {
int max_keepalive_requests;
if (StringToInt(arg, &max_keepalive_requests) &&
max_keepalive_requests > 0) {
driver_factory->set_native_fetcher_max_keepalive_requests(
max_keepalive_requests);
result = RewriteOptions::kOptionOk;
} else {
result = RewriteOptions::kOptionValueInvalid;
}
} else if (StringCaseEqual("ProcessScriptVariables", args[0])) { } else if (StringCaseEqual("ProcessScriptVariables", args[0])) {
if (scope == RewriteOptions::kProcessScopeStrict) { if (scope == RewriteOptions::kProcessScopeStrict) {
if (StringCaseEqual(arg, "on")) { if (StringCaseEqual(arg, "on")) {
+1 -1
View File
@@ -48,7 +48,7 @@ SystemRequestContext* NgxServerContext::NewRequestContext(
ngx_http_request_t* r) { ngx_http_request_t* r) {
// Based on ngx_http_variable_server_port. // Based on ngx_http_variable_server_port.
bool port_set = false; bool port_set = false;
int local_port; int local_port = 0;
#if (NGX_HAVE_INET6) #if (NGX_HAVE_INET6)
if (r->connection->local_sockaddr->sa_family == AF_INET6) { if (r->connection->local_sockaddr->sa_family == AF_INET6) {
local_port = ntohs(reinterpret_cast<struct sockaddr_in6*>( local_port = ntohs(reinterpret_cast<struct sockaddr_in6*>(
+4 -2
View File
@@ -55,6 +55,7 @@ namespace net_instaweb {
ngx_msec_t resolver_timeout, ngx_msec_t resolver_timeout,
ngx_msec_t fetch_timeout, ngx_msec_t fetch_timeout,
ngx_resolver_t* resolver, ngx_resolver_t* resolver,
int max_keepalive_requests,
ThreadSystem* thread_system, ThreadSystem* thread_system,
MessageHandler* handler) MessageHandler* handler)
: fetchers_count_(0), : fetchers_count_(0),
@@ -63,7 +64,8 @@ namespace net_instaweb {
byte_count_(0), byte_count_(0),
thread_system_(thread_system), thread_system_(thread_system),
message_handler_(handler), message_handler_(handler),
mutex_(NULL) { mutex_(NULL),
max_keepalive_requests_(max_keepalive_requests) {
resolver_timeout_ = resolver_timeout; resolver_timeout_ = resolver_timeout;
fetch_timeout_ = fetch_timeout; fetch_timeout_ = fetch_timeout;
ngx_memzero(&proxy_, sizeof(proxy_)); ngx_memzero(&proxy_, sizeof(proxy_));
@@ -223,7 +225,7 @@ namespace net_instaweb {
AsyncFetch* async_fetch) { AsyncFetch* async_fetch) {
async_fetch = EnableInflation(async_fetch); async_fetch = EnableInflation(async_fetch);
NgxFetch* fetch = new NgxFetch(url, async_fetch, NgxFetch* fetch = new NgxFetch(url, async_fetch,
message_handler, fetch_timeout_, log_); message_handler, log_);
ScopedMutex lock(mutex_); ScopedMutex lock(mutex_);
pending_fetches_.Add(fetch); pending_fetches_.Add(fetch);
SendCmd('F'); SendCmd('F');
+4 -2
View File
@@ -53,12 +53,13 @@ class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
NgxUrlAsyncFetcher( NgxUrlAsyncFetcher(
const char* proxy, ngx_log_t* log, ngx_msec_t resolver_timeout, const char* proxy, ngx_log_t* log, ngx_msec_t resolver_timeout,
ngx_msec_t fetch_timeout, ngx_resolver_t* resolver, ngx_msec_t fetch_timeout, ngx_resolver_t* resolver,
ThreadSystem* thread_system, MessageHandler* handler); int max_keepalive_requests, ThreadSystem* thread_system,
MessageHandler* handler);
~NgxUrlAsyncFetcher(); ~NgxUrlAsyncFetcher();
// It should be called in the module init_process callback function. Do some // It should be called in the module init_process callback function. Do some
// intializations which can't be done in the master process // initializations which can't be done in the master process
bool Init(); bool Init();
// shutdown all the fetches. // shutdown all the fetches.
@@ -139,6 +140,7 @@ class NgxUrlAsyncFetcher : public UrlAsyncFetcher {
ngx_connection_t* command_connection_; // the command pipe ngx_connection_t* command_connection_; // the command pipe
int pipe_fd_; // the write pipe end int pipe_fd_; // the write pipe end
ngx_resolver_t* resolver_; ngx_resolver_t* resolver_;
int max_keepalive_requests_;
ngx_msec_t resolver_timeout_; ngx_msec_t resolver_timeout_;
ngx_msec_t fetch_timeout_; ngx_msec_t fetch_timeout_;
+42
View File
@@ -269,6 +269,8 @@ PSA_JS_LIBRARY_URL_PREFIX="pagespeed_custom_static"
# An expected failure can be indicated like: "~In-place resource optimization~" # An expected failure can be indicated like: "~In-place resource optimization~"
PAGESPEED_EXPECTED_FAILURES=" PAGESPEED_EXPECTED_FAILURES="
~Override server header in resource flow.~
~Override server header in IPRO flow.~
" "
# Some tests are flakey under valgrind. For now, add them to the expected failures # Some tests are flakey under valgrind. For now, add them to the expected failures
@@ -2748,6 +2750,46 @@ start_test Base config has purging disabled. Check error message syntax.
OUT=$($WGET_DUMP "$HOSTNAME/pagespeed_admin/cache?purge=*") OUT=$($WGET_DUMP "$HOSTNAME/pagespeed_admin/cache?purge=*")
check_from "$OUT" fgrep -q "pagespeed EnableCachePurge on;" check_from "$OUT" fgrep -q "pagespeed EnableCachePurge on;"
start_test Default server header in html flow.
URL=http://headers.example.com/mod_pagespeed_example/
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
# '|| true' in the line below supresses the exit code from grep when there is no
# match in its input (1).
MATCHES=$(echo "$OUT" | grep -c "Server: nginx/") || true
check [ $MATCHES -eq 1 ]
start_test Default server header in resource flow.
URL=http://headers.example.com/mod_pagespeed_example/
URL+=combine_javascript2.js+combine_javascript1.js.pagespeed.jc.0.js
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
MATCHES=$(echo "$OUT" | grep -c "Server: nginx/") || true
check [ $MATCHES -eq 1 ]
start_test Default server header in IPRO flow.
URL=http://headers.example.com//mod_pagespeed_example/combine_javascript2.js
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
MATCHES=$(echo "$OUT" | grep -c "Server: nginx/") || true
check [ $MATCHES -eq 1 ]
start_test Override server header in html flow.
URL=http://headers.example.com/mod_pagespeed_test/whitespace.html
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
MATCHES=$(echo "$OUT" | grep -c "Server: override") || true
check [ $MATCHES -eq 1 ]
start_test Override server header in resource flow.
URL=http://headers.example.com/mod_pagespeed_test/
URL+=A.proxy_pass.css.pagespeed.cf.0.css
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
MATCHES=$(echo "$OUT" | grep -c "Server: override") || true
check [ $MATCHES -eq 1 ]
start_test Override server header in IPRO flow.
URL=http://headers.example.com/mod_pagespeed_test/proxy_pass.css
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1)
MATCHES=$(echo "$OUT" | grep -c "Server: override") || true
check [ $MATCHES -eq 1 ]
if $USE_VALGRIND; then if $USE_VALGRIND; then
# It is possible that there are still ProxyFetches outstanding # It is possible that there are still ProxyFetches outstanding
# at this point in time. Give them a few extra seconds to allow # at this point in time. Give them a few extra seconds to allow
+45
View File
@@ -38,6 +38,10 @@ http {
pagespeed StaticAssetPrefix /pagespeed_custom_static/; pagespeed StaticAssetPrefix /pagespeed_custom_static/;
pagespeed MessageBufferSize 200000; pagespeed MessageBufferSize 200000;
# Increase the default fetcher timeout to resolve sporadic flakeyness when
# the native fetcher uses 8.8.8.8 to resolve.
pagespeed FetcherTimeoutMs 10000;
pagespeed NativeFetcherMaxKeepaliveRequests 50;
root "@@SERVER_ROOT@@"; root "@@SERVER_ROOT@@";
@@ -1040,6 +1044,31 @@ http {
pagespeed DisableFilters remove_comments,add_instrumentation; pagespeed DisableFilters remove_comments,add_instrumentation;
} }
# Test that pagespeed is disabled when sendfile headers are present.
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name uses-sendfile.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
add_header 'X-Sendfile' 'blablabla';
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name doesnt-sendfile.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
}
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name uses-xaccelredirect.example.com;
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
pagespeed EnableFilters inline_javascript,rewrite_javascript;
add_header 'X-Accel-Redirect' 'blablabla';
}
# Proxy + IPRO a gzip'd file for testing Issue 896. # Proxy + IPRO a gzip'd file for testing Issue 896.
server { server {
listen @@SECONDARY_PORT@@; listen @@SECONDARY_PORT@@;
@@ -1148,6 +1177,22 @@ http {
pagespeed EnableFilters rewrite_css; pagespeed EnableFilters rewrite_css;
} }
server {
listen @@SECONDARY_PORT@@;
listen [::]:@@SECONDARY_PORT@@;
server_name headers.example.com;
root "@@SERVER_ROOT@@";
pagespeed FileCachePath "@@FILE_CACHE@@_purge";
pagespeed RewriteLevel CoreFilters;
pagespeed InPlaceRewriteDeadlineMs -1;
pagespeed LoadFromFile "http://headers.example.com/"
"@@SERVER_ROOT@@/";
location /mod_pagespeed_test/ {
more_set_headers "Server: overriden";
}
}
server { server {
listen @@PRIMARY_PORT@@; listen @@PRIMARY_PORT@@;
listen [::]:@@PRIMARY_PORT@@; listen [::]:@@PRIMARY_PORT@@;