Class: Camping::Server

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

Defined Under Namespace

Classes: Options, XSendfile

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeServer

Returns a new instance of Server.



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

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

Class Method Details

.logging_middlewareObject



113
114
115
116
117
# File 'lib/camping/server.rb', line 113

def logging_middleware
  lambda { |server|
    /CGI/.match?(server.server.name) || server.options[:quiet] ?  nil : [Camping::Firewatch, $stderr]
  }
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.



179
180
181
# File 'lib/camping/server.rb', line 179

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


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/camping/server.rb', line 229

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



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

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

#loaderObject



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

def loader
  @reloader || nil
end

#middlewareObject



120
121
122
123
124
125
# File 'lib/camping/server.rb', line 120

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

#opt_parserObject



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

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)


186
187
188
189
190
191
192
# File 'lib/camping/server.rb', line 186

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



173
174
175
# File 'lib/camping/server.rb', line 173

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

#start(file = nil) ⇒ Object

Starts the Camping Server. Camping server inherits from Rack::Server so referencing their documentation would be a good idea. @file: String, file location for a camp.rb file.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/camping/server.rb', line 130

def start(file = nil)
  commands = ARGV

  # 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

  Dir['kindling/*.rb'].each do |kindling|
    require_relative File.expand_path(kindling)
  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