wouter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/wouter.rb +156 -0
  3. metadata +165 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a103da6e9f11d0e96881ccaf75062ef5a6a5322e78e3010300465645d5a9bd62
4
+ data.tar.gz: e10e000a61b9a304156429f1c22244ab6af4b456bb17d1960a901eb9c1579a4d
5
+ SHA512:
6
+ metadata.gz: 3ae45cbb20ba4659e9ef46d44fdb9deafef6fb252ab17acdad3eef68a4a3f446113c2641e672e165d3b9e97cf32d8399932141f4db223a0bbcbfb8f0bcd9c6db
7
+ data.tar.gz: 95239729b7a893187eb60d126bbd75aab7901718c21e28b47053c491bea3b0eb613539618f2245b69b55cdb4a18a0f3155781179216d173c19f6cd47d2c680f4
data/lib/wouter.rb ADDED
@@ -0,0 +1,156 @@
1
+ require "bundler"
2
+ Bundler.setup(:default)
3
+ require "rack"
4
+
5
+ class Wouter
6
+
7
+ # Incoming HTTP Request Wrapper
8
+ class Request
9
+ attr_reader :params
10
+
11
+ def initialize(params:)
12
+ @params = params
13
+ end
14
+ end
15
+
16
+ # Outgoing HTTP Response Wrapper
17
+ class Response
18
+ attr_accessor :headers
19
+
20
+ def initialize
21
+ @headers = {'Content-Type' => 'text/html'}
22
+ @body = ""
23
+ @status = 200
24
+ end
25
+
26
+ def body(b)
27
+ @body = b
28
+ self
29
+ end
30
+
31
+ def status(s)
32
+ @status = s
33
+ self
34
+ end
35
+
36
+ def build_response
37
+ [@status, @headers, [@body]]
38
+ end
39
+ end
40
+
41
+ # HTTP Endpoint Helper class
42
+ class Endpoint
43
+ attr_accessor :request, :response
44
+ attr_reader :params
45
+
46
+ def initialize
47
+ @request = request
48
+ @response = response
49
+ end
50
+
51
+ def call(req, res)
52
+ @request = req
53
+ @params = req.params
54
+ @response = res
55
+ r = respond
56
+ @response.body r
57
+ end
58
+
59
+ def json(body)
60
+ @response.headers['Content-Type'] = 'application/json'
61
+ body
62
+ end
63
+
64
+ def status(code)
65
+ @response.status code
66
+ ""
67
+ end
68
+ end
69
+
70
+ ## Route Definitions
71
+
72
+ @@routes = []
73
+
74
+ ## DSL
75
+
76
+ class <<self
77
+ %i[get post put delete].each do |m|
78
+ define_method(m) do |path, route_class|
79
+ @@routes.push({
80
+ method: m.to_s.upcase.to_sym,
81
+ path: path,
82
+ route_class: route_class
83
+ })
84
+ end
85
+ end
86
+ end
87
+
88
+ ## Rack API
89
+
90
+ def self.call(env)
91
+ path = env["PATH_INFO"]
92
+ method = env["REQUEST_METHOD"].to_sym
93
+
94
+ route_params = {}
95
+
96
+ route = @@routes.find do |route|
97
+ if route[:method] == method
98
+ if route[:path].include?(":")
99
+ split_path = route[:path].split("/")
100
+ # Find all the named parameters in the route, drop the ":" so we have the names: ":id" => "id"
101
+ route_param_names = split_path.find_all { |s| s.size > 1 ? s[0] == ":" : false }.map { |s| s[1..-1] }
102
+ # Turn the route into a regex: "/hello/:name" => "\/hello\/(\w*)"
103
+ path_regex_string = split_path.map { |s| s[0] == ":" ? "(\\w*)" : s }.join("\/")
104
+ r = Regexp.new(path_regex_string)
105
+ if r.match?(path)
106
+ match_data = r.match(path)
107
+ # Match the match data with the named params, ex { "id" => 123 }
108
+ route_param_names.each_with_index do |n, i|
109
+ route_params[n] = match_data[i+1]
110
+ end
111
+ true
112
+ else
113
+ false
114
+ end
115
+ else
116
+ route[:path] == path
117
+ end
118
+ end
119
+ end
120
+
121
+ if route
122
+ params = generate_params(env["rack.input"].gets).merge(route_params)
123
+
124
+ request = Request.new(params: params)
125
+ response = Response.new
126
+
127
+ route_response = route[:route_class].new.call(request, response)
128
+ response route_response
129
+ else
130
+ response not_found
131
+ end
132
+ end
133
+
134
+ ### Helpers
135
+
136
+ def self.not_found
137
+ resp = Response.new
138
+ resp.status 404
139
+ resp.body "Not Found"
140
+ end
141
+
142
+ # Query string comes in as "key=value&key=value" and we turn it into { "key" => "value", "key" => "value" }
143
+ def self.generate_params(params)
144
+ return {} if params.nil? || params.empty?
145
+ params_hash = {}
146
+ params.split("&").each do |param_pair|
147
+ key, value = param_pair.split("=")
148
+ params_hash[key] = value
149
+ end
150
+ params_hash
151
+ end
152
+
153
+ def self.response(route_response)
154
+ route_response.build_response
155
+ end
156
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wouter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Robert Peterson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.6
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.6
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '12.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 12.3.1
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '12.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 12.3.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: rack-test
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.1'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.1.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.1'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.1.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: minitest
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '5.11'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 5.11.3
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.11'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 5.11.3
93
+ - !ruby/object:Gem::Dependency
94
+ name: minitest-rg
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '5.2'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 5.2.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '5.2'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 5.2.0
113
+ - !ruby/object:Gem::Dependency
114
+ name: m
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '1.5'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 1.5.1
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '1.5'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 1.5.1
133
+ description: Wouter is a modular web router built on Rack. I like explicitness. I
134
+ like modularity. Wouter aims to make both of those aspects simple.
135
+ email: robertpeterson@gmail.com
136
+ executables: []
137
+ extensions: []
138
+ extra_rdoc_files: []
139
+ files:
140
+ - lib/wouter.rb
141
+ homepage: https://github.com/rawburt/wouter
142
+ licenses:
143
+ - MIT
144
+ metadata: {}
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 2.7.3
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: Rack web router.
165
+ test_files: []