ruby-freedom 0.1.0

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: 4f0b7c517dc392b864435c8829ec2b7b4e7095accd2aad447e60b4d06e20c0d2
4
+ data.tar.gz: 0dabf4a60ecbe9f6480e3e5503a44d1e2aaf9c7afea89029730634fe63146e1c
5
+ SHA512:
6
+ metadata.gz: d49d2e3afc33373c1c646a75c2f46b6b3c0fe649119c4206179c8ea17f00ce9bfffa5542d9c0346b2ad6525831b5f48e1dcb8807505130253c33507e16119949
7
+ data.tar.gz: 8ac7fa6cf6ce590296b43bd3a3512e06692232e6edb4a37444d463a6560243cac7eff09e83887f3e9d0ce020c96721bb8f838437013f718267140690df2a4122
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.6
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ootoro838861@outlook.jp. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in freedom.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "minitest", "~> 5.0"
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 unagiootoro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # Freedom
2
+
3
+ Freedom is a very simple ruby web application framework.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'freedom'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install freedom
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Development
26
+
27
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+
29
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+
31
+ ## Contributing
32
+
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/freedom. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/freedom/blob/master/CODE_OF_CONDUCT.md).
34
+
35
+
36
+ ## License
37
+
38
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
39
+
40
+ ## Code of Conduct
41
+
42
+ Everyone interacting in the Freedom project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/freedom/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "freedom"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ require_relative "lib/freedom/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "ruby-freedom"
5
+ spec.version = Freedom::VERSION
6
+ spec.authors = ["unagiootoro"]
7
+ spec.email = ["ootoro838861@outlook.jp"]
8
+
9
+ spec.summary = %q{Tiny web application framework.}
10
+ spec.description = %q{Freedom is a very simple ruby web application framework.}
11
+ spec.homepage = "https://github.com/unagiootoro/freedom.git"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
14
+
15
+ spec.add_dependency "rack"
16
+ spec.add_dependency "rack-protection"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_development_dependency "bundler", ">= 1.16", "<3.0"
28
+ spec.add_development_dependency "rake", ">= 12.3.3"
29
+ spec.add_development_dependency "minitest", "~> 5.0"
30
+ spec.add_development_dependency "yard"
31
+ end
@@ -0,0 +1,14 @@
1
+ require "rack"
2
+ require "rack-protection"
3
+ require "uri"
4
+ require "erb"
5
+ require "logger"
6
+
7
+ module Freedom; end
8
+
9
+ require_relative "freedom/version"
10
+ require_relative "freedom/core/application"
11
+ require_relative "freedom/core/controller"
12
+ require_relative "freedom/core/request"
13
+ require_relative "freedom/core/response"
14
+ require_relative "freedom/core/config"
@@ -0,0 +1,154 @@
1
+ module Freedom
2
+ class BaseApplication
3
+ def initialize
4
+ @routing_table = {}
5
+ routes
6
+ end
7
+
8
+ def call(env)
9
+ req = Freedom::Request.new(env)
10
+ resolve(req)
11
+ end
12
+
13
+ def routes
14
+ raise NotImplementedError.new
15
+ end
16
+
17
+ def get(table_data)
18
+ route("GET", table_data)
19
+ end
20
+
21
+ def post(table_data)
22
+ route("POST", table_data)
23
+ end
24
+
25
+ def put(table_data)
26
+ route("PUT", table_data)
27
+ end
28
+
29
+ def delete(table_data)
30
+ route("DELETE", table_data)
31
+ end
32
+
33
+ def head(table_data)
34
+ route("HEAD", table_data)
35
+ end
36
+
37
+ def options(table_data)
38
+ route("OPTIONS", table_data)
39
+ end
40
+
41
+ def patch(table_data)
42
+ route("PATCH", table_data)
43
+ end
44
+
45
+ def link(table_data)
46
+ route("LINK", table_data)
47
+ end
48
+
49
+ def unlink(table_data)
50
+ route("UNLINK", table_data)
51
+ end
52
+
53
+ private
54
+
55
+ def route(http_method, table_data)
56
+ table_data.each do |path, controller_action|
57
+ controller_name, action_name = controller_action.split("#")
58
+ controller_class = Kernel.const_get(controller_name)
59
+ @routing_table[[http_method, path]] = [controller_class.new, action_name.to_sym]
60
+ end
61
+ end
62
+
63
+ def resolve(request)
64
+ result, match_data = match_routing_table(request)
65
+ if result
66
+ controller, action = *result
67
+ begin
68
+ res = controller.call(action, request)
69
+ res.finish
70
+ rescue => e
71
+ STDERR.puts e.full_message
72
+ status_500
73
+ end
74
+ else
75
+ if File.exist?("#{Dir.pwd}/#{Config.public_dir}#{request.path_info}")
76
+ files = Rack::Files.new(Config.public_dir)
77
+ files.get(request.env)
78
+ else
79
+ status_404
80
+ end
81
+ end
82
+ end
83
+
84
+ def match_routing_table(request)
85
+ @routing_table.each do |key, val|
86
+ http_method, path = *key
87
+ next unless http_method == request.request_method
88
+ if path.is_a?(String)
89
+ return [val, nil] if path == request.path_info
90
+ elsif path.is_a?(Regexp)
91
+ match_data = request.path_info.match(path)
92
+ return [val, match_data] if match_data
93
+ end
94
+ end
95
+ [nil, nil]
96
+ end
97
+
98
+ def status_404
99
+ res = Response.new(["404 Not Found"], 404)
100
+ res.finish
101
+ end
102
+
103
+ def status_500
104
+ res = Response.new(["500 Internal Server Error"], 500)
105
+ res.finish
106
+ end
107
+ end
108
+
109
+ class Application < BaseApplication
110
+ def self.start(options = {})
111
+ self.new(options).start
112
+ end
113
+
114
+ def initialize(options = {})
115
+ super()
116
+ @options = options.clone
117
+ @middlewares = default_middlewares
118
+ @rack_server = nil
119
+ end
120
+
121
+ def built?
122
+ !!@rack_server
123
+ end
124
+
125
+ def build
126
+ builder = Rack::Builder.new(self)
127
+ @middlewares.each do |middleware_array|
128
+ builder.use(*middleware_array)
129
+ end
130
+ rack_options = @options
131
+ rack_options[:app] = builder.to_app
132
+ rack_options[:Port] = 5700 unless rack_options[:Port]
133
+ @rack_server = Rack::Server.new(rack_options)
134
+ end
135
+
136
+ def start
137
+ build unless built?
138
+ @rack_server.start
139
+ end
140
+
141
+ def add_middleware(middleware_class, *middleware_args)
142
+ @middlewares << [middleware_class, *middleware_args]
143
+ end
144
+
145
+ private
146
+
147
+ def default_middlewares
148
+ [
149
+ [Rack::CommonLogger, ::Logger.new(Config.log_file_name)],
150
+ [Rack::Protection::PathTraversal],
151
+ ]
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,21 @@
1
+ module Freedom
2
+ module Config
3
+ class << self
4
+ attr_accessor :public_dir
5
+ attr_accessor :views_dir
6
+ attr_accessor :controller_dir
7
+
8
+ attr_accessor :encoding
9
+
10
+ attr_accessor :log_file_name
11
+ end
12
+ end
13
+
14
+ Config.public_dir = "public"
15
+ Config.views_dir = "views"
16
+ Config.controller_dir = "controller"
17
+
18
+ Config.encoding = "UTF-8"
19
+
20
+ Config.log_file_name = "logfile.txt"
21
+ end
@@ -0,0 +1,80 @@
1
+ module Freedom
2
+ class Controller
3
+ def initialize
4
+ @request = nil
5
+ @response = nil
6
+ end
7
+
8
+ def call(action, req)
9
+ @request = req
10
+ @response = Response.new(nil, 200)
11
+ catch(:halt) do
12
+ body = send(action)
13
+ return_plain
14
+ end
15
+ @response
16
+ end
17
+
18
+ def request
19
+ @request
20
+ end
21
+
22
+ def response
23
+ @response
24
+ end
25
+
26
+ def params
27
+ @request.params
28
+ end
29
+
30
+ def return_plain(body)
31
+ @response.content_type = "text/plain;charset=#{Config.encoding}"
32
+ halt(body: body)
33
+ end
34
+
35
+ def return_html(body)
36
+ @response.content_type = "text/html;charset=#{Config.encoding}"
37
+ halt(body: body)
38
+ end
39
+
40
+ def return_json(body)
41
+ @response.content_type = "application/json"
42
+ halt(body: body)
43
+ end
44
+
45
+ def html(name)
46
+ html = File.read("#{Config.views_dir}/#{name}.html")
47
+ return_html(html)
48
+ end
49
+
50
+ def erb(name)
51
+ html = ERB.new(File.read("#{Config.views_dir}/#{name}.erb", encoding: Config.encoding)).result(binding)
52
+ return_html(html)
53
+ end
54
+
55
+ def get_cookie(key)
56
+ @request.cookies[key]
57
+ end
58
+
59
+ def set_cookie(key, cookie)
60
+ hash = cookie.is_a?(String) ? { value: cookie} : cookie
61
+ @response.set_cookie(key, hash)
62
+ end
63
+
64
+ def url(path, scheme = nil)
65
+ scheme ||= @request.scheme
66
+ "#{scheme}://#{@request.domain + path}"
67
+ end
68
+
69
+ def redirect(uri)
70
+ @response.location = uri
71
+ halt status: 303
72
+ end
73
+
74
+ def halt(body: nil, status: 200)
75
+ @response.status = status if status
76
+ @response.body = [body] if body
77
+ throw :halt
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,27 @@
1
+ module Freedom
2
+ class Request < Rack::Request
3
+ def initialize(env)
4
+ super(env)
5
+ @post_data = nil
6
+ @domain = nil
7
+ @scheme = nil
8
+ end
9
+
10
+ def post_data
11
+ return @post_data if @post_data
12
+ @post_data = body.read
13
+ end
14
+
15
+ def domain
16
+ return @domain if @domain
17
+ match_data = @env["REQUEST_URI"].match(/.+\:\/\/(.+?)\//)
18
+ @domain = match_data[1]
19
+ end
20
+
21
+ def scheme
22
+ return @scheme if @scheme
23
+ match_data = @env["REQUEST_URI"].match(/(.+)\:\/\//)
24
+ @scheme = match_data[1]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ module Freedom
2
+ class Response < Rack::Response
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Freedom
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-freedom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - unagiootoro
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-12-02 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: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack-protection
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '3.0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '1.16'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 12.3.3
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 12.3.3
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: yard
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: Freedom is a very simple ruby web application framework.
104
+ email:
105
+ - ootoro838861@outlook.jp
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - CODE_OF_CONDUCT.md
113
+ - Gemfile
114
+ - LICENSE.txt
115
+ - README.md
116
+ - Rakefile
117
+ - bin/console
118
+ - bin/setup
119
+ - freedom.gemspec
120
+ - lib/freedom.rb
121
+ - lib/freedom/core/application.rb
122
+ - lib/freedom/core/config.rb
123
+ - lib/freedom/core/controller.rb
124
+ - lib/freedom/core/request.rb
125
+ - lib/freedom/core/response.rb
126
+ - lib/freedom/version.rb
127
+ homepage: https://github.com/unagiootoro/freedom.git
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 2.4.0
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 3.1.4
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: Tiny web application framework.
150
+ test_files: []