Class: Camping::Server

Inherits:
Rackup::Server
  • Object
show all
Defined in:
lib/camping/server.rb

Defined Under Namespace

Classes: Options, XSendfile

Instance Method Summary collapse

Constructor Details

#initializeServer

Returns a new instance of Server.



87
88
89
90
91
92
93
94
# File 'lib/camping/server.rb', line 87

def initialize(*)
  super
  @reloader = Camping::Reloader.new(options[:script]) do |app|
    if !app.options.has_key?(:dynamic_templates)
    app.options[:dynamic_templates] = true
   end
  end
end

Instance Method Details

#appObject

add the public directory as a Rack app serving files first, then the current value of self, which is our camping apps, as an app.



161
162
163
# File 'lib/camping/server.rb', line 161

def app
  Rack::Cascade.new([Rack::Files.new(public_dir), self], [405, 404, 403])
end

#call(env) ⇒ Object

call(env) res

How routing works

The first app added using Camping.goes is set at the root, we walk through the defined routes of the first app to see if there is a match. With no match we then walk through every other defined app. When we reach a matching route we call that app and Camping’s router handles the rest.

Mounting apps at different directories is now explicit by setting the url_prefix option:

camping.goes :Nuts          # Mounts Nuts at /
module Auth
   set :url_prefix, "auth/"
end
camping.goes :Auth          # Mounts Auth at /auth/
camping.goes :Blog          # Mounts Blog at /

Note that routes that you set explicitly with R are not prefixed. This us explicit control over routes:

module Auth::Controllers
   class Whatever < R '/thing/' # Mounts at /thing/
      def get
         render :some_view
      end
   end
end


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/camping/server.rb', line 211

def call(env)
  if ENV['environment'] == 'development'
    @reloader.reload
  end

  # our switch statement iterates through possible app outcomes, no apps
  # loaded, one app loaded, or multiple apps loaded.
  case @reloader.apps.length
  when 0
    [200, {'content-type' => 'text/html'}, ["I'm sorry but no apps were found."]]
  when 1
    @reloader.apps.values.first.call(env) # When we have one
  else
    # 2 and up get special treatment
    @reloader.apps.each do |name, app|
      app.routes.each do |r|
        if (path_matches?(env['PATH_INFO'], r))
          return app.call(env)
          next
        end
      end
    end

    # Just return the first app if we didn't find a match.
    @reloader.apps.values.first.call(env)
  end
end

#default_optionsObject



100
101
102
103
104
# File 'lib/camping/server.rb', line 100

def default_options
  super.merge({
    :Port => 3301
  })
end

#middlewareObject



106
107
108
109
110
# File 'lib/camping/server.rb', line 106

def middleware
  h = super
  h["development"] << [XSendfile]
  h
end

#opt_parserObject



96
97
98
# File 'lib/camping/server.rb', line 96

def opt_parser
  Options.new
end

#path_matches?(path, *reg) ⇒ Boolean

path_matches? accepts a regular expression string in our case our apps and controllers

Returns:

  • (Boolean)


168
169
170
171
172
173
174
# File 'lib/camping/server.rb', line 168

def path_matches?(path, *reg)
  p = T.(path)
  reg.each do |r|
    return true if Regexp.new(T.(r)).match?(p) && p == T.(r)
  end
  false
end

#public_dirObject

defines the public directory to be /public



155
156
157
# File 'lib/camping/server.rb', line 155

def public_dir
  File.expand_path('../public', @reloader.file)
end

#startObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/camping/server.rb', line 112

def start

  commands = []
  ARGV.each do |cmd|
    commands << cmd
  end

  # Parse commands
  case commands[0]
  when "new"
    Camping::Commands.new_cmd(commands[1])
    exit
  end

  if options[:version] == true
    puts "Camping v#{Camping::VERSION}"
    exit
  end

  @reloader.reload!
  r = @reloader

  if options[:routes] == true
    eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
    ARGV.clear
    Camping::Commands.routes
    exit
  end

  if options[:server] == "console"
    puts "** Starting console"
    eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
    ARGV.clear
    IRB.start
    exit
  else
    name = server.name[/\w+$/]
    puts "** Starting #{name} on #{options[:Host]}:#{options[:Port]}"
    super
  end
end