gopher2000 0.2.2 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 599d0bfe771be1795d77d08bd7fa8ef1df0b5c8ef89a6270d344aa9ad206e5ab
4
+ data.tar.gz: 64ee23ab4b4f63351c9572e19a995c5ca3da96919a79703e47a2830b9ddf6fba
5
+ SHA512:
6
+ metadata.gz: 7c16b9f80341276ad4f93aacbbf505d01b3aea5264da1e3119d43a10ea0037984b4d423ca51ff9f174a9af805daf8e079a71686296b9baee12607c0767706c59
7
+ data.tar.gz: 20adee6253ced84ab8d4a8c4c7413874b6f034a0b3ae12a86418336fa04acf16ca81ffc19fef41c6c4bdb28c348c7960a1214a4d9563274a80075a81d72fffae
@@ -0,0 +1 @@
1
+ 2.6.3
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.1
5
+ - 2.3.3
6
+ - 2.4.2
7
+ # uncomment this line if your project needs to run something other than `rake`:
8
+ # script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -1,27 +1,12 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in gopher.gemspec
1
+ source 'https://rubygems.org'
4
2
  gemspec
5
3
 
6
4
  gem "rake"
7
- gem "logging"
8
5
 
9
6
  # Add dependencies to develop your gem here.
10
7
  # Include everything needed to run rake, tests, features, etc.
11
8
  group :development do
12
- gem 'simplecov', :require => false, :group => :test
13
-
14
- gem "shoulda", ">= 0"
15
- gem "rspec"
16
-
17
- gem "bundler", "~> 1.0.0"
18
- gem "watchr"
19
9
 
20
10
  # There's a god example script stashed away in the repo
21
11
  gem "god"
22
-
23
- #
24
- # gems used in examples and for development.
25
- #
26
- gem "weather-underground"
27
12
  end
@@ -16,6 +16,8 @@ Gopher2000 - A Gopher server for the next millenium
16
16
  Gopher2000 is a ruby-based Gopher server. It is built for speedy, enjoyable development of
17
17
  all sorts of gopher sites.
18
18
 
19
+ [![Build Status](https://travis-ci.org/muffinista/gopher2000.svg?branch=master)](https://travis-ci.org/muffinista/gopher2000)
20
+
19
21
  Features
20
22
  --------
21
23
  * Simple, Sintra-inspired routing DSL.
@@ -57,7 +59,7 @@ menu :index do
57
59
  br(2)
58
60
 
59
61
  # link somewhere
60
- link 'current time', '/time'
62
+ text_link 'current time', '/time'
61
63
  br
62
64
  end
63
65
 
@@ -31,7 +31,7 @@ params = {
31
31
 
32
32
  opts.on('-d', '--debug', "run in debug mode") { params[:debug] = true }
33
33
  opts.on('-p port', 'set the port (default is 70)') { |val| params[:port] = Integer(val) }
34
- opts.on('-o addr', 'set the host (default is 0.0.0.0)') { |val| params[host] = val }
34
+ opts.on('-o addr', 'set the host (default is 0.0.0.0)') { |val| params[:host] = val }
35
35
  opts.on('-e env', 'set the environment (default is development)') { |val| params[:env] = val.to_sym }
36
36
 
37
37
  opts.on_tail("-h", "--help", "Show this message") do
File without changes
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #
5
+ # Simple gopher example
6
+ #
7
+
8
+ require 'gopher2000'
9
+
10
+ set :host, '0.0.0.0'
11
+ set :port, 7070
12
+
13
+ route '/figlet' do
14
+ render :figlet
15
+ end
16
+
17
+ #
18
+ # special text output rendering
19
+ #
20
+ text :figlet do
21
+ @text = "Hello!"
22
+
23
+ # nicely wrapped text
24
+ figlet @text
25
+
26
+ # spacing
27
+ br(2)
28
+ end
File without changes
@@ -57,11 +57,11 @@ menu :index do
57
57
  br(2)
58
58
 
59
59
  # link somewhere
60
- link 'current time', '/time'
60
+ text_link 'current time', '/time'
61
61
  br
62
62
 
63
63
  # another link
64
- link 'about', '/about'
64
+ text_link 'about', '/about'
65
65
  br
66
66
 
67
67
  # ask for some input
File without changes
File without changes
@@ -12,7 +12,6 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{Gopher2000 - A Gopher server for the next millenium}
13
13
  s.description = %q{Gopher2000 is a ruby-based Gopher server. It is built for speedy, enjoyable development of all sorts of gopher sites.}
14
14
 
15
- s.rubyforge_project = "gopher2000"
16
15
  s.licenses = ["WTFPL"]
17
16
 
18
17
  s.files = `git ls-files`.split("\n")
@@ -26,10 +25,11 @@ Gem::Specification.new do |s|
26
25
  s.add_development_dependency "yard"
27
26
  s.add_development_dependency "shoulda"
28
27
  s.add_development_dependency "rdoc"
29
- s.add_development_dependency "simplecov"
28
+ s.add_development_dependency "simplecov", "~> 0.16.1"
30
29
  s.add_development_dependency "watchr"
31
- s.add_development_dependency "eventmachine"
32
30
 
33
- s.add_runtime_dependency "eventmachine"
34
- s.add_runtime_dependency "logger"
31
+ s.add_runtime_dependency "artii", ">= 2.0.1"
32
+ s.add_runtime_dependency "eventmachine", "~> 1.2.5"
33
+ s.add_runtime_dependency "logging"
34
+ s.add_runtime_dependency "mimemagic"
35
35
  end
@@ -1,6 +1,6 @@
1
1
  require 'eventmachine'
2
2
  require 'stringio'
3
-
3
+ require 'logging'
4
4
 
5
5
  #
6
6
  # Define everything needed to run a gopher server
@@ -54,6 +54,13 @@ module Gopher
54
54
  config[:port] ||= 70
55
55
  end
56
56
 
57
+ #
58
+ # return the application environment
59
+ #
60
+ def env
61
+ config[:env] ||= 'development'
62
+ end
63
+
57
64
  #
58
65
  # are we in debugging mode?
59
66
  #
@@ -91,9 +98,9 @@ module Gopher
91
98
  #
92
99
  # mount a directory for browsing via gopher
93
100
  #
94
- # @param [Hash] A hash specifying the path your route will answer to, and the filesystem path to use '/route' => '/home/path/etc'
95
- #
96
- # @param [Hash] a hash of options for the mount. Primarily this is a filter, which will restrict the list files outputted. example: :filter => '*.jpg'
101
+ # @param [Hash] path A hash specifying the path your route will answer to, and the filesystem path to use '/route' => '/home/path/etc'
102
+ # @param [Hash] opts a hash of options for the mount. Primarily this is a filter, which will restrict the list files outputted. example: :filter => '*.jpg'
103
+ # @param [Class] klass The class that should be used to handle this mount. You could write and use a custom handler if desired
97
104
  #
98
105
  # @example mount the directory '/home/user/foo' at the gopher path '/files', and only show JPG files:
99
106
  # mount '/files' => '/home/user/foo', :filter => '*.jpg'
@@ -118,8 +125,7 @@ module Gopher
118
125
 
119
126
  #
120
127
  # define a route.
121
- # @param [String] the path your route will answer to. This is
122
- # basically a URI path
128
+ # @param [String] path the path your route will answer to. This is basically a URI path
123
129
  # @yield a block that handles your route
124
130
  #
125
131
  # @example respond with a simple string
@@ -133,7 +139,7 @@ module Gopher
133
139
  # end
134
140
  #
135
141
  def route(path, &block)
136
- selector = sanitize_selector(path)
142
+ selector = Gopher::Application.sanitize_selector(path)
137
143
  sig = compile!(selector, &block)
138
144
 
139
145
  debug_log("Add route for #{selector}")
@@ -145,6 +151,7 @@ module Gopher
145
151
 
146
152
  #
147
153
  # specify a default route to handle requests if no other route exists
154
+ # @yield a block to handle the default route
148
155
  #
149
156
  # @example render a template
150
157
  # default_route do
@@ -158,16 +165,15 @@ module Gopher
158
165
  #
159
166
  # lookup an incoming path
160
167
  #
161
- # @param [String] the selector path of the incoming request
168
+ # @param [String] selector the selector path of the incoming request
162
169
  #
163
170
  def lookup(selector)
164
171
  unless routes.nil?
165
- routes.each do |pattern, keys, block|
166
-
172
+ routes.each do |pattern, keys, block|
167
173
  if match = pattern.match(selector)
168
174
  match = match.to_a
169
175
  url = match.shift
170
-
176
+
171
177
  params = to_params_hash(keys, match)
172
178
 
173
179
  #
@@ -190,7 +196,7 @@ module Gopher
190
196
 
191
197
  #
192
198
  # find and run the first route which matches the incoming request
193
- # @param [Request] Gopher::Request object
199
+ # @param [Request] req Gopher::Request object
194
200
  #
195
201
  def dispatch(req)
196
202
  debug_log(req)
@@ -201,6 +207,9 @@ module Gopher
201
207
  if ! @request.valid?
202
208
  response.body = handle_invalid_request
203
209
  response.code = :error
210
+ elsif @request.url?
211
+ response.body = handle_url(@request)
212
+ response.code = :success
204
213
  else
205
214
  begin
206
215
  debug_log("do lookup for #{@request.selector}")
@@ -233,11 +242,11 @@ module Gopher
233
242
  # define a template which will be used to render a gopher-style
234
243
  # menu.
235
244
  #
236
- # @param [String/Symbol] -- the name of the template. This is what
237
- # identifies the template when making a call to render
245
+ # @param [String/Symbol] name the name of the template. This is what
246
+ # identifies the template when making a call to render
238
247
  # @yield a block which will output the menu. This block is
239
- # executed within an instance of Gopher::Rendering::Menu and will
240
- # have access to all of its methods.
248
+ # executed within an instance of Gopher::Rendering::Menu and will
249
+ # have access to all of its methods.
241
250
  #
242
251
  # @example a simple menu:
243
252
  # menu :index do
@@ -273,7 +282,7 @@ module Gopher
273
282
  # access to the methods defined in Gopher::Rendering::Text for
274
283
  # wrapping strings, adding simple headers, etc.
275
284
  #
276
- # @param [String/Symbol] -- the name of the template. This is what identifies the template when making a call to render
285
+ # @param [String/Symbol] name the name of the template. This is what identifies the template when making a call to render
277
286
  #
278
287
  # @yield a block which will output the menu. This block is executed within an instance of Gopher::Rendering::Text and will have access to all of its methods.
279
288
  # @example simple example
@@ -295,7 +304,7 @@ module Gopher
295
304
 
296
305
  #
297
306
  # find a template
298
- # @param [String/Symbol] name of the template
307
+ # @param [String/Symbol] t name of the template
299
308
  # @return template block and the class context it should use
300
309
  #
301
310
  def find_template(t)
@@ -311,8 +320,8 @@ module Gopher
311
320
 
312
321
  #
313
322
  # Find the desired template and call it within the proper context
314
- # @param [String/Symbol] name of the template to render
315
- # @param [Array] optional arguments to be passed to template
323
+ # @param [String/Symbol] template name of the template to render
324
+ # @param [Array] arguments optional arguments to be passed to template
316
325
  # @return result of rendering
317
326
  #
318
327
  def render(template, *arguments)
@@ -347,6 +356,15 @@ module Gopher
347
356
  menus.include?(:error) ? :error : :'internal/error'
348
357
  end
349
358
 
359
+
360
+ #
361
+ # get the id of the template that will be used when rendering an html page
362
+ # @return name of error template
363
+ #
364
+ def url_template
365
+ menus.include?(:html) ? :html : :'internal/url'
366
+ end
367
+
350
368
  #
351
369
  # get the id of the template that will be used when rendering an
352
370
  # invalid request
@@ -385,7 +403,7 @@ module Gopher
385
403
  # Gopher servers in production)
386
404
  #
387
405
  def non_blocking?
388
- config[:non_blocking] ||= ! debug_mode?
406
+ config.key?(:non_blocking) ? config[:non_blocking] : ! debug_mode?
389
407
  end
390
408
 
391
409
 
@@ -411,7 +429,7 @@ module Gopher
411
429
  # turn a path string with optional keys (/foo/:bar/:boo) into a
412
430
  # regexp which will be used when searching for a route
413
431
  #
414
- # @param [String] the path to compile
432
+ # @param [String] path the path to compile
415
433
  #
416
434
  def compile(path)
417
435
  keys = []
@@ -428,23 +446,25 @@ module Gopher
428
446
  [/^#{pattern}$/, keys]
429
447
  end
430
448
 
431
- #
432
- # Sanitizes a gopher selector
433
- #
434
- def sanitize_selector(raw)
435
- raw.to_s.dup.
436
- strip. # Strip whitespace
437
- sub(/\/$/, ''). # Strip last rslash
438
- sub(/^\/*/, '/'). # Strip extra lslashes
439
- gsub(/\.+/, '.') # Don't want consecutive dots!
440
- end
441
449
 
442
450
  class << self
443
- #
451
+
452
+ #
453
+ # Sanitizes a gopher selector
454
+ #
455
+ def sanitize_selector(raw)
456
+ "/#{raw}".dup.
457
+ strip. # Strip whitespace
458
+ sub(/\/$/, ''). # Strip last rslash
459
+ sub(/^\/*/, '/'). # Strip extra lslashes
460
+ gsub(/\.+/, '.') # Don't want consecutive dots!
461
+ end
462
+
463
+ #
444
464
  # generate a method which we will use to run routes. this is
445
465
  # based on #generate_method as used by sinatra.
446
466
  # @see https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb
447
- # @param [String] name to use for the method
467
+ # @param [String] method_name name to use for the method
448
468
  # @yield block to use for the method
449
469
  def generate_method(method_name, &block)
450
470
  define_method(method_name, &block)
@@ -453,7 +473,7 @@ module Gopher
453
473
  method
454
474
  end
455
475
  end
456
-
476
+
457
477
  #
458
478
  # output a debugging message
459
479
  #
@@ -470,15 +490,37 @@ module Gopher
470
490
  #
471
491
  def register_defaults
472
492
  menu :'internal/not_found' do
473
- text "Sorry, #{@request.selector} was not found"
493
+ error "Sorry, #{@request.selector} was not found"
474
494
  end
475
495
 
476
496
  menu :'internal/error' do |details|
477
- text "Sorry, there was an error #{details}"
497
+ error "Sorry, there was an error #{details}"
478
498
  end
479
499
 
480
500
  menu :'internal/invalid_request' do
481
- text "invalid request"
501
+ error "invalid request"
502
+ end
503
+
504
+ menu :'internal/url' do
505
+ output = <<-EOHTML
506
+ <html>
507
+ <head>
508
+ <meta http-equiv="refresh" content="5;URL=#{@request.url}">
509
+ </head>
510
+ <body>
511
+ <p>
512
+ You are following a link from gopher to a website. If your browser supports it, you will be
513
+ automatically taken to the web site shortly. If you do not get
514
+ sent there, please click <a href="#{@request.url}">here</a>.
515
+ </p>
516
+ <p>
517
+ The URL linked is: <a href="#{@request.url}">#{@request.url}</a>.
518
+ </p>
519
+ <p>Have a nice day!</p>
520
+ </body>
521
+ </html>
522
+ EOHTML
523
+ output
482
524
  end
483
525
  end
484
526
 
@@ -486,6 +528,10 @@ module Gopher
486
528
  render not_found_template
487
529
  end
488
530
 
531
+ def handle_url(request)
532
+ render url_template, request
533
+ end
534
+
489
535
  def handle_error(e)
490
536
  render error_template, e
491
537
  end
@@ -22,16 +22,25 @@ module Gopher
22
22
  #
23
23
  # called by EventMachine when there's an incoming request
24
24
  #
25
- # @param [String] incoming selector
25
+ # @param [String] selector incoming selector
26
26
  # @return Response object
27
27
  #
28
- def receive_data(selector)
29
- call! Request.new(selector, remote_ip)
28
+ def receive_data data
29
+ (@buf ||= '') << data
30
+
31
+ while line = @buf.slice!(/(.*)\r?\n/)
32
+ receive_line(line)
33
+ end
30
34
  end
31
35
 
36
+ # Invoked with lines received over the network
37
+ def receive_line(line)
38
+ call! Request.new(line, remote_ip)
39
+ end
40
+
32
41
  #
33
42
  # generate a request object from an incoming selector, and dispatch it to the app
34
- # @param [String] incoming selector
43
+ # @param [Request] request Request object to handle
35
44
  # @return Response object
36
45
  #
37
46
  def call!(request)