| 1 | | %w[active_support markaby tempfile uri].map{|l|require l} |
| 2 | | module Camping;C=self;f=__FILE__;S=IO.read(f)unless f=~/\(/ |
| 3 | | P="Cam\ping Problem!";module Helpers;def R(c,*g);p,h=/\(.+?\)/,g.grep(Hash) |
| 4 | | (g-=h).inject(c.urls.find{|x|x.scan(p).size==g.size}.dup){|s,a|s.sub p,C. |
| 5 | | escape((a[a.class.primary_key]rescue a))}+(h.any?? "?"+h[0].map{|x|x.map{|z|C. |
| 6 | | escape z}*"="}*"&": "")end;def URL c='/',*a;c=R(c,*a)if c.respond_to?:urls |
| 7 | | c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI(c)end;def/p;p[/^\//]?@root+p : |
| 8 | | p end;def errors_for o;ul.errors{o.errors.each_full{|x|li x}}if o.errors.any?end |
| 9 | | end;module Base;attr_accessor:input,:cookies,:env,:headers,:body, |
| 10 | | :status,:root;def method_missing*a,&b;a.shift if a[0]==:render;m=Mab.new({},self) |
| 11 | | s=m.capture{send(*a,&b)};s=m.capture{send(:layout){s}}if /^_/!~a[0].to_s and m. |
| 12 | | respond_to?:layout;s end;def r s,b,h={};@status=s;@headers.merge!h;@body=b end |
| 13 | | def redirect*a;r 302,'','Location'=>URL(*a)end;Z="\r\n";def to_a;[@status,@body, |
| 14 | | @headers]end;def initialize r,e,m;e=H[e.to_hash];@status,@method,@env,@headers, |
| 15 | | @root=200,m.downcase,e,{'Content-Type'=>"text/html"},e.SCRIPT_NAME.sub(/\/$/,'') |
| 16 | | @k=C.kp e.HTTP_COOKIE;q=C.qsp e.QUERY_STRING;@in=r;if%r|\Amultipart/form-.*boun\ |
| 17 | | dary=\"?([^\";,]+)|n.match e.CONTENT_TYPE;b=/(?:\r?\n|\A)#{Regexp::quote("--#$1" |
| 18 | | )}(?:--)?\r$/;until@in.eof?;fh=H[];for l in@in;case l;when Z;break |
| 19 | | when/^Content-D.+?: form-data;/;fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten] |
| 20 | | when/^Content-Type: (.+?)(\r$|\Z)/m;fh[:type]=$1;end;end;fn=fh[:name];o=if |
| 21 | | fh[:filename];o=fh[:tempfile]=Tempfile.new(:C);o.binmode;else;fh=""end;s=8192;k= |
| 22 | | '';l=@in.read(s*2);while l;if(k<<l)=~b;o<<$`.chomp;@in.seek(-$'.size, |
| 23 | | IO::SEEK_CUR);break;end;o<<k.slice!(0...s);l=@in.read(s) |
| 24 | | end;C.qsp(fn,'&;',fh,q)if fn;fh[:tempfile].rewind if fh.is_a?H;end;elsif@method== |
| 25 | | "post" and e.CONTENT_TYPE == "application/x-www-form-urlencoded" |
| 26 | | q.u C.qsp(@in.read)end;@cookies,@input=@k.dup,q.dup end;def service*a |
| 27 | | @body=send(@method,*a)if respond_to?@method;@headers["Set-Cookie"]=@cookies.map{ |
| 28 | | |k,v|"#{k}=#{C.escape(v)}; path=#{self/'/'}"if v!=@k[k]}-[nil];self end;def to_s |
| 29 | | "Status: #{@status}#{Z+@headers.map{|k,v|[*v].map{|x|[k,v]*": "}}*Z+Z*2}#{@body}" |
| 30 | | end;end;X=module Controllers;@r=[];class<<self;def r;@r;end;def R*u |
| 31 | | r=@r;Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end;def M;def M |
| 32 | | end;constants.map{|c|k=const_get(c);k.send:include,C,Base,Helpers,Models;r[0,0]=k if |
| 33 | | !r.include?k;k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end;def |
| 34 | | D p;r.map{|k|k.urls.map{|x|return k,$~[1..-1]if p=~/^#{x}\/?$/}};[NotFound,[p]]end |
| 35 | | end;class NotFound<R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end |
| 36 | | class ServerError<R();def get k,m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class |
| 37 | | } #{e.message}:";ul{e.backtrace.each{|bt|li(bt)}}}.to_s)end end;self;end;class<< |
| 38 | | self;def goes m;eval S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING;end;def escape s |
| 39 | | s.to_s.gsub(/[^ \w.-]+/n){'%'+($&. |
| 40 | | unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')end;def un s;s.tr('+',' ').gsub( |
| 41 | | /%([\da-f]{2})/in){[$1].pack('H*')}end;def qsp q,d='&;',y=nil,z=H[];m=proc{|_,o,n|o.u( |
| 42 | | n,&m)rescue([*o]<<n)};q.to_s.split(/[#{d}]+ */n).inject((b,z=z,H[])[0]){|h,p|k,v=un(p). |
| 43 | | split('=',2);h.u k.split(/[\]\[]+/).reverse.inject(y||v){|x,i|H[i,x]},&m}end;def |
| 44 | | kp s;c=qsp(s,';,')end;def run r=$stdin,e=ENV;X.M;k,a=X.D un("/#{e[ |
| 45 | | 'PATH_INFO']}".gsub(/\/+/,'/'));k.new(r,e,(m=e['REQUEST_METHOD']||"GET")).Y.service(*a); |
| 46 | | rescue=>x;X::ServerError.new(r,e,'get').service(k,m,x)end |
| 47 | | def method_missing m,c,*a;X.M;k=X.const_get(c).new(StringIO.new,H['HTTP_HOST', |
| 48 | | '','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s);H.new(a.pop).each{|e,f|k.send( |
| 49 | | "#{e}=",f)}if Hash===a[-1];k.service(*a);end;end;module Views;include X,Helpers |
| 50 | | end;module Models;autoload:Base,'camping/db';def Y;self;end;end;class Mab< |
| 51 | | Markaby::Builder;include Views;def tag!*g,&b;h=g[-1];[:href,:action,:src].map{ |
| 52 | | |a|(h[a]=self/h[a])rescue 0};super end end;H=HashWithIndifferentAccess;class H |
| 53 | | def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m]:super end |
| 54 | | alias u regular_update;end end |
| | 1 | %w[active_support markaby tempfile uri].map{|l|require l};module Camping;C=self |
| | 2 | f=__FILE__;S=IO.read(f)unless f=~/\(/;P="Cam\ping Problem!";H= |
| | 3 | HashWithIndifferentAccess;class H;def method_missing m,*a;m.to_s=~/=$/?self[$` |
| | 4 | ]=a[0]:a==[]?self[m]:super end;alias u regular_update;end;module Helpers |
| | 5 | def R c,*g;p,h=/\(.+?\)/,g.grep(Hash);(g-=h).inject(c.urls.find{|x|x.scan(p). |
| | 6 | size==g.size}.dup){|s,a|s.sub p,C.escape((a[a.class.primary_key]rescue a))}+( |
| | 7 | h.any?? "?"+h[0].map{|x|x.map{|z|C.escape z}*"="}*"&": "")end;def errors_for o |
| | 8 | ul.errors{o.errors.each_full{|er|li er}}if o.errors.any?end;def /(p);p[/^\//]? |
| | 9 | @root+p:p end;def URL c='/',*a;c=R(c,*a)if c.respond_to?:urls;c=self/c;c="//"+ |
| | 10 | @env.HTTP_HOST+c if c[/^\//];URI(c) end end;module Base;attr_accessor:input, |
| | 11 | :cookies,:env,:headers,:body,:status,:root;Z="\r\n";def method_missing*a,&b;a. |
| | 12 | shift if a[0]==:render;m=Mab.new({},self);s=m.capture{send(*a,&b)};s=m.capture{ |
| | 13 | send(:layout){s}}if /^_/!~a[0].to_s and m.respond_to?:layout;s end;def |
| | 14 | redirect*a;r 302,'','Location'=>URL(*a)end;def r s,b,h={};@status=s;headers. |
| | 15 | merge!h;@body=b end;def to_a;[status,body,headers]end;def initialize r,e,m;e=H[ |
| | 16 | e.to_hash];@status,@method,@env,@headers,@root=200,m.downcase,e,{ |
| | 17 | 'Content-Type'=>"text/html"},e.SCRIPT_NAME.sub(/\/$/,'');@k=C.kp e.HTTP_COOKIE |
| | 18 | q=C.qsp e.QUERY_STRING;@in=r;if%r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n. |
| | 19 | match e.CONTENT_TYPE;b=/(?:\r?\n|\A)#{Regexp::quote"--#$1"}(?:--)?\r$/;until |
| | 20 | @in.eof?;fh=H[];for l in@in;case l;when Z;break;when/^Content-D.+?: form-data;/ |
| | 21 | fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten];when |
| | 22 | /^Content-Type: (.+?)(\r$|\Z)/m;fh[:type]=$1;end;end;fn=fh[:name];o=if fh[ |
| | 23 | :filename];o=fh[:tempfile]=Tempfile.new(:C);o.binmode;else;fh=""end;s=8192;k='' |
| | 24 | l=@in.read(s*2);while l;if(k<<l)=~b;o<<$`.chomp;@in.seek(-$'.size,IO::SEEK_CUR) |
| | 25 | break;end;o<<k.slice!(0...s);l=@in.read(s);end;C.qsp(fn,'&;',fh,q)if fn;fh[ |
| | 26 | :tempfile].rewind if fh.is_a?H;end;elsif@method=="post" && e.CONTENT_TYPE== |
| | 27 | "application/x-www-form-urlencoded";q.u C.qsp(@in.read)end;@cookies,@input=@k. |
| | 28 | dup,q.dup end;def service*a;@body=send(@method,*a)if respond_to?@method |
| | 29 | headers["Set-Cookie"]=cookies.map{|k,v|"#{k}=#{C.escape v}; path=#{self/'/'}"if |
| | 30 | v!=@k[k]}-[nil];self end;def to_s;"Status: #{status}#{Z+headers.map{|k,v|[*v]. |
| | 31 | map{|x|[k,v]*": "}}*Z+Z*2}#{body}"end;end;X=module Controllers;@r=[];class<< |
| | 32 | self;def r;@r;end;def R*u;r=@r;Class.new{meta_def(:urls){u};meta_def(:inherited |
| | 33 | ){|x|r<<x}}end;def D p;r.map{|k|k.urls.map{|x|return k,$~[1..-1]if p=~/^#{x |
| | 34 | }\/?$/}};[NotFound,[p]]end;def M;def M;end;constants.map{|c|k=const_get(c);k. |
| | 35 | send:include,C,Base,Helpers,Models;r[0,0]=k if !r.include?k;k.meta_def(:urls){[ |
| | 36 | "/#{c.downcase}"]}if !k.respond_to?:urls}end;end;class NotFound<R();def get p |
| | 37 | r(404,Mab.new{h1 P;h2 p+" not found"})end end;class ServerError<R();def get k, |
| | 38 | m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class} #{e.message}:";ul{e. |
| | 39 | backtrace.each{|bt|li bt}}})end end;self;end;class<<self;def goes m;eval S. |
| | 40 | gsub(/Camping/,m.to_s),TOPLEVEL_BINDING;end;def escape s;s.to_s.gsub( |
| | 41 | /[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')end;def un s |
| | 42 | s.tr('+',' ').gsub(/%([\da-f]{2})/in){[$1].pack('H*')}end;def qsp q,d='&;',y= |
| | 43 | nil,z=H[];m=proc{|_,o,n|o.u(n,&m)rescue([*o]<<n)};q.to_s.split(/[#{d}]+ */n). |
| | 44 | inject((b,z=z,H[])[0]){|h,p|k,v=un(p).split('=',2);h.u k.split(/[\]\[]+/). |
| | 45 | reverse.inject(y||v){|x,i|H[i,x]},&m}end;def kp s;c=qsp(s,';,')end;def |
| | 46 | run r=$stdin,e=ENV;X.M;k,a=X.D un("/#{e['PATH_INFO']}".gsub(/\/+/,'/'));k.new( |
| | 47 | r,e,(m=e['REQUEST_METHOD']||"GET")).Y.service(*a);rescue=>x;X::ServerError.new( |
| | 48 | r,e,'get').service(k,m,x)end;def method_missing m,c,*a;X.M;k=X.const_get(c). |
| | 49 | new(StringIO.new,H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s);H. |
| | 50 | new(a.pop).each{|e,f|k.send("#{e}=",f)}if Hash===a[-1];k.service(*a);end;end |
| | 51 | module Views;include X,Helpers;end;module Models;autoload:Base,'camping/db';def |
| | 52 | Y;self;end;end;class Mab<Markaby::Builder;include Views;def tag!*g,&b;h=g[-1] |
| | 53 | [:href,:action,:src].map{|a|(h[a]=self/h[a])rescue 0};super end end end |