| 6 | | escape z}*"="}*"&": "")end;def URL c='/',*a;c=R(c,*a)if c. |
| 7 | | respond_to?:urls;c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI(c)end;def/p |
| 8 | | p[/^\//]?@root+p : p end;def errors_for o;ul.errors{o.errors.each_full{|x|li x} |
| 9 | | }if o.errors.any?end end;module Base;include Helpers;attr_accessor:input, |
| 10 | | :cookies,:env,:headers,:body,:status,:root;def method_missing*a,&b |
| 11 | | a.shift if a[0]==:render;m=Mab.new({},self);s=m.capture{send(*a,&b)} |
| 12 | | s=m.capture{send(:layout){s}} if /^_/!~a[0].to_s and m.respond_to?:layout |
| 13 | | s end;def r s,b,h={};@status=s;@headers.merge!h;@body=b end |
| 14 | | def redirect*a;r 302,'','Location'=>URL(*a)end;Z="\r\n" |
| 15 | | def to_a;[@status,@body,@headers]end |
| 16 | | def initialize r,e,m;e=H[e.to_hash];@status,@method,@env,@headers,@root=200,m. |
| 17 | | downcase,e,{'Content-Type'=>"text/html"},e.SCRIPT_NAME.sub(/\/$/,'') |
| 18 | | @k=C.kp e.HTTP_COOKIE;q=C.qsp e.QUERY_STRING;@in=r |
| 19 | | if%r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n.match e.CONTENT_TYPE |
| 20 | | b=/(?:\r?\n|\A)#{Regexp::quote("--#$1")}(?:--)?\r$/;until@in.eof?;fh=H[];for l in@in |
| 21 | | case l;when Z;break;when/^Content-D.+?: form-data;/;fh.u H[*$'. |
| 22 | | scan(/(?:\s(\w+)="([^"]+)")/).flatten];when/^Content-Type: (.+?)(\r$|\Z)/m;fh[ |
| 23 | | :type]=$1;end;end;fn=fh[:name];o=if fh[:filename];o=fh[:tempfile]=Tempfile.new(:C) |
| 24 | | o.binmode;else;fh=""end;while l=@in.read(16384);if l=~b;o<<$`.chomp;@in.seek(-$'. |
| 25 | | size,IO::SEEK_CUR);break;end;o<<l;end;C.qsp(fn,'&;',fh,q) if fn;fh[:tempfile].rewind if |
| 26 | | fh.is_a?H;end;elsif@method=="post";q.u C.qsp(@in.read)end;@cookies,@input= |
| 27 | | @k.dup,q.dup end;def service*a;@body=send(@method,*a)if respond_to?@method |
| 28 | | @headers["Set-Cookie"]=@cookies.map{|k,v|"#{k}=#{C.escape(v)}; path=#{self/'/' |
| 29 | | }"if v!=@k[k]}-[nil];self end;def to_s;a=[];@headers.map{|k,v|[*v].map{|x|a<< |
| 30 | | "#{k}: #{x}"}};"Status: #{@status}#{Z+a*Z+Z*2+@body}"end;end |
| 31 | | X=module Controllers;@r=[];class<<self;def r;@r;end;def R*u;r=@r;Class.new{ |
| 32 | | meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end;def M;def M;end;constants.map{|c| |
| 33 | | k=const_get(c);k.send:include,C,Base,Models;r[0,0]=k if !r.include?k;k.meta_def( |
| 34 | | :urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end;def D p;r.map{|k|k.urls. |
| 35 | | map{|x|return k,$~[1..-1]if p=~/^#{x}\/?$/}};[NotFound,[p]]end end;class |
| 36 | | NotFound<R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end;class |
| 37 | | ServerError<R();def get k,m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class |
| | 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;include Helpers;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;while l=@in. |
| | 22 | read(16384);if l=~b;o<<$`.chomp;@in.seek(-$'.size,IO::SEEK_CUR);break;end;o<<l |
| | 23 | end;C.qsp(fn,'&;',fh,q) if fn;fh[:tempfile].rewind if fh.is_a?H;end;elsif@method== |
| | 24 | "post" and e.CONTENT_TYPE == "application/x-www-form-urlencoded" |
| | 25 | q.u C.qsp(@in.read)end;@cookies,@input=@k.dup,q.dup end;def service*a |
| | 26 | @body=send(@method,*a)if respond_to?@method;@headers["Set-Cookie"]=@cookies.map{ |
| | 27 | |k,v|"#{k}=#{C.escape(v)}; path=#{self/'/'}"if v!=@k[k]}-[nil];self end;def to_s |
| | 28 | a=[];@headers.map{|k,v|[*v].map{|x|a<<"#{k}: #{x}"}};"Status: #{@status}#{Z+a*Z+ |
| | 29 | Z*2+@body}"end;end;X=module Controllers;@r=[];class<<self;def r;@r;end;def R*u |
| | 30 | r=@r;Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end;def M;def M |
| | 31 | end;constants.map{|c|k=const_get(c);k.send:include,C,Base,Models;r[0,0]=k if |
| | 32 | !r.include?k;k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end;def |
| | 33 | D p;r.map{|k|k.urls.map{|x|return k,$~[1..-1]if p=~/^#{x}\/?$/}};[NotFound,[p]]end |
| | 34 | end;class NotFound<R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end |
| | 35 | class ServerError<R();def get k,m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class |