<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>README</filename>
    </added>
    <added>
      <filename>doc/configuration.markdown</filename>
    </added>
    <added>
      <filename>doc/events.dot</filename>
    </added>
    <added>
      <filename>doc/faq.markdown</filename>
    </added>
    <added>
      <filename>doc/index.markdown</filename>
    </added>
    <added>
      <filename>doc/layout.html.erb</filename>
    </added>
    <added>
      <filename>doc/license.markdown</filename>
    </added>
    <added>
      <filename>doc/rack-cache.css</filename>
    </added>
    <added>
      <filename>doc/storage.markdown</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -4,3 +4,12 @@ tags
 /dist
 /coverage
 /doc/api
+/doc/*.png
+/doc/*.pdf
+/doc/*.svg
+/doc/config
+/doc/configuration.html
+/doc/index.html
+/doc/license.html
+/doc/storage.html
+/doc/faq.html</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Copyright (c) 2008 Ryan Tomayko &lt;http://tomayko.com/&gt;
+Copyright (c) 2008 Ryan Tomayko &lt;http://tomayko.com/about&gt;
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the &quot;Software&quot;), to</diff>
      <filename>COPYING</filename>
    </modified>
    <modified>
      <diff>@@ -30,13 +30,13 @@ task :rcov do
 end
 
 # DOC =======================================================================
+desc 'Build all documentation'
+task :doc =&gt; %w[doc:api doc:graphs doc:source doc:markdown]
 
 # requires the hanna gem:
 #   gem install mislav-hanna --source=http://gems.github.com
-
-desc 'Generate Hanna RDoc under doc/api'
-task :doc =&gt; ['doc/api/index.html']
-
+desc 'Build API documentation (doc/api)'
+task 'doc:api' =&gt; 'doc/api/index.html' 
 file 'doc/api/index.html' =&gt; FileList['lib/**/*.rb'] do |f|
   sh &lt;&lt;-SH
   hanna --charset utf8 --fmt html --inline-source --line-numbers \
@@ -47,6 +47,55 @@ file 'doc/api/index.html' =&gt; FileList['lib/**/*.rb'] do |f|
 end
 CLEAN.include 'doc/api'
 
+desc 'Build graphviz graphs'
+task 'doc:graphs'
+%w[pdf png svg].each do |filetype|
+  FileList[&quot;doc/*.dot&quot;].each do |source|
+    dest = source.sub(/dot$/, filetype)
+    file dest =&gt; source do |f|
+      sh &quot;dot -T#{filetype} #{source} -o #{f.name}&quot;
+    end
+    task 'doc:graphs' =&gt; dest
+    CLEAN.include dest
+  end
+end
+
+desc 'Build default config documentation'
+task 'doc:source'
+FileList['lib/rack/cache/config/*.rb'].each do |source|
+  basename = File.basename(source)
+  dest = &quot;doc/config/#{basename}.html&quot;
+  file dest =&gt; source do |f|
+    mkdir_p &quot;doc/config&quot;
+    sh &quot;source-highlight -s ruby -f html -i #{source} -o #{dest}&quot;
+  end
+  task 'doc:source' =&gt; dest
+  CLEAN.include dest
+end
+
+desc 'Build markdown documentation files'
+task 'doc:markdown'
+FileList['doc/*.markdown'].each do |source|
+  dest = &quot;doc/#{File.basename(source, '.markdown')}.html&quot;
+  file dest =&gt; source do |f|
+    require 'erb'
+    require 'rdiscount'
+    template = File.read(source)
+    content = Markdown.new(ERB.new(template, 0, &quot;%&lt;&gt;&quot;).result(binding)).to_html
+    title = content.match(&quot;&lt;h1&gt;(.*)&lt;/h1&gt;&quot;)[1] rescue ''
+    layout = ERB.new(File.read(&quot;doc/layout.html.erb&quot;), 0, &quot;%&lt;&gt;&quot;)
+    output = layout.result(binding)
+    File.open(dest, 'w') { |io| io.write(output) }
+  end
+  task 'doc:markdown' =&gt; dest
+  CLEAN.include dest
+end
+file 'doc/configuration.html' =&gt; 'doc/config/default.rb.html'
+
+task 'doc:publish' =&gt; :doc do
+  sh 'rsync -avz doc/ gus@tomayko.com:/src/rack-cache'
+end
+
 # PACKAGING =================================================================
 
 def package(ext='')</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -7,33 +7,37 @@
 
   * Baseline caching logic moved out of config, into Rack::Cache::Core
   * Document events and transitions in rack/cache/config/default.rb
-  * Basic logging support.
-  * EntityStore: store entity bodies by SHA
-  * MetaStore: response headers by URL
+  * Basic logging support (trace, debug, warn, info from within Context)
+  * EntityStore: store entity bodies keyed by SHA
+  * MetaStore: store response headers keyed by URL
   * Add support for Vary
   * ETag validation
-  * Implement error transition
+  * Implement error! transition
   * memcached meta and entity store implementations
   * Get rid of default_entity_store
-  - URL based backing store configuration
-  - Update MetaStore/EntityStore documentation
-  - Tool to generate config file documentation
+  * URL based storage configuration
+  * Read options from Rack env if present (rack-cache.XXX keys)
+  * Document storage areas and implementations
+  - Document configuration/events
   - Document request, response, cached object
-  - Sample app
+  - Website
 
 ## 0.3
 
   - BUG: meta store hits but entity misses
-  - breakers.rb config and tests
-  - no-cache.rb config and tests
+  - BUG: HEAD request on invalid entry caches zero-length response
+  - Are we doing HEAD properly?
   - liberal, conservative, sane caching configs
+  - Sample app
+  - breakers.rb doc and tests
+  - no-cache.rb doc and tests
   - Canonicalized URL for cache key:
     - sorts params by key, then value
     - urlencodes /[^ A-Za-z0-9_.-]/ host, path, and param key/value
   - Support server-specific X-Sendfile (or similar) for delivering cached
     bodies.
   - Sqlite3 (meta store)
-  - Automatic cache invalidation on PUT, POST, DELETE.
+  - Cache invalidation on PUT, POST, DELETE.
     - Invalidate at the request URI; or, anything that's &quot;near&quot; the request URI.
     - Invalidate at the URI of the Location or Content-Location response header.
 
@@ -42,11 +46,9 @@
   - Purge/invalidate specific cache entries
   - Purge/invalidate everything
   - Maximum size of cached entity
-  - Are we doing HEAD properly?
   - Last-Modified factor: requests that have a Last-Modified header but no Expires
     header have a TTL assigned based on the last modified age of the response:
     TTL = (Age * Factor), or, 1h  = (10h * 0.1)
-  - Read options from Rack env if present (rack.cache.XXX keys)
   - I wonder if it would be possible to run in threaded mode but with an
     option to lock before making requests to the backend. The idea is to be
     able to serve requests from cache in separate threads. This should
@@ -57,3 +59,5 @@
   - When a cache misses due to Vary, try to validate using the best match. Note
     that you can't do this with a weak validator, so only strong etags can be
     used.
+  - Consider implementing ESI (http://www.w3.org/TR/esi-lang). This should
+    probably be implemented as a separate middleware component.</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -2,17 +2,50 @@ require 'fileutils'
 require 'time'
 require 'rack'
 
-# Rack Caching Middleware
+module Rack #:nodoc:
+end
+
+# = HTTP Caching For Rack
+#
+# Rack::Cache is suitable as a quick, drop-in component to enable HTTP caching
+# for Rack-enabled applications that produce freshness (+Expires+, +Cache-Control+)
+# and/or validation (+Last-Modified+, +ETag+) information.
+#
+# * Standards-based (RFC 2616 compliance)
+# * Freshness/expiration based caching and validation
+# * Supports HTTP Vary
+# * Portable: 100% Ruby / works with any Rack-enabled framework
+# * VCL-like configuration language for advanced caching policies
+# * Disk, memcached, and heap memory storage backends
+#
+# === Usage
+#
+# Create with default options:
+#   require 'rack/cache'
+#   Rack::Cache.new(app, :verbose =&gt; true, :entitystore =&gt; 'file:cache')
+#
+# Within a rackup file (or with Rack::Builder):
+#   require 'rack/cache'
+#   use Rack::Cache do
+#     set :verbose, true
+#     set :metastore, 'memcached://localhost:11211/meta'
+#     set :entitystore, 'file:/var/cache/rack'
+#   end
+#   run app
+#
 module Rack::Cache
   require 'rack/cache/request'
   require 'rack/cache/response'
   require 'rack/cache/context'
   require 'rack/cache/storage'
 
-  # Create a new Rack::Cache middleware component
-  # that fetches resources from the specified backend
-  # application.
+  # Create a new Rack::Cache middleware component that fetches resources from
+  # the specified backend application. The +options+ Hash can be used to
+  # specify default configuration values (see attributes defined in
+  # Rack::Cache::Options for possible key/values). When a block is given, it
+  # is executed within the context of the newly create Rack::Cache::Context
+  # object.
   def self.new(backend, options={}, &amp;b)
-    Context.new(backend, options={}, &amp;b)
+    Context.new(backend, options, &amp;b)
   end
 end</diff>
      <filename>lib/rack/cache.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,18 +14,18 @@ module Rack::Cache
   # logic, calls out to an event handler, and then kicks off the next
   # transition.
   #
-  # Five object of interest are made available during execution:
+  # Five objects of interest are made available during execution:
   #
-  # * #original_request - The request as originally received. This object
-  #   is not modified.
-  # * #request - The request that may eventually be sent downstream in
-  #   case of pass or miss. This object defaults to the #original_request
+  # * +original_request+ - The request as originally received. This object
+  #   is never modified.
+  # * +request+ - The request that may eventually be sent downstream in
+  #   case of pass or miss. This object defaults to the +original_request+
   #   but may be modified or replaced entirely.
-  # * #original_response - The response exactly as specified by the
-  #   downstream application. This is nil on cache hit.
-  # * #object - The response loaded from cache or stored to cache. This
-  #   object becomes #response if the cached response is valid.
-  # * #response - The response that will be delivered upstream after
+  # * +original_response+ - The response exactly as specified by the
+  #   downstream application; +nil+ on cache hit.
+  # * +object+ - The response loaded from cache or stored to cache. This
+  #   object becomes +response+ if the cached response is valid.
+  # * +response+ - The response that will be delivered upstream after
   #   processing is complete. This object may be modified as necessary.
   #
   # These objects can be accessed and modified from within event handlers
@@ -88,6 +88,7 @@ module Rack::Cache
       end
     end
 
+  private
     # Determine if the response's Last-Modified date matches the
     # If-Modified-Since value provided in the original request.
     def not_modified?</diff>
      <filename>lib/rack/cache/core.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,8 +4,6 @@ module Rack::Cache
   # Entity stores are used to cache response bodies across requests. All
   # Implementations are required to calculate a SHA checksum of the data written
   # which becomes the response body's key.
-  #--
-  # TODO document pros and cons of different EntityStore implementations
   class EntityStore
 
     # Read body calculating the SHA1 checksum and size while
@@ -147,7 +145,6 @@ module Rack::Cache
     DISK = Disk
     FILE = Disk
 
-
     # Stores entity bodies in memcached.
     class MemCache &lt; EntityStore
 </diff>
      <filename>lib/rack/cache/entitystore.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,21 +4,17 @@ require 'digest/sha1'
 
 module Rack::Cache
 
-  # The meta store is responsible for storing and retrieving negotiation
-  # tuples keyed by request URL.
+  # The meta store is responsible for storing meta information about a
+  # request/response pair keyed by the request's URL.
   #
-  # === Negotiation Tuples
-  #
-  # The meta store keeps a list of &quot;negotiation tuples&quot; for each canonical
-  # request URL. A negotiation tuple is a two element Array of the form:
+  # The meta store keeps a list of request/response pairs for each canonical
+  # request URL. A request/response pair is a two element Array of the form:
   #   [request, response]
   #
   # The +request+ element is a Hash of Rack environment keys. Only protocol
   # keys (i.e., those that start with &quot;HTTP_&quot;) are stored. The +response+
   # element is a Hash of cached HTTP response headers for the paired request.
   #
-  # === Backing Implementations
-  #
   # The MetaStore class is abstract and should not be instanstiated
   # directly. Concrete subclasses should implement the protected #read,
   # #write, and #purge methods. Care has been taken to keep these low-level
@@ -128,15 +124,15 @@ module Rack::Cache
     end
 
   protected
-    # Locate all cached negotiations that match the specified request
-    # URL key. The result must be an Array of all cached negotation
-    # tuples. An empty Array must be returned if nothing is cached for
+    # Locate all cached request/response pairs that match the specified
+    # URL key. The result must be an Array of all cached request/response
+    # pairs. An empty Array must be returned if nothing is cached for
     # the specified key.
     def read(key)
       raise NotImplemented
     end
 
-    # Store an Array of negotiation tuples for the given key. Concrete
+    # Store an Array of request/response pairs for the given key. Concrete
     # implementations should not attempt to filter or concatenate the
     # list in any way.
     def write(key, negotiations)
@@ -158,7 +154,7 @@ module Rack::Cache
   public
 
     # Concrete MetaStore implementation that uses a simple Hash to store
-    # negotiations on the heap.
+    # request/response pairs on the heap.
     class Heap &lt; MetaStore
       def initialize(hash={})
         @hash = hash
@@ -190,7 +186,8 @@ module Rack::Cache
     HEAP = Heap
     MEM = HEAP
 
-    # Concrete MetaStore implementation that stores negotiations on disk.
+    # Concrete MetaStore implementation that stores request/response
+    # pairs on disk.
     class Disk &lt; MetaStore
       attr_reader :root
 
@@ -252,7 +249,7 @@ module Rack::Cache
     DISK = Disk
     FILE = Disk
 
-    # Stores negotiation meta information in memcached. Keys are not stored
+    # Stores request/response pairs in memcached. Keys are not stored
     # directly since memcached has a 250-byte limit on key names. Instead,
     # the SHA-1 hexdigest of the key is used.
     class MemCache &lt; MetaStore</diff>
      <filename>lib/rack/cache/metastore.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 require 'rack/utils'
 
-module Rack::Utils
+module Rack::Utils #:nodoc:
   # A facade over a Rack Environment Hash that gives access to headers
   # using their normal RFC 2616 names.
 </diff>
      <filename>lib/rack/utils/environment_headers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
 
   s.name = 'rack-cache'
   s.version = '0.2'
-  s.date = '2008-09-21'
+  s.date = '2008-10-19'
 
   s.description = &quot;Caching middleware for Rack&quot;
   s.summary     = &quot;Caching middleware for Rack&quot;
@@ -16,10 +16,17 @@ Gem::Specification.new do |s|
   s.files = %w[
     CHANGES
     COPYING
-    README.markdown
+    README
     Rakefile
     TODO
-    doc/faq.txt
+    doc/configuration.markdown
+    doc/events.dot
+    doc/faq.markdown
+    doc/index.markdown
+    doc/layout.html.erb
+    doc/license.markdown
+    doc/rack-cache.css
+    doc/storage.markdown
     lib/rack/cache.rb
     lib/rack/cache/config.rb
     lib/rack/cache/config/breakers.rb
@@ -27,27 +34,29 @@ Gem::Specification.new do |s|
     lib/rack/cache/config/no-cache.rb
     lib/rack/cache/context.rb
     lib/rack/cache/core.rb
-    lib/rack/cache/entity_store.rb
+    lib/rack/cache/entitystore.rb
     lib/rack/cache/headers.rb
-    lib/rack/cache/meta_store.rb
+    lib/rack/cache/metastore.rb
     lib/rack/cache/options.rb
     lib/rack/cache/request.rb
     lib/rack/cache/response.rb
+    lib/rack/cache/storage.rb
     lib/rack/utils/environment_headers.rb
     rack-cache.gemspec
     test/cache_test.rb
     test/config_test.rb
     test/context_test.rb
     test/core_test.rb
-    test/entity_store_test.rb
+    test/entitystore_test.rb
     test/environment_headers_test.rb
     test/headers_test.rb
     test/logging_test.rb
-    test/meta_store_test.rb
+    test/metastore_test.rb
     test/options_test.rb
     test/pony.jpg
     test/response_test.rb
     test/spec_setup.rb
+    test/storage_test.rb
   ]
   # = MANIFEST =
 </diff>
      <filename>rack-cache.gemspec</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>README.markdown</filename>
    </removed>
    <removed>
      <filename>doc/faq.txt</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>6a4d996e646f0bcb53c2f923ce93796ae22ba117</id>
    </parent>
  </parents>
  <author>
    <name>Ryan Tomayko</name>
    <email>rtomayko@gmail.com</email>
  </author>
  <url>http://github.com/rtomayko/rack-cache/commit/5b59ea2e33216b8cb6af08bf45dcc24f0f545761</url>
  <id>5b59ea2e33216b8cb6af08bf45dcc24f0f545761</id>
  <committed-date>2008-10-19T22:24:34-07:00</committed-date>
  <authored-date>2008-10-18T11:01:28-07:00</authored-date>
  <message>documentation system + documentation</message>
  <tree>c579996e0be81b684674162535b756b49cf75142</tree>
  <committer>
    <name>Ryan Tomayko</name>
    <email>rtomayko@gmail.com</email>
  </committer>
</commit>
