-
Notifications
You must be signed in to change notification settings - Fork 361
Design
Accurate as of 2012-12-21
Most of ngx_pagespeed is glue code, attaching PageSpeed to Nginx. What's attached to what, and how does it work?
The two main places we interact with an Nginx request are in a body filter and a content handler. In the body filter we pass html to PageSpeed for optimizing, while in the content handler we respond to requests for optimized PageSpeed resources (css, images, javascript). An example might be helpful.
-
Nginx receives a request for
http://example.com
GET / HTTP/1.1 Host: example.com
-
Nginx calls our content handler [1], which declines to handle the request because it's not for an optimized
.pagespeed.
resource. -
Nginx continues trying other content handlers until it finds one that can handle the request. This may be a
proxy_pass
,fastcgi_pass
, atry_files
, or anything else that the webmaster might have configured Nginx to use. -
Whatever content handler Nginx selects will start streaming a response as a linked list of buffers ("buffer chain").
ngx_chain_t in: ngx_buf_t* buf: u_char* start u_char* end ngx_chain_t* next
-
Nginx passes that chain of buffers through all registered body filters, which includes ours. If this were not html being sent, our body filter would immediately pass the buffers on to the next registered body filter.
-
Our body filter will see one buffer chain at a time, but it might not be the whole file's worth. For static files on disk it usually will be, but perhaps if we're proxying from an upstream that quickly dumps some layout html but takes much longer to generate personalized content. Imagine the contents of the buffer chain on the first call to the body filter are:
<html> <link rel="stylesheet" href="site.css"> <script src="navbar.js"> <script src="hover.js">
[1] As tracked in Issue #102, our content handler is not always called first. This needs to be fixed, and this description assumes we've fixed it.