merge pull request #22 Support Custom Options
off by default, either of these commands below would fetch the example file with the filter on:
curl 'http://localhost:8050/mod_pagespeed_example/add_instrumentation.html?ModPagespeedFilters=add_instrumentation'
curl --header 'ModPagespeedFilters:add_instrumentation' 'http://localhost:8050/mod_pagespeed_example/add_instrumentation.html'
Compared to just
curl http://localhost:8050/mod_pagespeed_example/add_instrumentation.html
the difference is that there's a chunk of complicated javascript at the end
added by the filter.
This commit is contained in:
+26
-13
@@ -27,19 +27,39 @@ namespace net_instaweb {
|
|||||||
NgxBaseFetch::NgxBaseFetch(ngx_http_request_t* r, int pipe_fd)
|
NgxBaseFetch::NgxBaseFetch(ngx_http_request_t* r, int pipe_fd)
|
||||||
: request_(r), done_called_(false), last_buf_sent_(false),
|
: request_(r), done_called_(false), last_buf_sent_(false),
|
||||||
pipe_fd_(pipe_fd) {
|
pipe_fd_(pipe_fd) {
|
||||||
|
PopulateRequestHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
NgxBaseFetch::~NgxBaseFetch() { }
|
NgxBaseFetch::~NgxBaseFetch() { }
|
||||||
|
|
||||||
void NgxBaseFetch::PopulateHeaders() {
|
void NgxBaseFetch::PopulateRequestHeaders() {
|
||||||
|
CopyHeadersFromTable<RequestHeaders>(&request_->headers_in.headers,
|
||||||
|
request_headers());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NgxBaseFetch::PopulateResponseHeaders() {
|
||||||
|
CopyHeadersFromTable<ResponseHeaders>(&request_->headers_out.headers,
|
||||||
|
response_headers());
|
||||||
|
|
||||||
|
// Manually copy over the content type because it's not included in
|
||||||
|
// request_->headers_out.headers.
|
||||||
|
response_headers()->Add(
|
||||||
|
HttpAttributes::kContentType,
|
||||||
|
ngx_http_pagespeed_str_to_string_piece(
|
||||||
|
&request_->headers_out.content_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// http_version is the version number of protocol; 1.1 = 1001. See
|
||||||
// NGX_HTTP_VERSION_* in ngx_http_request.h
|
// NGX_HTTP_VERSION_* in ngx_http_request.h
|
||||||
response_headers()->set_major_version(request_->http_version / 1000);
|
headers_to->set_major_version(request_->http_version / 1000);
|
||||||
response_headers()->set_minor_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
|
// Standard nginx idiom for iterating over a list. See ngx_list.h
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_list_part_t* part = &request_->headers_out.headers.part;
|
ngx_list_part_t* part = &headers_from->part;
|
||||||
ngx_table_elt_t* header = static_cast<ngx_table_elt_t*>(part->elts);
|
ngx_table_elt_t* header = static_cast<ngx_table_elt_t*>(part->elts);
|
||||||
|
|
||||||
for (i = 0 ; /* void */; i++) {
|
for (i = 0 ; /* void */; i++) {
|
||||||
@@ -57,15 +77,8 @@ void NgxBaseFetch::PopulateHeaders() {
|
|||||||
StringPiece value = ngx_http_pagespeed_str_to_string_piece(
|
StringPiece value = ngx_http_pagespeed_str_to_string_piece(
|
||||||
&header[i].value);
|
&header[i].value);
|
||||||
|
|
||||||
response_headers()->Add(key, value);
|
headers_to->Add(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For some reason content_type is not included in
|
|
||||||
// request_->headers_out.headers, which means I don't fully understand how
|
|
||||||
// headers_out works, but manually copying over content type works.
|
|
||||||
StringPiece content_type = ngx_http_pagespeed_str_to_string_piece(
|
|
||||||
&request_->headers_out.content_type);
|
|
||||||
response_headers()->Add(HttpAttributes::kContentType, content_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NgxBaseFetch::HandleWrite(const StringPiece& sp,
|
bool NgxBaseFetch::HandleWrite(const StringPiece& sp,
|
||||||
|
|||||||
+10
-1
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "net/instaweb/http/public/async_fetch.h"
|
#include "net/instaweb/http/public/async_fetch.h"
|
||||||
|
#include "net/instaweb/http/public/headers.h"
|
||||||
#include "net/instaweb/util/public/string.h"
|
#include "net/instaweb/util/public/string.h"
|
||||||
|
|
||||||
namespace net_instaweb {
|
namespace net_instaweb {
|
||||||
@@ -46,8 +47,11 @@ class NgxBaseFetch : public AsyncFetch {
|
|||||||
NgxBaseFetch(ngx_http_request_t* r, int pipe_fd);
|
NgxBaseFetch(ngx_http_request_t* r, int pipe_fd);
|
||||||
virtual ~NgxBaseFetch();
|
virtual ~NgxBaseFetch();
|
||||||
|
|
||||||
|
// Copies the request headers out of request_->headers_in->headers.
|
||||||
|
void PopulateRequestHeaders();
|
||||||
|
|
||||||
// Copies the response headers out of request_->headers_out->headers.
|
// Copies the response headers out of request_->headers_out->headers.
|
||||||
void PopulateHeaders();
|
void PopulateResponseHeaders();
|
||||||
|
|
||||||
// Puts a chain in link_ptr if we have any output data buffered. Returns
|
// 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
|
// NGX_OK on success, NGX_ERROR on errors. If there's no data to send, sends
|
||||||
@@ -71,6 +75,11 @@ class NgxBaseFetch : public AsyncFetch {
|
|||||||
virtual void HandleHeadersComplete();
|
virtual void HandleHeadersComplete();
|
||||||
virtual void HandleDone(bool success);
|
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
|
// Indicate to nginx that we would like it to call
|
||||||
// CollectAccumulatedWrites().
|
// CollectAccumulatedWrites().
|
||||||
void RequestCollection();
|
void RequestCollection();
|
||||||
|
|||||||
+24
-2
@@ -590,13 +590,34 @@ ngx_http_pagespeed_create_request_context(ngx_http_request_t* r,
|
|||||||
// on the proxy fetch below.
|
// on the proxy fetch below.
|
||||||
ctx->base_fetch = new net_instaweb::NgxBaseFetch(r, file_descriptors[1]);
|
ctx->base_fetch = new net_instaweb::NgxBaseFetch(r, file_descriptors[1]);
|
||||||
|
|
||||||
|
// Stripping ModPagespeed query params before the property cache lookup to
|
||||||
|
// make cache key consistent for both lookup and storing in cache.
|
||||||
|
//
|
||||||
|
// Sets option from request headers and url.
|
||||||
|
net_instaweb::ServerContext::OptionsBoolPair query_options_success =
|
||||||
|
ctx->cfg->server_context->GetQueryOptions(
|
||||||
|
&url, ctx->base_fetch->request_headers(), NULL);
|
||||||
|
bool get_query_options_success = query_options_success.second;
|
||||||
|
if (!get_query_options_success) {
|
||||||
|
// Failed to parse query params or request headers.
|
||||||
|
// TODO(jefftk): send a helpful error message to the visitor.
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"ngx_http_pagespeed_create_request_context: "
|
||||||
|
"parsing headers or query params failed.");
|
||||||
|
ngx_http_pagespeed_release_request_context(ctx);
|
||||||
|
return NGX_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will be NULL if there aren't custom options..
|
||||||
|
net_instaweb::RewriteOptions* custom_options = query_options_success.first;
|
||||||
|
|
||||||
// This code is based off of ProxyInterface::ProxyRequestCallback and
|
// This code is based off of ProxyInterface::ProxyRequestCallback and
|
||||||
// ProxyFetchFactory::StartNewProxyFetch
|
// ProxyFetchFactory::StartNewProxyFetch
|
||||||
|
|
||||||
// If the global options say we're running furious (the experiment framework)
|
// If the global options say we're running furious (the experiment framework)
|
||||||
// then clone them into custom_options so we can manipulate custom options
|
// then clone them into custom_options so we can manipulate custom options
|
||||||
// without affecting the global options.
|
// without affecting the global options.
|
||||||
net_instaweb::RewriteOptions* custom_options = NULL;
|
|
||||||
net_instaweb::RewriteOptions* global_options =
|
net_instaweb::RewriteOptions* global_options =
|
||||||
ctx->cfg->server_context->global_options();
|
ctx->cfg->server_context->global_options();
|
||||||
if (global_options->running_furious()) {
|
if (global_options->running_furious()) {
|
||||||
@@ -724,7 +745,8 @@ ngx_http_pagespeed_body_filter(ngx_http_request_t* r, ngx_chain_t* in) {
|
|||||||
// Call this here and not in the header filter because we want to see the
|
// Call this here and not in the header filter because we want to see the
|
||||||
// headers after any other filters are finished modifying them. At this
|
// headers after any other filters are finished modifying them. At this
|
||||||
// point they are final.
|
// point they are final.
|
||||||
ctx->base_fetch->PopulateHeaders(); // TODO(jefftk): is this thread safe?
|
// TODO(jefftk): is this thread safe?
|
||||||
|
ctx->base_fetch->PopulateResponseHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user