
The camping module contains three modules for separating your application:
Of use to you is also one module for storing helpful additional methods:
How do you run Camping apps? Oh, uh… The Camping Server!
The Camping Server is, firstly and thusly, a set of rules. At the very least, The Camping Server must:
In fact, Camping comes with its own little The Camping Server.
At a command prompt, run: camping examples/ and the entire examples/ directory will be served.
Configurations also exist for Apache and Lighttpd. See code.whytheluckystiff.net/camping/wiki/TheCampingServer.
Many postambles will check for your application‘s create method and will run it when the web server starts up. This is a good place to check for database tables and create those tables to save users of your application from needing to manually set them up.
def Blog.create
unless Blog::Models::Post.table_exists?
ActiveRecord::Schema.define do
create_table :blog_posts, :force => true do |t|
t.column :id, :integer, :null => false
t.column :user_id, :integer, :null => false
t.column :title, :string, :limit => 255
t.column :body, :text
end
end
end
end
For more tips, see code.whytheluckystiff.net/camping/wiki/GiveUsTheCreateMethod.

URL escapes a string.
Camping.escape("I'd go to the museum straightway!")
#=> "I%27d+go+to+the+museum+straightway%21"
[ show source ]
# File lib/camping.rb, line 606
606: def escape(s); s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ', '+') end

When you are running many applications, you may want to create independent modules for each Camping application. Namespaces for each. Camping::goes defines a toplevel constant with the whole MVC rack inside.
require 'camping' Camping.goes :Blog module Blog::Controllers; ... end module Blog::Models; ... end module Blog::Views; ... end
[ show source ]
# File lib/camping.rb, line 597
597: def goes(m)
598: eval S.gsub(/Camping/,m.to_s).gsub("A\pps = []","Cam\ping::Apps<<self"), TOPLEVEL_BINDING
599: end

Parses a string of cookies from the Cookie header.
[ show source ]
# File lib/camping.rb, line 638
638: def kp(s); c = qs_parse(s, ';,'); end

The Camping scriptable dispatcher. Any unhandled method call to the app module will be sent to a controller class, specified as an argument.
Blog.get(:Index) #=> #<Blog::Controllers::Index ... >
The controller object contains all the @cookies, @body, @headers, etc. formulated by the response.
You can also feed environment variables and query variables as a hash, the final argument.
Blog.post(:Login, :input => {'username' => 'admin', 'password' => 'camping'})
#=> #<Blog::Controllers::Login @user=... >
Blog.get(:Info, :env => {:HTTP_HOST => 'wagon'})
#=> #<Blog::Controllers::Info @env={'HTTP_HOST'=>'wagon'} ...>
[ show source ]
# File lib/camping.rb, line 686
686: def method_missing(m, c, *a)
687: X.M
688: k = X.const_get(c).new(StringIO.new,
689: H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s)
690: H.new(a.pop).each { |e,f| k.send("#{e}=",f) } if Hash === a[-1]
691: k.service *a
692: end

Parses a query string into an Camping::H object.
input = Camping.qs_parse("name=Philarp+Tremain&hair=sandy+blonde")
input.name
#=> "Philarp Tremaine"
Also parses out the Hash-like syntax used in PHP and Rails and builds nested hashes from it.
input = Camping.qs_parse("post[id]=1&post[user]=_why")
#=> {'post' => {'id' => '1', 'user' => '_why'}}
[ show source ]
# File lib/camping.rb, line 627
627: def qs_parse(qs, d = '&;')
628: m = proc {|_,o,n|o.u(n,&m)rescue([*o]<<n)}
629: (qs||'').
630: split(/[#{d}] */n).
631: inject(H[]) { |h,p| k, v=un(p).split('=',2)
632: h.u(k.split(/[\]\[]+/).reverse.
633: inject(v) { |x,i| H[i,x] },&m)
634: }
635: end

Fields a request through Camping. For traditional CGI applications, the method can be executed without arguments.
if __FILE__ == $0
Camping::Models::Base.establish_connection :adapter => 'sqlite3',
:database => 'blog3.db'
Camping::Models::Base.logger = Logger.new('camping.log')
puts Camping.run
end
The Camping controller returned from run has a to_s method in case you are running from CGI or want to output the full HTTP output. In the above example, puts will call to_s for you.
For FastCGI and Webrick-loaded applications, you will need to use a request loop, with run at the center, passing in the read r and write w streams. You will also need to mimick or pass in the ENV replacement as part of your wrapper.
See Camping::FastCGI and Camping::WEBrick for examples.
[ show source ]
# File lib/camping.rb, line 660
660: def run(r=$stdin,e=ENV)
661: X.M
662: k,a=X.D un("/#{e['PATH_INFO']}".gsub(/\/+/,'/'))
663: k.new(r,e,(m=e['REQUEST_METHOD']||"GET")).Y.service *a
664: rescue Exception=>x
665: X::ServerError.new(r,e,'get').service(k,m,x)
666: end

Unescapes a URL-encoded string.
Camping.un("I%27d+go+to+the+museum+straightway%21")
#=> "I'd go to the museum straightway!"
[ show source ]
# File lib/camping.rb, line 613
613: def un(s); s.tr('+', ' ').gsub(/%([\da-f]{2})/in){[$1].pack('H*')} end