Module | Camping |
In: |
lib/camping/fastcgi.rb
lib/camping/reloader.rb lib/camping/db.rb lib/camping/session.rb lib/camping-unabridged.rb |
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.
Apps | = | [] |
Stores an Array of all Camping
applications modules. Modules are added automatically by +Camping.goes+.
Camping.goes :Blog Camping.goes :Tepee Camping::Apps # => [Blog, Tepee] |
|
C | = | self | ||
S | = | IO.read(__FILE__).sub(/^ S = I.+$/,'') | ||
P | = | "Cam\ping Problem!" | ||
H | = | HashWithIndifferentAccess | ||
X | = | Controllers |
URL escapes a string.
Camping.escape("I'd go to the museum straightway!") #=> "I%27d+go+to+the+museum+straightway%21"
# File lib/camping-unabridged.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
# File lib/camping-unabridged.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.
# File lib/camping-unabridged.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'} ...>
# File lib/camping-unabridged.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'}}
# File lib/camping-unabridged.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.
# File lib/camping-unabridged.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