@@ -128,7 +128,7 @@ InstawebHandler::~InstawebHandler() {
128
128
// If fetch_ is null we either never tried to fetch anything or it took
129
129
// ownership of itself after timing out.
130
130
if (fetch_ != NULL ) {
131
- if (WaitForFetch () == ApacheFetch:: kWaitSuccess ) {
131
+ if (WaitForFetch ()) {
132
132
delete fetch_; // Fetch completed normally.
133
133
} else {
134
134
// Fetch took ownership of itself and will continue in the background.
@@ -137,19 +137,19 @@ InstawebHandler::~InstawebHandler() {
137
137
}
138
138
}
139
139
140
- ApacheFetch::WaitResult InstawebHandler::WaitForFetch () {
140
+ bool InstawebHandler::WaitForFetch () {
141
141
if (fetch_ == NULL ) {
142
- return ApacheFetch:: kWaitSuccess ; // Nothing to wait for.
142
+ return true ; // Nothing to wait for.
143
143
}
144
144
145
- ApacheFetch::WaitResult wait_result = fetch_->Wait (rewrite_driver_);
146
- if (wait_result != ApacheFetch:: kWaitSuccess ) {
145
+ bool ok = fetch_->Wait (rewrite_driver_);
146
+ if (!ok ) {
147
147
// Give up on waiting for the fetch so we stop tying up a thread. Fetch has
148
148
// taken ownership of itself, will discard any messages it receives if it's
149
149
// abandoned, and will delete itself when Done() is called, if ever.
150
150
fetch_ = NULL ;
151
151
}
152
- return wait_result ;
152
+ return ok ;
153
153
}
154
154
155
155
void InstawebHandler::SetupSpdyConnectionIfNeeded () {
@@ -179,16 +179,19 @@ RewriteDriver* InstawebHandler::MakeDriver() {
179
179
}
180
180
181
181
ApacheFetch* InstawebHandler::MakeFetch (const GoogleString& url,
182
+ bool buffered,
182
183
StringPiece debug_info) {
183
184
DCHECK (fetch_ == NULL );
184
185
// ApacheFetch takes ownership of request_headers.
185
186
RequestHeaders* request_headers = new RequestHeaders ();
186
187
ApacheRequestToRequestHeaders (*request_, request_headers);
187
- fetch_ = new ApacheFetch (url, debug_info, server_context_->thread_system (),
188
- server_context_->timer (),
189
- new ApacheWriter (request_),
190
- request_headers, request_context_, options_,
191
- server_context_->message_handler ());
188
+ fetch_ = new ApacheFetch (
189
+ url, debug_info, server_context_->thread_system (),
190
+ server_context_->timer (),
191
+ new ApacheWriter (request_, server_context_->thread_system ()),
192
+ request_headers, request_context_, options_,
193
+ server_context_->message_handler ());
194
+ fetch_->set_buffered (buffered);
192
195
return fetch_;
193
196
}
194
197
@@ -441,13 +444,12 @@ bool InstawebHandler::HandleAsInPlace() {
441
444
!= NULL ) || (request_->user != NULL ));
442
445
443
446
RewriteDriver* driver = MakeDriver ();
444
- MakeFetch (original_url_ , " ipro" );
447
+ MakeFetch (true /* buffered */ , " ipro" );
445
448
fetch_->set_handle_error (false );
446
449
driver->FetchInPlaceResource (stripped_gurl_, false /* proxy_mode */ , fetch_);
447
- ApacheFetch::WaitResult wait_result = WaitForFetch ();
448
- if (wait_result != ApacheFetch::kWaitSuccess ) {
449
- // Note: fetch_ has been released; no longer safe to look at;
450
- handled = (wait_result == ApacheFetch::kAbandonedAndHandled );
450
+ bool ok = WaitForFetch ();
451
+ if (!ok) {
452
+ // Nothing to do, fetch_ has been released, no longer safe to look at.
451
453
} else if (fetch_->status_ok ()) {
452
454
server_context_->rewrite_stats ()->ipro_served ()->Add (1 );
453
455
handled = true ;
@@ -504,12 +506,12 @@ bool InstawebHandler::HandleAsProxy() {
504
506
&host_header, &is_proxy) &&
505
507
is_proxy) {
506
508
RewriteDriver* driver = MakeDriver ();
507
- MakeFetch (mapped_url, " proxy" );
509
+ MakeFetch (mapped_url, true /* buffered */ , " proxy" );
508
510
fetch_->set_is_proxy (true );
509
511
driver->SetRequestHeaders (*fetch_->request_headers ());
510
512
server_context_->proxy_fetch_factory ()->StartNewProxyFetch (
511
513
mapped_url, fetch_, driver, NULL , NULL );
512
- handled = WaitForFetch () != ApacheFetch:: kAbandonedAndDeclined ;
514
+ handled = WaitForFetch ();
513
515
}
514
516
515
517
return handled; // false == declined
@@ -867,39 +869,51 @@ apr_status_t InstawebHandler::instaweb_handler(request_rec* request) {
867
869
server_context->StatisticsPage (is_global_statistics,
868
870
instaweb_handler.query_params (),
869
871
instaweb_handler.options (),
870
- instaweb_handler.MakeFetch (" statistics" ));
872
+ instaweb_handler.MakeFetch (
873
+ false /* unbuffered */ , " statistics" ));
871
874
return OK;
872
875
} else if ((request_handler_str == kAdminHandler ) ||
873
876
(request_handler_str == kGlobalAdminHandler )) {
874
877
InstawebHandler instaweb_handler (request);
878
+ // The fetch has to be buffered because if it's a cache lookup it could
879
+ // complete asynchrously via the rewrite thread.
875
880
server_context->AdminPage ((request_handler_str == kGlobalAdminHandler ),
876
881
instaweb_handler.stripped_gurl (),
877
882
instaweb_handler.query_params (),
878
883
instaweb_handler.options (),
879
- instaweb_handler.MakeFetch (" admin" ));
884
+ instaweb_handler.MakeFetch (
885
+ true /* buffered */ , " admin" ));
880
886
ret = OK;
881
887
} else if (global_config->enable_cache_purge () &&
882
888
!global_config->purge_method ().empty () &&
883
889
(global_config->purge_method () == request->method )) {
884
890
InstawebHandler instaweb_handler (request);
885
891
AdminSite* admin_site = server_context->admin_site ();
892
+ // I'm not convinced that the purge handler must complete synchronously. It
893
+ // schedules work on the rewrite driver factory's scheduler, and while in my
894
+ // testing it processes everything on the calling thread I'm not sure this
895
+ // is part of the contract. The response is just headers and a few bytes of
896
+ // body, so buffering is basically free. To be on the safe side let's
897
+ // buffer this one too.
886
898
admin_site->PurgeHandler (instaweb_handler.original_url_ ,
887
899
server_context->cache_path (),
888
- instaweb_handler.MakeFetch (" purge" ));
900
+ instaweb_handler.MakeFetch (
901
+ true /* buffered */ , " purge" ));
889
902
ret = OK;
890
903
} else if (request_handler_str == kConsoleHandler ) {
891
904
InstawebHandler instaweb_handler (request);
892
905
server_context->ConsoleHandler (*instaweb_handler.options (),
893
906
AdminSite::kOther ,
894
907
instaweb_handler.query_params (),
895
- instaweb_handler.MakeFetch (" console" ));
908
+ instaweb_handler.MakeFetch (
909
+ false /* unbuffered */ , " console" ));
896
910
ret = OK;
897
911
} else if (request_handler_str == kMessageHandler ) {
898
912
InstawebHandler instaweb_handler (request);
899
913
server_context->MessageHistoryHandler (
900
914
*instaweb_handler.options (),
901
915
AdminSite::kOther ,
902
- instaweb_handler.MakeFetch (" messages" ));
916
+ instaweb_handler.MakeFetch (false /* unbuffered */ , " messages" ));
903
917
ret = OK;
904
918
} else if (request_handler_str == kLogRequestHeadersHandler ) {
905
919
// For testing CustomFetchHeader.
0 commit comments