Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.

Commit 1964ef5

Browse files
committed
Fix crasher on 404 .pagespeed. resources w/a custom location
- Fix nginx-side flow so we handle .pagespeed. resources ok when they will land on a customized 404 internal location. - Additionally, check for a wiped request context and make sure we do not dereference a null pointer, which is what hurt in the flow we entered above as the IPRO lookup still was generating events while the nginx side request context was gone. - Also, as a preliminary measure, do not check fail when we receive a stale event originating from a NgxBaseFetch that is no longer associated with our request context. Do log a warning so we'll hear about this happening either through system test failures or a bug report. Fixes #1081
1 parent 56a5d41 commit 1964ef5

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

src/ngx_base_fetch.cc

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ const char* BaseFetchTypeToCStr(NgxBaseFetchType type) {
118118
return "can't get here";
119119
}
120120

121+
// TODO(oschaaf): replace the ngx_log_error with VLOGS or pass in a
122+
// MessageHandler and use that.
121123
void NgxBaseFetch::ReadCallback(const ps_event_data& data) {
122124
NgxBaseFetch* base_fetch = reinterpret_cast<NgxBaseFetch*>(data.sender);
123125
ngx_http_request_t* r = base_fetch->request();
@@ -138,9 +140,30 @@ void NgxBaseFetch::ReadCallback(const ps_event_data& data) {
138140
if (refcount == 0 || detached) {
139141
return;
140142
}
143+
141144
ps_request_ctx_t* ctx = ps_get_request_context(r);
142145

143-
CHECK(data.sender == ctx->base_fetch);
146+
// If our request context was zeroed, skip this event.
147+
// See https://github.com/pagespeed/ngx_pagespeed/issues/1081
148+
if (ctx == NULL) {
149+
// Should not happen normally, when it does this message will cause our
150+
// system tests to fail.
151+
ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0,
152+
"pagespeed [%p] skipping event: request context gone", r);
153+
return;
154+
}
155+
156+
// Normally we expect the sender to equal the active NgxBaseFetch instance.
157+
DCHECK(data.sender == ctx->base_fetch);
158+
159+
// If someone changed our request context or NgxBaseFetch, skip processing.
160+
if (data.sender != ctx->base_fetch) {
161+
ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0,
162+
"pagespeed [%p] skipping event: event originating from disassociated"
163+
" NgxBaseFetch instance.", r);
164+
return;
165+
}
166+
144167
CHECK(r->count > 0) << "r->count: " << r->count;
145168

146169
int rc;

src/ngx_pagespeed.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,8 @@ ngx_int_t ps_base_fetch_handler(ngx_http_request_t* r) {
284284
// modules running after us to manipulate those responses.
285285
if (!status_ok && (ctx->base_fetch->base_fetch_type() != kHtmlTransform
286286
&& ctx->base_fetch->base_fetch_type() != kIproLookup)) {
287-
return status_code;
287+
ps_release_base_fetch(ctx);
288+
return ngx_http_filter_finalize_request(r, NULL, status_code);
288289
}
289290

290291
if (ctx->preserve_caching_headers != kDontPreserveHeaders) {

test/nginx_system_test.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,14 @@ check_from "$OUT" fgrep -qi '404'
12411241
MATCHES=$(echo "$OUT" | grep -c "Cache-Control: override") || true
12421242
check [ $MATCHES -eq 1 ]
12431243

1244+
start_test Custom 404 does not crash.
1245+
URL=http://custom404.example.com/mod_pagespeed_test/
1246+
URL+=A.doesnotexist.css.pagespeed.cf.0.css
1247+
# The 404 response makes wget exit with an error code, which we ignore.
1248+
OUT=$(http_proxy=$SECONDARY_HOSTNAME $WGET_DUMP -O /dev/null -S $URL 2>&1) || true
1249+
# We ignored the exit code, check if we got a 404 response.
1250+
check_from "$OUT" fgrep -qi '404'
1251+
12441252
start_test Shutting down.
12451253

12461254
# Fire up some heavy load if ab is available to test a stressed shutdown

test/pagespeed_test.conf.template

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,14 @@ http {
967967
}
968968
}
969969

970+
server {
971+
listen @@SECONDARY_PORT@@;
972+
listen [::]:@@SECONDARY_PORT@@;
973+
server_name custom404.example.com;
974+
pagespeed FileCachePath "@@SECONDARY_CACHE@@";
975+
error_page 404 /404.html;
976+
}
977+
970978
server {
971979
listen @@SECONDARY_PORT@@;
972980
listen [::]:@@SECONDARY_PORT@@;

0 commit comments

Comments
 (0)