1
0
mirror of https://github.com/mrclay/minify.git synced 2025-08-11 00:24:11 +02:00

Add wiki docs and point to some of them (lots of work left here)

This commit is contained in:
Steve Clay
2015-09-04 17:38:45 -04:00
parent d233b65d3d
commit f1ef53e84e
21 changed files with 1195 additions and 12 deletions

92
docs/old/History.wiki.md Normal file
View File

@@ -0,0 +1,92 @@
## Version 2.1.5 (2012-03-10)
* Removed XSS vulnerability
* Disabled builder by default
* command line tools to minify and rewrite URIs in CSS
* upgrade (optional) JSMin+ library
* more efficient JS minification when using CC/YUIC
* Closure Compiler uses cURL when allow\_url\_fopen is off
* Missing file notices when using groups
## Version 2.1.4b (2010-07-10)
* Option to minify JS with Closure Compiler API w/ JSMin failover
* Cookie/bookmarklet-based debug mode. No HTML editing!
* Allows 1 file to be missing w/o complete failure
* Combine multiple groups and files in single URI
* More useful HTML helpers for writing versioned URIs
* More detailed error logging, including minifier exceptions
* Builder offers more helpful messages/PHP environment warnings
* Bypass minification based on filename pattern. e.g. foo.min.js / foo-min.css
* JSMin won't choke on common Closure compiler syntaxes (`i+ ++j`)
* Better caching in IE6
* Cache ids are influenced by group/file names
* Debug mode for Javascript doesn't break on common XPath strings (Prototype 1.6)
* Removed annoying maxFiles limit
* mbstring.func\_overload usage is safer
## Version 2.1.3 (2009-06-30)
* CSS fixes
* A few URI rewriting bugs fixed
* comment/whitespace removal no longer breaks some values
* IE6 [pseudo-element selector bug](http://www.crankygeek.com/ie6pebug/) no longer triggered
* HTTP fixes
* Proper Expires handling in webkit (dropped "must-revalidate", which triggered a [webkit bug](http://mrclay.org/index.php/2009/02/24/safari-4-beta-cache-controlmust-revalidate-bug/))
* ETag generation now valid ([must be unique when gzipped](https://issues.apache.org/bugzilla/show_bug.cgi?id=39727))
* Vary header always sent when Accept-Encoding is sniffed
* Dropped deflate encoding, since browser and proxy support [could be buggy](http://stackoverflow.com/questions/883841/).
* File cache now works w/o setting `$min_cachePath`
* No more 5.3 deprecation warnings: `split()` removed
* API: Can set contentType Minify\_Source objects (fixes an annoying [caveat](http://groups.google.com/group/minify/msg/8446d32ee99a4961))
* [Resolved Issue list](http://code.google.com/p/minify/issues/list?can=1&q=label%3ARelease-2.1.2%20status%3AVerified)
## Version 2.1.2 (2009-03-04)
* Javascript fixes
* Debug mode no longer confused by `*/*` in strings/RegExps (jQuery)
* quote characters inside RegExp literals no longer cause exception
* files ending in single-line comments no longer cause code loss
* CSS: data: URLs no longer mangled
* Optional error logging to Firefox's FirePHP extension
* Unit tests to check for common DOCUMENT\_ROOT problems
* DOCUMENT\_ROOT no longer overwritten on IIS servers
* Builder app doesn't fail on systems without gzdeflate()
* APC caching class included
## Version 2.1.1 (2008-10-19)
* Bug fix release
* Detection and workarounds for zlib.output\_compression and non-PHP encoding modules
* Zlib not required (mod\_rewrite, et.al., can still be used for encoding)
* HTML : More IE conditional comments preserved
* Minify\_groupUri() utility fixed
## Version 2.1.0 (2008-09-18)
* "min" default application for quick deployment
* Minify URI Builder app & bookmarklet for quickly creating minify URIs
* Relative URIs in CSS file are fixed automatically by default
* "debug" mode for revealing original line #s in combined files
* Better IIS support
* Improved minifier classes:
* JS: preserves IE conditional comments
* CSS: smaller output, preserves more hacks and valid CSS syntax, shorter line lengths, other bug fixes
* HTML: smaller output, shorter line lengths, other bug fixes
* Default Cache-Control: max-age of 30 minutes
* Conditional GETs supported even when max-age sent
* Experimental memcache cache class (default is files)
* Minify\_Cache\_File has flock()s (by default)
* Workaround for Windows mtime reporting bug
## Version 2.0.0 (2008-05-22)
* Complete code overhaul. Minify is now a PEAR-style class and toolkit for building customized minifying file servers.
* Content-Encoding: deflate/gzip/compress, based on request headers
* Expanded CSS and HTML minifiers with test cases
* Easily plug-in 3rd-party minifiers (like Packer)
* Plug-able front end controller allows changing the way files are chosen
* Compression & encoding modules lazy-loaded as needed (304 responses use minimal code)
* Separate utility classes for HTTP encoding and cache control
## Version 1.0.1 (2007-05-05)
* Fixed various problems resolving pathnames when hosted on an NFS mount.
* Fixed 'undefined constant' notice.
* Replaced old JSMin library with a much faster custom implementation.
## Version 1.0.0 (2007-05-02)
* First release.

View File

@@ -0,0 +1,31 @@
### Browsers, trust your cache
In all responses a `Cache-Control` header is sent, telling the browser it doesn't need to "check in" with the server for some period of time. The ideal request is the one that never leaves the browser!
### Convert a request to source objects
When the browser makes a request like `/min/g=css`, Apache rewrites this to `/min/index.php?g=css`, which calls Minify's front controller.
A separate controller then uses the querystring to establish a "sources" array, specifying exactly which objects (usually files) are to be included in the final output.
### Try browser cache
Minify finds the latest modification time of all the source objects (`filemtime` for files, so if you use a tool that doesn't update this, you might need to `touch` your modified files).
If the browser has sent an `If-Modified-Since` header, and it's valid (the given date is older than the most recent source), then a 304 header is returned, execution stops, and the browser uses its cache copy.
### Try server cache
Minify generates a unique cache ID for the particular set of sources and their options. This is used to maintain a cache (file usually) of the final output.
If the cache is "valid" (younger than the most recently modified source), then its content is sent along with a `Last-Modified` header with the most recent source's modification time, and execution stops.
### Minification has to be done
If any source is younger than the cache, the cache must be rebuilt from the minification process (slow, but infrequently done):
Minify processes each source with a "minifier" function (determined by the content type of the sources and source-specific options), combines them to a single string, saves this to the cache object, then serves it with the `Last-Modified` header as sbove.
#### Content encoding
Minify actually stores a gzipped version of each output in a second cache object. If the browser supports it, Minify streams the pre-compressed content straight from cache (disk usually) to the browser.

View File

@@ -0,0 +1,63 @@
# HTTP Caching in Minify
## Conditional GET
Minify sends all files with Last-Modified and ETag headers. If the browser requests a file again it will send along If-Modified-Since and If-None-Match headers. Minify checks these headers and, if the browser has the latest version, sends back only a slim "304 Not Modified" response (no content), telling the browser to use its cached file.
## Expires Header
Minify also sends Expires and Cache-Control: max-age headers, indicating that the file should be considered valid for a period of time. In future page views the browser will not re-request the file (unless the user refreshes), and instead will use the cached version.
By default, Minify sends an Expires header for 1800 seconds (30 minutes) into the future (configurable via `$min_serveOptions['maxAge']`). This means your file changes may not be seen by users immediately after you make them. If your changes must be seen immediately, you should reduce max-age to 0, but note you will not get as much benefit, as browsers will still have to send requests **every time**.
## Far-off Expires
When pre-set groups are used and a number is appended to the minify URI (e.g. `/min/g=css&456`), then Minify sends an Expires date of 1 year in the future. This is great for caching, but places responsibility on your HTML pages. They _must_ change the number whenever a JS/CSS source file is updated, or the browser will not know to re-request the file. If you're generating your page with PHP, the [Minify\_groupUri](http://code.google.com/p/minify/source/browse/min/utils.php?r=222#11) utility function can make this easier to manage.
# Using `HTTP_ConditionalGet` in other projects
Minify uses the PHP class [HTTP\_ConditionalGet](http://code.google.com/p/minify/source/browse/lib/HTTP/ConditionalGet.php) to implement the conditional GET model. To use this in your own project you'll need the last modification time of your content (for a file, use [filemtime()](http://www.php.net/filemtime)), or a short hash digest of the content (something that changes when the content changes). You'll also want to consider if the content can be stored in public caches, or should only be stored in the user's browser.
## When the last modification time is known
In this example we implement conditional GET for a mostly-static PHP script. The browser needs to redownload the content only when the file is updated.
```
// top of file
$cg = new HTTP_ConditionalGet(array(
'isPublic' => true,
'lastModifiedTime' => filemtime(__FILE__)
));
$cg->sendHeaders();
if ($cg->cacheIsValid) { // 304 already sent
exit();
}
// rest of script
```
For the first request the browser's cache won't be valid, so the full script will execute, sending the full content. On the next, the cache will be valid and the sendHeaders() method will have already set the 304 header, so the script can be halted.
There's also a shortcut static method for this:
```
HTTP_ConditionalGet::check(filemtime(__FILE__), true); // exits if client has cache
// rest of script
```
## When last modification time isn't known
Let's say you have an HTML page in a database, but no modification time. To reduce DB requests, you cache this content in a file/memory, but you'd also like to reduce bandwidth. In this case, what you can do is also cache a hash of the page along with the content. Now you can do this:
```
$cache = getCache();
$cg = new HTTP_ConditionalGet(array(
'isPublic' => true,
'contentHash' => $cache['hash']
));
$cg->sendHeaders();
if ($cg->cacheIsValid) { // 304 already sent
exit();
}
echo $cache['page'];
```
Although Last-Modified cannot be set, ETag will serve the same purposes in most browsers, allowing the conditional GET.

View File

@@ -0,0 +1,13 @@
## 1. Be easy to implement
A PHP user should be able to quickly start serving JS/CSS much more optimally.
## 2. Be extensible/versatile
The user should be able to work Minify into an environment without modifying Minify's source. Right now this should be easy on the controller side, but the Minify class is static, which is fast, but may hinder extensibility.
## 3. Be fast as possible
With the release of 2.0.2 Minify will be much faster, outperforming even Apache's mod\_deflate (which apparently doesn't cache the encoded content like mod\_gzip does).
Since testing has shown that [pre-encoding files and using type-maps on Apache is blazingly fast](http://mrclay.org/index.php/2008/06/03/pre-encoding-vs-mod_deflate/), Minify should work towards maintaining builds of pre-encoded files and letting Apache serve them. It's not clear if there's something similar to type-maps on lighttpd, but it's worth looking into.

15
docs/old/Security.wiki.md Normal file
View File

@@ -0,0 +1,15 @@
This was quickly converted from an e-mail, please consider it "temporary".
## Each file specified by `$_GET['f']` must:
* Have the [same extension, either "css" or "js"](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/lib/Minify/Controller/MinApp.php#66),
* Exist, and...
* Have a [realpath() within a whitelist of subdirectories](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/lib/Minify/Controller/Base.php#122).
The default whitelist contains only DOCUMENT\_ROOT, but can be [specified](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/config.php#57).
Then, a few more steps just to be paranoid:
* If a base was given by `$_GET['b']`, [it can't have ".."](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/lib/Minify/Controller/MinApp.php#84).
* `$_GET['f']` [must not contain "//", "\", or "./"](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/lib/Minify/Controller/MinApp.php#64).
* There can be [no duplicates](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/lib/Minify/Controller/MinApp.php#77) and only a [limited number of files](http://code.google.com/p/minify/source/browse/tags/release_2.1.1/min/config.php#73) can be specified.

View File

@@ -0,0 +1,35 @@
# Minify 2
[Minify 2.0.0](http://code.google.com/p/minify/source/browse/tags/release_2.0.0/) was released May 22, 2008 and represents an architectural redesign of Minify's code and its usage. 2.0 is built as a library of classes allowing users to easily build customized minified-file servers; or add minification, HTTP encoding, or [conditional GET](http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers) to existing projects.
The release includes 3 [example sites](http://code.google.com/p/minify/source/browse/tags/release_2.0.0/web/examples) to demostrate usage and [unit tests](http://code.google.com/p/minify/source/browse/tags/release_2.0.0/web/test/) you can run on your system.
## Documentation
Each PHP file is documented, but, for now, the [README file](http://code.google.com/p/minify/source/browse/tags/release_2.0.0/README) is the best reference for getting started with the library. This [blog post](http://mrclay.org/index.php/2008/03/27/minifying-javascript-and-css-on-mrclayorg/) may also give you some ideas.
The best place for questions is the [minify Google group](http://groups.google.com/group/minify).
### Included HTTP Classes
The two HTTP utility classes, [HTTP\_ConditionalGet](http://code.google.com/p/minify/source/browse/lib/HTTP/ConditionalGet.php) and [HTTP\_Encoder](http://code.google.com/p/minify/source/browse/lib/HTTP/Encoder.php), are already fairly well-tested and include a set of test pages to see how they work. On the [Florida Automated Weather Network](http://fawn.ifas.ufl.edu/) site, these are used especially in scripts that serve data to our Flash components.
Here's an example of using both to conditionally serve a text file gzipped:
```
$cg = new HTTP_ConditionalGet(array(
'lastModifiedTime' => filemtime($filepath)
,'isPublic' => true
));
$cg->sendHeaders();
if ($cg->cacheIsValid) {
// client cache was valid, no content needed
exit();
}
require 'HTTP/Encoder.php';
$he = new HTTP_Encoder(array(
'content' => file_get_contents($filepath)
,'type' => 'text/plain'
));
$he->encode();
$he->sendAll();
```