package Net::SPDY::Compressor; =head1 NAME Net::SPDY::Compressor - SPDY header compressor =head1 ALPHA WARNING B This is an ALPHA stage software. In particular this means that even though it probably won't kill your cat, re-elect George W. Bush nor install Solaris 11 Express edition to your hard drive, it is in active development, functionality is missing and no APIs are stable. See F file in the distribution to learn about missing and planned functionality. You are more than welcome to join the development and submit patches with fixes or enhancements. Bug reports are probably not very useful at this point. =head1 SYNOPSIS use Net::SPDY::Compressor; my $compr = new Net::SPDY::Compressor; print $compr->uncompress($compr->compress("Hello, World!\n")); =head1 DESCRIPTION B provides a convenient way to compress data in a way used by the SPDY protocol. This, in particular, means, that there are two separate streams (for input and output), streams are synced after each message and the stream is initialized with a dictionary of strings common to web communication. =cut use strict; use warnings; use Compress::Zlib qw/inflateInit deflateInit Z_SYNC_FLUSH/; our $VERSION = '0.1'; =head1 CONSTANTS For the actual values refer to the protocol specification. =over 4 =item C The initial SPDY compression dictionary. =back =cut use constant DICT => "\x00\x00\x00\x07\x6f\x70\x74\x69". #----opti "\x6f\x6e\x73\x00\x00\x00\x04\x68". #ons----h "\x65\x61\x64\x00\x00\x00\x04\x70". #ead----p "\x6f\x73\x74\x00\x00\x00\x03\x70". #ost----p "\x75\x74\x00\x00\x00\x06\x64\x65". #ut----de "\x6c\x65\x74\x65\x00\x00\x00\x05". #lete---- "\x74\x72\x61\x63\x65\x00\x00\x00". #trace--- "\x06\x61\x63\x63\x65\x70\x74\x00". #-accept- "\x00\x00\x0e\x61\x63\x63\x65\x70". #---accep "\x74\x2d\x63\x68\x61\x72\x73\x65". #t-charse "\x74\x00\x00\x00\x0f\x61\x63\x63". #t----acc "\x65\x70\x74\x2d\x65\x6e\x63\x6f". #ept-enco "\x64\x69\x6e\x67\x00\x00\x00\x0f". #ding---- "\x61\x63\x63\x65\x70\x74\x2d\x6c". #accept-l "\x61\x6e\x67\x75\x61\x67\x65\x00". #anguage- "\x00\x00\x0d\x61\x63\x63\x65\x70". #---accep "\x74\x2d\x72\x61\x6e\x67\x65\x73". #t-ranges "\x00\x00\x00\x03\x61\x67\x65\x00". #----age- "\x00\x00\x05\x61\x6c\x6c\x6f\x77". #---allow "\x00\x00\x00\x0d\x61\x75\x74\x68". #----auth "\x6f\x72\x69\x7a\x61\x74\x69\x6f". #orizatio "\x6e\x00\x00\x00\x0d\x63\x61\x63". #n----cac "\x68\x65\x2d\x63\x6f\x6e\x74\x72". #he-contr "\x6f\x6c\x00\x00\x00\x0a\x63\x6f". #ol----co "\x6e\x6e\x65\x63\x74\x69\x6f\x6e". #nnection "\x00\x00\x00\x0c\x63\x6f\x6e\x74". #----cont "\x65\x6e\x74\x2d\x62\x61\x73\x65". #ent-base "\x00\x00\x00\x10\x63\x6f\x6e\x74". #----cont "\x65\x6e\x74\x2d\x65\x6e\x63\x6f". #ent-enco "\x64\x69\x6e\x67\x00\x00\x00\x10". #ding---- "\x63\x6f\x6e\x74\x65\x6e\x74\x2d". #content- "\x6c\x61\x6e\x67\x75\x61\x67\x65". #language "\x00\x00\x00\x0e\x63\x6f\x6e\x74". #----cont "\x65\x6e\x74\x2d\x6c\x65\x6e\x67". #ent-leng "\x74\x68\x00\x00\x00\x10\x63\x6f". #th----co "\x6e\x74\x65\x6e\x74\x2d\x6c\x6f". #ntent-lo "\x63\x61\x74\x69\x6f\x6e\x00\x00". #cation-- "\x00\x0b\x63\x6f\x6e\x74\x65\x6e". #--conten "\x74\x2d\x6d\x64\x35\x00\x00\x00". #t-md5--- "\x0d\x63\x6f\x6e\x74\x65\x6e\x74". #-content "\x2d\x72\x61\x6e\x67\x65\x00\x00". #-range-- "\x00\x0c\x63\x6f\x6e\x74\x65\x6e". #--conten "\x74\x2d\x74\x79\x70\x65\x00\x00". #t-type-- "\x00\x04\x64\x61\x74\x65\x00\x00". #--date-- "\x00\x04\x65\x74\x61\x67\x00\x00". #--etag-- "\x00\x06\x65\x78\x70\x65\x63\x74". #--expect "\x00\x00\x00\x07\x65\x78\x70\x69". #----expi "\x72\x65\x73\x00\x00\x00\x04\x66". #res----f "\x72\x6f\x6d\x00\x00\x00\x04\x68". #rom----h "\x6f\x73\x74\x00\x00\x00\x08\x69". #ost----i "\x66\x2d\x6d\x61\x74\x63\x68\x00". #f-match- "\x00\x00\x11\x69\x66\x2d\x6d\x6f". #---if-mo "\x64\x69\x66\x69\x65\x64\x2d\x73". #dified-s "\x69\x6e\x63\x65\x00\x00\x00\x0d". #ince---- "\x69\x66\x2d\x6e\x6f\x6e\x65\x2d". #if-none- "\x6d\x61\x74\x63\x68\x00\x00\x00". #match--- "\x08\x69\x66\x2d\x72\x61\x6e\x67". #-if-rang "\x65\x00\x00\x00\x13\x69\x66\x2d". #e----if- "\x75\x6e\x6d\x6f\x64\x69\x66\x69". #unmodifi "\x65\x64\x2d\x73\x69\x6e\x63\x65". #ed-since "\x00\x00\x00\x0d\x6c\x61\x73\x74". #----last "\x2d\x6d\x6f\x64\x69\x66\x69\x65". #-modifie "\x64\x00\x00\x00\x08\x6c\x6f\x63". #d----loc "\x61\x74\x69\x6f\x6e\x00\x00\x00". #ation--- "\x0c\x6d\x61\x78\x2d\x66\x6f\x72". #-max-for "\x77\x61\x72\x64\x73\x00\x00\x00". #wards--- "\x06\x70\x72\x61\x67\x6d\x61\x00". #-pragma- "\x00\x00\x12\x70\x72\x6f\x78\x79". #---proxy "\x2d\x61\x75\x74\x68\x65\x6e\x74". #-authent "\x69\x63\x61\x74\x65\x00\x00\x00". #icate--- "\x13\x70\x72\x6f\x78\x79\x2d\x61". #-proxy-a "\x75\x74\x68\x6f\x72\x69\x7a\x61". #uthoriza "\x74\x69\x6f\x6e\x00\x00\x00\x05". #tion---- "\x72\x61\x6e\x67\x65\x00\x00\x00". #range--- "\x07\x72\x65\x66\x65\x72\x65\x72". #-referer "\x00\x00\x00\x0b\x72\x65\x74\x72". #----retr "\x79\x2d\x61\x66\x74\x65\x72\x00". #y-after- "\x00\x00\x06\x73\x65\x72\x76\x65". #---serve "\x72\x00\x00\x00\x02\x74\x65\x00". #r----te- "\x00\x00\x07\x74\x72\x61\x69\x6c". #---trail "\x65\x72\x00\x00\x00\x11\x74\x72". #er----tr "\x61\x6e\x73\x66\x65\x72\x2d\x65". #ansfer-e "\x6e\x63\x6f\x64\x69\x6e\x67\x00". #ncoding- "\x00\x00\x07\x75\x70\x67\x72\x61". #---upgra "\x64\x65\x00\x00\x00\x0a\x75\x73". #de----us "\x65\x72\x2d\x61\x67\x65\x6e\x74". #er-agent "\x00\x00\x00\x04\x76\x61\x72\x79". #----vary "\x00\x00\x00\x03\x76\x69\x61\x00". #----via- "\x00\x00\x07\x77\x61\x72\x6e\x69". #---warni "\x6e\x67\x00\x00\x00\x10\x77\x77". #ng----ww "\x77\x2d\x61\x75\x74\x68\x65\x6e". #w-authen "\x74\x69\x63\x61\x74\x65\x00\x00". #ticate-- "\x00\x06\x6d\x65\x74\x68\x6f\x64". #--method "\x00\x00\x00\x03\x67\x65\x74\x00". #----get- "\x00\x00\x06\x73\x74\x61\x74\x75". #---statu "\x73\x00\x00\x00\x06\x32\x30\x30". #s----200 "\x20\x4f\x4b\x00\x00\x00\x07\x76". #-OK----v "\x65\x72\x73\x69\x6f\x6e\x00\x00". #ersion-- "\x00\x08\x48\x54\x54\x50\x2f\x31". #--HTTP-1 "\x2e\x31\x00\x00\x00\x03\x75\x72". #-1----ur "\x6c\x00\x00\x00\x06\x70\x75\x62". #l----pub "\x6c\x69\x63\x00\x00\x00\x0a\x73". #lic----s "\x65\x74\x2d\x63\x6f\x6f\x6b\x69". #et-cooki "\x65\x00\x00\x00\x0a\x6b\x65\x65". #e----kee "\x70\x2d\x61\x6c\x69\x76\x65\x00". #p-alive- "\x00\x00\x06\x6f\x72\x69\x67\x69". #---origi "\x6e\x31\x30\x30\x31\x30\x31\x32". #n1001012 "\x30\x31\x32\x30\x32\x32\x30\x35". #01202205 "\x32\x30\x36\x33\x30\x30\x33\x30". #20630030 "\x32\x33\x30\x33\x33\x30\x34\x33". #23033043 "\x30\x35\x33\x30\x36\x33\x30\x37". #05306307 "\x34\x30\x32\x34\x30\x35\x34\x30". #40240540 "\x36\x34\x30\x37\x34\x30\x38\x34". #64074084 "\x30\x39\x34\x31\x30\x34\x31\x31". #09410411 "\x34\x31\x32\x34\x31\x33\x34\x31". #41241341 "\x34\x34\x31\x35\x34\x31\x36\x34". #44154164 "\x31\x37\x35\x30\x32\x35\x30\x34". #17502504 "\x35\x30\x35\x32\x30\x33\x20\x4e". #505203-N "\x6f\x6e\x2d\x41\x75\x74\x68\x6f". #on-Autho "\x72\x69\x74\x61\x74\x69\x76\x65". #ritative "\x20\x49\x6e\x66\x6f\x72\x6d\x61". #-Informa "\x74\x69\x6f\x6e\x32\x30\x34\x20". #tion204- "\x4e\x6f\x20\x43\x6f\x6e\x74\x65". #No-Conte "\x6e\x74\x33\x30\x31\x20\x4d\x6f". #nt301-Mo "\x76\x65\x64\x20\x50\x65\x72\x6d". #ved-Perm "\x61\x6e\x65\x6e\x74\x6c\x79\x34". #anently4 "\x30\x30\x20\x42\x61\x64\x20\x52". #00-Bad-R "\x65\x71\x75\x65\x73\x74\x34\x30". #equest40 "\x31\x20\x55\x6e\x61\x75\x74\x68". #1-Unauth "\x6f\x72\x69\x7a\x65\x64\x34\x30". #orized40 "\x33\x20\x46\x6f\x72\x62\x69\x64". #3-Forbid "\x64\x65\x6e\x34\x30\x34\x20\x4e". #den404-N "\x6f\x74\x20\x46\x6f\x75\x6e\x64". #ot-Found "\x35\x30\x30\x20\x49\x6e\x74\x65". #500-Inte "\x72\x6e\x61\x6c\x20\x53\x65\x72". #rnal-Ser "\x76\x65\x72\x20\x45\x72\x72\x6f". #ver-Erro "\x72\x35\x30\x31\x20\x4e\x6f\x74". #r501-Not "\x20\x49\x6d\x70\x6c\x65\x6d\x65". #-Impleme "\x6e\x74\x65\x64\x35\x30\x33\x20". #nted503- "\x53\x65\x72\x76\x69\x63\x65\x20". #Service- "\x55\x6e\x61\x76\x61\x69\x6c\x61". #Unavaila "\x62\x6c\x65\x4a\x61\x6e\x20\x46". #bleJan-F "\x65\x62\x20\x4d\x61\x72\x20\x41". #eb-Mar-A "\x70\x72\x20\x4d\x61\x79\x20\x4a". #pr-May-J "\x75\x6e\x20\x4a\x75\x6c\x20\x41". #un-Jul-A "\x75\x67\x20\x53\x65\x70\x74\x20". #ug-Sept- "\x4f\x63\x74\x20\x4e\x6f\x76\x20". #Oct-Nov- "\x44\x65\x63\x20\x30\x30\x3a\x30". #Dec-00-0 "\x30\x3a\x30\x30\x20\x4d\x6f\x6e". #0-00-Mon "\x2c\x20\x54\x75\x65\x2c\x20\x57". #--Tue--W "\x65\x64\x2c\x20\x54\x68\x75\x2c". #ed--Thu- "\x20\x46\x72\x69\x2c\x20\x53\x61". #-Fri--Sa "\x74\x2c\x20\x53\x75\x6e\x2c\x20". #t--Sun-- "\x47\x4d\x54\x63\x68\x75\x6e\x6b". #GMTchunk "\x65\x64\x2c\x74\x65\x78\x74\x2f". #ed-text- "\x68\x74\x6d\x6c\x2c\x69\x6d\x61". #html-ima "\x67\x65\x2f\x70\x6e\x67\x2c\x69". #ge-png-i "\x6d\x61\x67\x65\x2f\x6a\x70\x67". #mage-jpg "\x2c\x69\x6d\x61\x67\x65\x2f\x67". #-image-g "\x69\x66\x2c\x61\x70\x70\x6c\x69". #if-appli "\x63\x61\x74\x69\x6f\x6e\x2f\x78". #cation-x "\x6d\x6c\x2c\x61\x70\x70\x6c\x69". #ml-appli "\x63\x61\x74\x69\x6f\x6e\x2f\x78". #cation-x "\x68\x74\x6d\x6c\x2b\x78\x6d\x6c". #html-xml "\x2c\x74\x65\x78\x74\x2f\x70\x6c". #-text-pl "\x61\x69\x6e\x2c\x74\x65\x78\x74". #ain-text "\x2f\x6a\x61\x76\x61\x73\x63\x72". #-javascr "\x69\x70\x74\x2c\x70\x75\x62\x6c". #ipt-publ "\x69\x63\x70\x72\x69\x76\x61\x74". #icprivat "\x65\x6d\x61\x78\x2d\x61\x67\x65". #emax-age "\x3d\x67\x7a\x69\x70\x2c\x64\x65". #-gzip-de "\x66\x6c\x61\x74\x65\x2c\x73\x64". #flate-sd "\x63\x68\x63\x68\x61\x72\x73\x65". #chcharse "\x74\x3d\x75\x74\x66\x2d\x38\x63". #t-utf-8c "\x68\x61\x72\x73\x65\x74\x3d\x69". #harset-i "\x73\x6f\x2d\x38\x38\x35\x39\x2d". #so-8859- "\x31\x2c\x75\x74\x66\x2d\x2c\x2a". #1-utf--- "\x2c\x65\x6e\x71\x3d\x30\x2e"; #-enq-0- =head1 METHODS =over 4 =item new Creates a new compressor instance. =cut sub new { my $class = shift; my $self = bless {}, $class; # Initiate the Zlib streams my $status; ($self->{inflater}, $status) = inflateInit ( -Dictionary => DICT); die $status if $status; ($self->{deflater}, $status) = deflateInit ( -Level => 0, -Dictionary => DICT); die $status if $status; return $self; } =item compress STRING Returns a compressed string. =cut sub compress { my $self = shift; my $msg = shift; my ($o1, $o2, $status); ($o1, $status) = $self->{deflater}->deflate ($msg); die $status if $status; ($o2, $status) = $self->{deflater}->flush (Z_SYNC_FLUSH); die $status if $status; return $o1.$o2; } =item uncompress STRING Returns an uncompressed string given a compressed one. =cut sub uncompress { my $self = shift; my $msg = shift; my ($out, $status) = $self->{inflater}->inflate (\$msg); die $status if $status; return $out; } =back =head1 SEE ALSO =over =item * L -- SPDY project web site =item * L -- Protocol specification =back =head1 CONTRIBUTING Source code for I is kept in a public GIT repository. Visit L. Bugs reports and feature enhancement requests are tracked at L. =head1 COPYRIGHT Copyright 2012, Lubomir Rintel This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Lubomir Rintel C =cut 1;