public
Description: the 4k pocket full-of-gags web microframework
Homepage: http://code.whytheluckystiff.net/camping/
Clone URL: git://github.com/why/camping.git
Search Repo:
* Introduced error 501 handling and changed NotFound and ServerError 
controllers to #r404 and #r500 methods. camping.rb is exactly at 4000 
octets !
* Some doc fixes in man page, README, CHANGELOG. Unfortunately the rdoc 
are still badly parsed.
zimbatm (author)
Tue Oct 02 13:23:16 -0700 2007
commit  d48556510fa0efda7b975d10f9a96299c11070a0
tree    62304245266dba6cf29fa958dec384d51c6e33bf
parent  4b6a2c828c5df614f2368135a41d062adc138d2a
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0
@@ -1,3 +1,22 @@
0
+= 1.6
0
+=== ???, 2007
0
+
0
+* Camping::Apps removed, it wasn't reliable.
0
+* bin/camping server kinds splitted in various files.
0
+* NotFound and ServerError controllers changed to methods :
0
+
0
+ r404 : called when a controller was not found
0
+ r500 : called on uncaught exception
0
+ r501 : called on undefined method
0
+
0
+ All of those can be overridden at your taste.
0
+
0
+* Markaby no longer required. Like AR, is it autoloaded on (Mab) usage.
0
+* Camping::H is now inheriting from Hash instead of HashWithIndifferentAccess.
0
+* Which made possible to remove the last strict dependency : active_support
0
+* #errors_for removed, it wasn't really used
0
+* Bug fixes !
0
+
0
 = 1.5
0
 === 3rd Oct, 2006
0
 
0
...
93
94
95
96
 
97
98
99
...
93
94
95
 
96
97
98
99
0
@@ -93,7 +93,7 @@ If you run them from the commandline, you'll probably just see a pile of HTML.
0
 Camping comes with an tool for launching apps from the commandline:
0
 
0
 * Run: <tt>camping blog.rb</tt>
0
-* Visit http://localhost:3301/blog/ to use the app.
0
+* Visit http://localhost:3301/ to use the app.
0
 
0
 == How the Camping Tool Works
0
 
...
146
147
148
149
150
151
152
...
155
156
157
158
 
159
160
161
...
146
147
148
 
149
150
151
...
154
155
156
 
157
158
159
160
0
@@ -146,7 +146,6 @@ namespace :check do
0
     end
0
     if File.size("lib/camping.rb") > SIZE_LIMIT
0
       STDERR.puts "lib/camping.rb: file is too big (> #{SIZE_LIMIT})"
0
- exit 1
0
     end
0
   end
0
 
0
@@ -155,7 +154,7 @@ namespace :check do
0
     i = 1
0
     File.open("lib/camping.rb").each_line do |line|
0
       if line.size > 81 # 1 added for \n
0
- puts "lib/camping.rb:#{i}: line too long (#{line[-10..-1].inspect})"
0
+ STDERR.puts "lib/camping.rb:#{i}: line too long (#{line[-10..-1].inspect})"
0
       end
0
       i += 1
0
     end
...
5
6
7
8
9
10
11
...
5
6
7
 
8
9
10
0
@@ -5,7 +5,6 @@ require 'ostruct'
0
 require 'stringio'
0
 require 'yaml'
0
 
0
-begin require 'rubygems' rescue LoadError end
0
 require 'camping'
0
 require 'camping/server'
0
 
...
30
31
32
33
34
35
 
 
36
37
38
...
91
92
93
94
 
95
96
97
...
322
323
324
 
 
 
 
 
 
 
 
 
 
 
 
325
326
327
...
338
339
340
341
342
 
 
 
 
 
 
 
 
 
 
 
 
343
344
 
 
 
 
 
 
 
 
345
346
 
347
348
 
 
 
 
 
 
349
350
 
 
 
 
351
352
353
...
364
365
366
367
 
368
369
370
...
417
418
419
420
 
421
422
423
...
493
494
495
496
 
497
498
499
 
 
500
501
502
 
503
504
505
...
517
518
519
520
 
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
 
 
 
575
576
577
...
660
661
662
663
664
665
666
 
 
 
 
667
668
669
...
30
31
32
 
 
 
33
34
35
36
37
...
90
91
92
 
93
94
95
96
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
...
349
350
351
 
 
352
353
354
355
356
357
358
359
360
361
362
363
364
 
365
366
367
368
369
370
371
372
373
 
374
375
 
376
377
378
379
380
381
382
 
383
384
385
386
387
388
389
...
400
401
402
 
403
404
405
406
...
453
454
455
 
456
457
458
459
...
529
530
531
 
532
533
534
 
535
536
537
538
 
539
540
541
542
...
554
555
556
 
557
558
559
560
561
562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
564
565
566
567
568
...
651
652
653
 
 
 
 
654
655
656
657
658
659
660
0
@@ -30,9 +30,8 @@
0
 #
0
 %w[tempfile uri].map { |l| require l }
0
 
0
-class Object
0
- # Define a method m with the passed block on the metaclass.
0
- def meta_def(m,&b)
0
+class Object #:nodoc:
0
+ def meta_def(m,&b) #:nodoc:
0
     (class<<self;self end).send(:define_method,m,&b)
0
   end
0
 end
0
@@ -91,7 +90,7 @@ end
0
 module Camping
0
   C = self
0
   S = IO.read(__FILE__) rescue nil
0
- P = "Cam\ping Problem!"
0
+ P = '<h1>Cam\ping Problem!</h1><h2>%s</h2>'
0
   # An object-like Hash.
0
   # All Camping query string and cookie variables are loaded as this.
0
   #
0
@@ -322,6 +321,18 @@ module Camping
0
       s
0
     end
0
 
0
+ # A quick means of setting this controller's status, body and headers.
0
+ # Used internally by Camping, but... by all means...
0
+ #
0
+ # r(302, '', 'Location' => self / "/view/12")
0
+ #
0
+ # Is equivalent to:
0
+ #
0
+ # redirect "/view/12"
0
+ #
0
+ # See also: #r404, #r500 and #r501
0
+ def r(s, b, h = {}); @status = s; headers.u(h); @body = b; end
0
+
0
     # Formulate a redirect response: a 302 status with <tt>Location</tt> header
0
     # and a blank body. Uses Helpers#URL to build the location from a controller
0
     # route or path.
0
@@ -338,16 +349,41 @@ module Camping
0
       r(302,'','Location'=>URL(*a))
0
     end
0
 
0
- # A quick means of setting this controller's status, body and headers.
0
- # Used internally by Camping, but... by all means...
0
+ # Called when a controller was not found. It is mainly used internally, but it can
0
+ # also be useful for you, if you want to filter some parameters.
0
+ #
0
+ # module Camping
0
+ # def r404(p=env.PATH)
0
+ # @status = 404
0
+ # div do
0
+ # h1 'Camping Problem!'
0
+ # h2 "#{p} not found"
0
+ # end
0
+ # end
0
+ # end
0
     #
0
- # r(302, '', 'Location' => self / "/view/12")
0
+ # See: I
0
+ def r404(p=env.PATH)
0
+ r(404, P % "#{p} not found")
0
+ end
0
+
0
+ # If there is a parse error in Camping or in your application's source code, it will not be caught
0
+ # by Camping. The controller class +k+ and request method +m+ (GET, POST, etc.) where the error
0
+ # took place are passed in, along with the Exception +e+ which can be mined for useful info.
0
     #
0
- # Is equivalent to:
0
+ # You can overide it, but if you have an error in here, it will be uncaught !
0
     #
0
- # redirect "/view/12"
0
+ # See: I
0
+ def r500(k,m,x)
0
+ r(500, P % "#{k}.#{m}" + "<h3>#{x.class} #{x.message}: <ul>#{x.backtrace.map{|b|"<li>#{b}</li>"}}</ul></h3>")
0
+ end
0
+
0
+ # Called if an undefined method is called on a Controller, along with the request method +m+ (GET, POST, etc.)
0
     #
0
- def r(s, b, h = {}); @status = s; headers.u(h); @body = b; end
0
+ # See: I
0
+ def r501(m=@method)
0
+ r(501, P % "#{m.upcase} not implemented")
0
+ end
0
 
0
     # Turn a controller into an array. This is designed to be used to pipe
0
     # controllers into the <tt>r</tt> method. A great way to forward your
0
@@ -364,7 +400,7 @@ module Camping
0
     def to_a;[status, body, headers] end
0
 
0
     def initialize(r, e, m) #:nodoc:
0
- @status, @method, @env, @headers, @root = 200, m.downcase, e,
0
+ @status, @method, @env, @headers, @root = 200, m, e,
0
           H['Content-Type','text/html'], e.SCRIPT_NAME.sub(/\/$/,'')
0
       @k = C.kp(e.HTTP_COOKIE)
0
       q = C.qsp(e.QUERY_STRING)
0
@@ -417,7 +453,7 @@ module Camping
0
     # See http://code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides for more
0
     # on before and after overrides with Camping.
0
     def service(*a)
0
- @body = send(@method, *a) if respond_to? @method
0
+ @body = send(@method, *a)
0
       headers['Set-Cookie'] = cookies.map { |k,v| "#{k}=#{C.escape(v)}; path=#{self/"/"}" if v != @k[k] } - [nil]
0
       self
0
     end
0
@@ -493,13 +529,14 @@ module Camping
0
       # # Classes with routes are searched in order of their creation.
0
       #
0
       # So, define your catch-all controllers last.
0
- def D(p)
0
+ def D(p, m)
0
         r.map { |k|
0
           k.urls.map { |x|
0
- return k, $~[1..-1] if p =~ /^#{x}\/?$/
0
+ return (k.instance_method(m) rescue nil) ?
0
+ [k, m, *$~[1..-1]] : [I, 'r501', m] if p =~ /^#{x}\/?$/
0
           }
0
         }
0
- [NotFound, [p]]
0
+ [I, 'r404', p]
0
       end
0
 
0
       # The route maker, this is called by Camping internally, you shouldn't need to call it.
0
@@ -517,61 +554,15 @@ module Camping
0
         constants.map { |c|
0
           k=const_get(c)
0
           k.send :include,C,Base,Helpers,Models
0
- r[0,0]=k if !r.include?k
0
+ @r=[k]+r if r-[k]==r
0
           k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls
0
         }
0
       end
0
     end
0
 
0
- # The NotFound class is a special controller class for handling 404 errors, in case you'd
0
- # like to alter the appearance of the 404. The path is passed in as +p+.
0
- #
0
- # module Camping::Controllers
0
- # class NotFound
0
- # def get(p)
0
- # @status = 404
0
- # div do
0
- # h1 'Camping Problem!'
0
- # h2 "#{p} not found"
0
- # end
0
- # end
0
- # end
0
- # end
0
- #
0
- class NotFound < R()
0
- def get(p)
0
- r(404, "<h1>#{P}</h1><h2>#{p} not found</h2>")
0
- end
0
- end
0
-
0
- # The ServerError class is a special controller class for handling many (but not all) 500 errors.
0
- # If there is a parse error in Camping or in your application's source code, it will not be caught
0
- # by Camping. The controller class +k+ and request method +m+ (GET, POST, etc.) where the error
0
- # took place are passed in, along with the Exception +e+ which can be mined for useful info.
0
- #
0
- # module Camping::Controllers
0
- # class ServerError
0
- # def get(k,m,e)
0
- # @status = 500
0
- # div do
0
- # h1 'Camping Problem!'
0
- # h2 "in #{k}.#{m}"
0
- # h3 "#{e.class} #{e.message}:"
0
- # ul do
0
- # e.backtrace.each do |bt|
0
- # li bt
0
- # end
0
- # end
0
- # end
0
- # end
0
- # end
0
- # end
0
- #
0
- class ServerError < R()
0
- def get(k,m,e)
0
- r(500, "<h1>#{P}</h1><h2>#{k}.#{m}</h2><h3>#{e.class} #{e.message
0
- }:<ul>#{e.backtrace.map{ |b| "<li>#{b}</li>" } }")
0
- end
0
+
0
+ # Internal controller with no route. Used by #D and C.run to show internal messages.
0
+ class I < R()
0
     end
0
 
0
     self
0
@@ -660,10 +651,10 @@ module Camping
0
     def run(r=$stdin,e=ENV)
0
       X.M
0
       e = H[e.to_hash]
0
- k,a=X.D e.PATH_INFO=un("/#{e.PATH_INFO}".gsub(/\/+/,'/'))
0
- k.new(r,e,(m=e.REQUEST_METHOD||"GET")).Y.service(*a)
0
- rescue=>x
0
- X::ServerError.new(r,e,'get').service(k,m,x)
0
+ k,m,*a=X.D e.PATH_INFO=un("/#{e.PATH_INFO}".gsub(/\/+/,'/')),(e.REQUEST_METHOD||'get').downcase
0
+ k.new(r,e,m).Y.service(*a)
0
+ rescue => x
0
+ X::I.new(r,e,'r500').service(k,m,x)
0
     end
0
 
0
     # The Camping scriptable dispatcher. Any unhandled method call to the app module will
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
49
50
51
52
53
54
55
56
57
58
 
 
 
 
 
 
 
 
 
 
 
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
 
 
 
 
 
 
 
 
 
51
52
53
54
55
56
57
58
59
60
61
0
@@ -1,58 +1,61 @@
0
-%w[tempfile uri].map{|l|require l};class Object;def meta_def m,&b
0
-(class<<self;self end).send(:define_method,m,&b)end end
0
-module Camping;C=self;S=IO.read(__FILE__)rescue nil;P="Cam\ping Problem!"
0
-class H<Hash;def method_missing m,*a
0
-m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end;alias u merge!
0
-undef id, type;end
0
-module Helpers def R c,*g;p,h=/\(.+?\)/,g.grep(Hash);g-=h;
0
-raise"bad route"unless u=c.urls.find{|x|break x if x.scan(p).size==g.size&&
0
-/^#{x}\/?$/=~(x=g.inject(x){|x,a|x.sub p,C.escape((a[a.class.primary_key
0
-]rescue a))})}
0
-h.any?? u+"?"+h[0].map{|x|x.map{|z|C.escape z}*"="}*"&":u end
0
-def /(p);p[/^\//]?@root+p:p;end;def URL c='/',*a
0
-c=R(c,*a)if c.respond_to?:urls;c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//]
0
-URI(c) end end;module Base;attr_accessor:input,:cookies,:env,:headers,:body,
0
-:status,:root;Z="\r\n";def method_missing*a,&b;a.shift if a[0]==:render
0
-m=Mab.new({},self);s=m.capture{send(*a,&b)};s=m.capture{send(:layout){s}}if
0
-/^_/!~a[0].to_s and m.respond_to?:layout;s end;def redirect*a
0
-r 302,'','Location'=>URL(*a)end;def r s,b,h={};@status=s;headers.u h
0
-@body=b end;def to_a;[status,body,headers]end;def initialize r,e,m
0
-@status,@method,@env,@headers,@root=200,m.downcase,e,H[
0
-'Content-Type',"text/html"],e.SCRIPT_NAME.sub(/\/$/,'');@k=C.kp e.HTTP_COOKIE
0
-q=C.qsp e.QUERY_STRING;@in=r;case e.CONTENT_TYPE
0
-when %r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n
0
-b=/(?:\r?\n|\A)#{Regexp::quote"--#$1"}(?:--)?\r$/;until
0
-@in.eof?;fh=H[];for l in@in;case l;when Z;break;when/^Content-D.+?: form-data;/
0
-fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten];when
0
-/^Content-Type: (.+?)(\r$|\Z)/m;fh.type=$1;end;end;fn=fh.name;o=if fh.
0
-filename;o=fh.tempfile=Tempfile.new(:C);o.binmode;else;fh=""end;s=8192;k=''
0
-l=@in.read(s*2);while l;if(k<<l)=~b;o<<$`.chomp;@in.seek(-$'.size,IO::SEEK_CUR)
0
-break;end;o<<k.slice!(0...s);l=@in.read(s);end;C.qsp(fn,'&;',fh,q)if fn;fh.
0
-tempfile.rewind if fh.is_a?H;end;when "application/x-www-form-urlencoded"
0
-q.u C.qsp(@in.read)end;@cookies,@input=@k.dup,q.dup end;def service*a
0
-@body=send(@method,*a)if respond_to?@method
0
-headers["Set-Cookie"]=cookies.map{|k,v|"#{k}=#{C.escape v}; path=#{self/'/'}"if
0
-v!=@k[k]}-[nil];self end;def to_s;"Status: #@status#{Z+headers.map{|k,v|[*v].
0
-map{|x|[k,v]*": "}}*Z+Z}#@body"end;end;X=module Controllers;@r=[];class<<
0
-self;def r;@r;end;def R*u;r=@r;Class.new{meta_def(:urls){u};meta_def(:inherited
0
-){|x|r<<x}}end;def D p;r.map{|k|k.urls.map{|x|return k,$~[1..-1]if p=~/^#{x
0
-}\/?$/}};[NotFound,[p]]end;def M;def M;end;constants.map{|c|k=const_get(c);k.
0
-send:include,C,Base,Helpers,Models;r[0,0]=k if !r.include?k;k.meta_def(:urls){[
0
-"/#{c.downcase}"]}if !k.respond_to?:urls}end;end;class NotFound<R();def get p
0
-r(404,"<h1>#{P}</h1><h2>#{p} not found</h2>")end end;class ServerError<R()
0
-def get k,m,e;r(500,"<h1>#{P}</h1><h2>#{k}.#{m}</h2><h3>#{e.class} #{e.message
0
-}:<ul>#{e.backtrace.map{ |b| "<li>#{b}</li>" } }")end end;self;end;class<<self
0
-def goes m;eval S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING;end;def escape s
0
-s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')
0
-end;def un s;s.tr('+',' ').gsub(/%([\da-f]{2})/in){[$1].pack('H*')}end
0
+%w[tempfile uri].map{|l|require l};class Object;def meta_def m,&b;(class<<self
0
+self end).send:define_method,m,&b end end;module Camping;C=self
0
+S=IO.read(__FILE__)rescue nil;P="<h1>Cam\\ping Problem!</h1><h2>%s</h2>"
0
+class H<Hash
0
+def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end
0
+alias u merge!;undef id,type;end;module Helpers;def R c,*g
0
+p,h=/\(.+?\)/,g.grep(Hash);g-=h;raise"bad route"unless u=c.urls.find{|x|
0
+break x if x.scan(p).size==g.size&&/^#{x}\/?$/=~(x=g.inject(x){|x,a|
0
+x.sub p,C.escape((a[a.class.primary_key]rescue a))})}
0
+h.any?? u+"?"+h[0].map{|x|x.map{|z|C.escape z}*"="}*"&":u end;def / p
0
+p[/^\//]?@root+p:p end;def URL c='/',*a;c=R(c, *a) if c.respond_to?:urls
0
+c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI c end end;module Base
0
+attr_accessor:input,:cookies,:env,:headers,:body,:status,:root;Z="\r\n"
0
+def method_missing *a,&b;a.shift if a[0]==:render;m=Mab.new({},self)
0
+s=m.capture{send(*a,&b)};s=m.capture{send(:layout){s}}if/^_/!~a[0].to_s and
0
+m.respond_to?:layout;s end;def r s,b,h={};@status=s;headers.u(h);@body=b
0
+end;def redirect *a;r 302,'','Location'=>URL(*a)end;def r404 p=env.PATH
0
+r 404,P%"#{p} not found"end;def r500 k,m,x
0
+r 500,P%"#{k}.#{m}"+"<h3>#{x.class} #{x.message}: <ul>#{x.
0
+backtrace.map{|b|"<li>#{b}</li>"}}</ul></h3>"end;def r501 m=@method
0
+r 501,P%"#{m.upcase} not implemented"end;def to_a
0
+[status,body,headers]end;def initialize r,e,m;@status,@method,@env,@headers,
0
+@root=200,m,e,H['Content-Type','text/html'],e.SCRIPT_NAME.sub(/\/$/,'')
0
+@k=C.kp e.HTTP_COOKIE;q=C.qsp e.QUERY_STRING;@in=r;case e.CONTENT_TYPE
0
+when%r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n
0
+b=/(?:\r?\n|\A)#{Regexp.quote"--#$1"}(?:--)?\r$/;until@in.eof?;fh=H[]
0
+for l in@in;case l;when Z;break;when/^Content-D.+?: form-data;/
0
+fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten]
0
+when/^Content-Type: (.+?)(\r$|\Z)/m: fh.type = $1 end end;fn=fh.name
0
+o=if fh.filename;o=fh.tempfile=Tempfile.new(:C);o.binmode;else;fh="";end;s=8192
0
+k='';l=@in.read(s*2);while l;if(k<<l)=~b;o<<$`.chomp
0
+@in.seek(-$'.size,IO::SEEK_CUR);break end;o<<k.slice!(0...s);l=@in.read(s) end
0
+C.qsp(fn,'&;',fh,q)if fn;fh.tempfile.rewind if fh.is_a?H end;when
0
+"application/x-www-form-urlencoded": q.u(C.qsp(@in.read))end
0
+@cookies,@input=@k.dup,q.dup end;def service *a;@body=send @method,*a
0
+headers['Set-Cookie']=cookies.map{|k,v|"#{k}=#{C.escape(v)}; path=#{self/
0
+"/"}"if v!=@k[k]}-[nil];self end;def to_s
0
+"Status: #@status#{Z+headers.map{|k,v|[*v].map{|x|[k,v]*": "}}*Z+Z}#@body"end
0
+end;X=module Controllers;@r=[];class<<self;def r;@r end;def R *u;r=@r
0
+Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end
0
+def D p,m;r.map{|k|k.urls.map{|x|return(k.instance_method(m)rescue nil)?
0
+[k,m,*$~[1..-1]]:[I,'r501',m]if p=~/^#{x}\/?$/}};[I,'r404',p]
0
+end;def M;def M;end;constants.map{|c|k=const_get(c)
0
+k.send:include,C,Base,Helpers,Models;@r=[k]+r if r-[k]==r
0
+k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end end;class I<R()
0
+end;self end;class<<self;def goes m
0
+eval S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING end;def escape s
0
+s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr' ','+'
0
+end;def un s;s.tr('+',' ').gsub(/%([\da-f]{2})/in){[$1].pack'H*'}end
0
 def qsp q,d='&;',y=nil,z=H[];m=proc{|_,o,n|o.u(n,&m)rescue([*o]<<n)}
0
-(q.to_s.split(/[#{d}]+ */n)-['']).inject((b,z=z,H[])[0]){|h,p|k,v=un(p).
0
-split('=',2);h.u k.split(/[\]\[]+/).reverse.inject(y||v){|x,i|H[i,x]},&m}end
0
-def kp s;c=qsp(s,';,')end;def run r=$stdin,e=ENV;X.M;e=H[e.to_hash]
0
-k,a=X.D e.PATH_INFO=un("/#{e.PATH_INFO}".gsub(/\/+/,'/'));k.new(
0
-r,e,(m=e.REQUEST_METHOD||"GET")).Y.service(*a);rescue=>x;X::ServerError.new(
0
-r,e,'get').service(k,m,x)end;def method_missing m,c,*a;X.M;k=X.const_get(c).
0
-new(StringIO.new,H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s)
0
-H[a.pop].each{|e,f|k.send("#{e}=",f)}if Hash===a[-1];k.service(*a);end;end
0
-module Views;include X,Helpers;end;module Models;autoload:Base,'camping/db';def
0
-Y;self;end;end;autoload:Mab,'camping/mab'end
0
+(q.to_s.split(/[#{d}]+ */n)-[""]).inject((b,z=z,H[])[0]){|h,p|k,v=un(p).
0
+split'=',2;h.u k.split(/[\]\[]+/).reverse.inject(y||v){|x,i|H[i,x]},&m}end
0
+def kp s;c=qsp s,';,'end;def run r=$stdin,e=ENV;X.M;e=H[e.to_hash];k,m,*a=X.D e.
0
+PATH_INFO=un("/#{e.PATH_INFO}".gsub(/\/+/,'/')),
0
+(e.REQUEST_METHOD||'get').downcase
0
+k.new(r,e,m).Y.service(*a);rescue=>x;X::I.new(r,e,'r500').service k,m,x
0
+end;def method_missing m,c,*a;X.M;k=X.const_get(c).new StringIO.new,
0
+H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s
0
+H[a.pop].each{|e,f|k.send"#{e}=",f}if Hash===a[-1];k.service(*a)end end
0
+module Views;include X,Helpers end;module Models;autoload:Base,'camping/db'
0
+def Y;self;end end;autoload:Mab,'camping/mab'end
...
94
95
96
97
 
98
99
100
101
102
103
104
...
94
95
96
 
97
98
99
 
 
 
100
101
0
@@ -94,11 +94,8 @@ class Base < Hash
0
   private
0
   
0
   def insert_app(script)
0
- self[script] = Application.new(script)
0
+ self[script] = Reloader.new(script)
0
   end
0
 end
0
-
0
-class Application < Camping::Reloader
0
-end
0
 end
0
 
...
28
29
30
 
31
32
33
...
42
43
44
 
45
46
47
...
28
29
30
31
32
33
34
...
43
44
45
46
47
48
49
0
@@ -28,6 +28,7 @@ module Misc
0
     class BadLinks
0
       def get; render :bad_links; end
0
     end
0
+ class BadMethod; end
0
   end
0
 
0
   module Views
0
@@ -42,6 +43,7 @@ module Misc
0
             li{ a "Links", :href=>R(Links)}
0
             li{ a "BadLinks", :href=>R(BadLinks)}
0
             li{ a "Redirect", :href=>R(Redirect)}
0
+ li{ a "BadMethod", :href=>R(BadMethod)}
0
           end
0
           p { yield }
0
         end

Comments

    No one has commented yet.