summary refs log tree commit
diff options
context:
space:
mode:
authorJames Tucker <jftucker@gmail.com>2013-04-29 11:55:32 -0700
committerJames Tucker <jftucker@gmail.com>2013-04-29 11:55:32 -0700
commit1cefdc0503dd92bf7c260bc85e4a67ded9ceeda6 (patch)
tree812fb1a16a751d52bf295d2b42c696c05bb9e80a
parent9a76a1116025eed19e0220c088bd6b0bdac9a6ff (diff)
downloadrack-1cefdc0503dd92bf7c260bc85e4a67ded9ceeda6.tar.gz
Add deflated JSON support
-rw-r--r--lib/rack/session/cookie.rb14
-rw-r--r--test/spec_session_cookie.rb22
2 files changed, 36 insertions, 0 deletions
diff --git a/lib/rack/session/cookie.rb b/lib/rack/session/cookie.rb
index be537a9c..22e33d1f 100644
--- a/lib/rack/session/cookie.rb
+++ b/lib/rack/session/cookie.rb
@@ -1,4 +1,5 @@
 require 'openssl'
+require 'zlib'
 require 'rack/request'
 require 'rack/response'
 require 'rack/session/abstract/id'
@@ -78,6 +79,19 @@ module Rack
             ::Rack::Utils::OkJson.decode(super(str)) rescue nil
           end
         end
+
+        class ZipJSON < Base64
+          def encode(obj)
+            super(Zlib::Deflate.deflate(::Rack::Utils::OkJson.encode(obj)))
+          end
+
+          def decode(str)
+            return unless str
+            ::Rack::Utils::OkJson.decode(Zlib::Inflate.inflate(super(str)))
+          rescue
+            nil
+          end
+        end
       end
 
       # Use no encoding for session cookies
diff --git a/test/spec_session_cookie.rb b/test/spec_session_cookie.rb
index 94c34654..f5d69b16 100644
--- a/test/spec_session_cookie.rb
+++ b/test/spec_session_cookie.rb
@@ -119,6 +119,28 @@ describe Rack::Session::Cookie do
         coder.decode('lulz').should.equal nil
       end
     end
+
+    describe 'ZipJSON' do
+      it 'jsons, deflates, and base64 encodes' do
+        coder = Rack::Session::Cookie::Base64::ZipJSON.new
+        obj   = %w[fuuuuu]
+        json = Rack::Utils::OkJson.encode(obj)
+        coder.encode(obj).should.equal [Zlib::Deflate.deflate(json)].pack('m')
+      end
+
+      it 'base64 decodes, inflates, and decodes json' do
+        coder = Rack::Session::Cookie::Base64::ZipJSON.new
+        obj   = %w[fuuuuu]
+        json  = Rack::Utils::OkJson.encode(obj)
+        b64   = [Zlib::Deflate.deflate(json)].pack('m')
+        coder.decode(b64).should.equal obj
+      end
+
+      it 'rescues failures on decode' do
+        coder = Rack::Session::Cookie::Base64::ZipJSON.new
+        coder.decode('lulz').should.equal nil
+      end
+    end
   end
 
   it "warns if no secret is given" do