supersimplehttp 0.1.1

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: 827ec9cfe19d8824123b8ec013363b545507bf0cb54be321e13bb584df2063bc
4
+ data.tar.gz: 61bfe0e319c6c2a3f3f217aed9f4c8e210730637bddd1e8f15bba4377c483524
5
+ SHA512:
6
+ metadata.gz: 197333ddc3e3dcfa12703532193f30a90b1b42831cb114cf28217bfa592fa938a70e8a3ea9a1daebdf330a4d609a84641320547732919034c34756a5c63c51ea
7
+ data.tar.gz: 26ad44dbecba16a998eb0006db71f94d580d3283e3a8221802702cb19e20c74edff92aca0a411c85f8881336d31cf6a7fde70a58542c8a495dc1841363096b01
@@ -0,0 +1,2 @@
1
+ # Autodetect text files
2
+ * text=auto
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .vscode
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.6
7
+ before_install: gem install bundler -v 1.17.2
@@ -0,0 +1,34 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.1.1] - 2020-09-06
6
+
7
+ ### Added
8
+
9
+ - Ability to server static files
10
+ - Pass in function to start
11
+ - Added index.html to example
12
+
13
+ ### Changed
14
+
15
+ - How responses are handled (to be able to serve files)
16
+ - Fixed Readme
17
+ - Updated example
18
+ - Formatted file correctly with ruby conventions
19
+
20
+ ## [0.1.0] - 2020-09-06
21
+
22
+ ### Added
23
+
24
+ - Created the gem bundle
25
+ - Created basic test
26
+ - Created simple server
27
+
28
+ ### Changed
29
+
30
+ - Updated example
31
+ - Updated README
32
+
33
+ [0.1.1]: https://github.com/filipwtf/supersimplehttp/releases/tag/v0.1.1s
34
+ [0.1.0]: https://github.com/filipwtf/supersimplehttp/releases/tag/v0.1.0
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/filipwtf/supersimplehttp" }
4
+
5
+ # Specify your gem's dependencies in supersimplehttp.gemspec
6
+ gemspec
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ supersimplehttp (0.1.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.14.2)
10
+ rake (10.5.0)
11
+
12
+ PLATFORMS
13
+ x64-mingw32
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 2.1.4)
17
+ minitest (~> 5.0)
18
+ rake (~> 10.0)
19
+ supersimplehttp!
20
+
21
+ BUNDLED WITH
22
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Filip
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Supersimplehttp
2
+
3
+ NOTE: This shouldn't be used in a real environment it's not secure
4
+ Supper Simple HTTP is a simple HTTP server created in ruby. At it's current stage it has no real world use there are way better frameworks. I simple made this project to learn Ruby.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'supersimplehttp'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install supersimplehttp
21
+
22
+ ## Usage
23
+
24
+ You can check out the example folder
25
+
26
+ Create a new ruby file:
27
+
28
+ ```rb
29
+ require 'supersimplehttp'
30
+
31
+ Supersimplehttp::Server.new('localhost', 5000)
32
+
33
+ ```
34
+
35
+ ## Development
36
+
37
+ 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.
38
+
39
+ 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).
40
+
41
+ ## Contributing
42
+
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/filipwtf/supersimplehttp.
44
+
45
+ ## License
46
+
47
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -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 "supersimplehttp"
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,6 @@
1
+ require 'supersimplehttp'
2
+
3
+ port = 5000
4
+ addr = 'localhost'
5
+
6
+ server = Supersimplehttp::Server.new(addr, port) { "[Supersimplehttp] running on #{addr}:#{port}" }
@@ -0,0 +1 @@
1
+ Hello
@@ -0,0 +1,148 @@
1
+ class ResponsePreparer
2
+ SERVER_ROOT = "example/tmp/web-server"
3
+
4
+ def prepare_response(request)
5
+ if request.fetch(:path) == "/"
6
+ respond_with(SERVER_ROOT + "index.html")
7
+ else
8
+ respond_with(SERVER_ROOT + request.fetch(:path))
9
+ end
10
+ end
11
+
12
+ def respond_with(path)
13
+ if File.exists?(path)
14
+ send_ok_response(File.binread(path))
15
+ else
16
+ send_file_not_found
17
+ end
18
+ end
19
+
20
+ def send_ok_response(data)
21
+ Response.new(code: 200, data: data)
22
+ end
23
+
24
+ def send_file_not_found
25
+ Response.new(code: 404)
26
+ end
27
+ end
28
+
29
+ class Response
30
+ def initialize(code:, body: "")
31
+ @code = code
32
+ @response =
33
+ "HTTP/1.1 #{code}\r\n" +
34
+ "Content-Length: #{body.size}\r\n" +
35
+ "\r\n" +
36
+ "#{body}\r\n"
37
+ end
38
+
39
+ def send(client)
40
+ client.write(@response)
41
+ end
42
+
43
+ def code
44
+ @code
45
+ end
46
+
47
+ end
48
+
49
+ class RequestParser
50
+ REPLACEMENTS = [['%2e', '.'], ['%2f', '/'], ['%5c', ''], ['%255c', ''], ['.',''], [':', ':.'], ['=/', '']]
51
+
52
+ def initialize(request)
53
+ @request = request
54
+ end
55
+
56
+ def parse
57
+ method, path, version = @request.lines[0].split
58
+ path = normalize_path(path)
59
+
60
+ if path.include? '?'
61
+ query = path.split('?')[1]
62
+ path = path.split('?')[0]
63
+ query = parse_query(query)
64
+ end
65
+
66
+ headers = parse_headers(@request)
67
+
68
+ body = nil
69
+ if headers.has_key?(:"content-type")
70
+ body = @request.split(/\n\r\n/)[1]
71
+ end
72
+
73
+ {
74
+ method: method,
75
+ version: version,
76
+ path: path,
77
+ query: query,
78
+ headers: headers,
79
+ body: body
80
+ }
81
+ end
82
+
83
+ =begin
84
+ splits http headers and creates key values pairs
85
+ =end
86
+ def parse_headers(headers_string)
87
+ headers = {}
88
+ headers_string.lines[1..-1].each do |line|
89
+ return headers if line == "\r\n"
90
+ header, value = line.split
91
+ header = normalize(header)
92
+ headers[header] = value
93
+ end
94
+ end
95
+
96
+ =begin
97
+ This method parses url params
98
+ https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams
99
+
100
+ parameter = name=Jonathan%20Smith&age=18
101
+ returns
102
+ {
103
+ :name=>"Jonathan Smith",
104
+ :age=>"18"
105
+ }
106
+
107
+ =end
108
+ def parse_query(query_string)
109
+ params = query_string.split('&')
110
+ queries = {}
111
+ params.each do |param|
112
+ param, value = param.split('=')
113
+ param, value = remove_encoded_space(param, value)
114
+ param = normalize(param)
115
+ queries[param] = value
116
+ end
117
+ return queries
118
+ end
119
+
120
+ def normalize(data)
121
+ data.gsub(":","").downcase.to_sym
122
+ end
123
+
124
+ # Remove url encoded space %20
125
+ def remove_encoded_space(*args)
126
+ index = 0;
127
+ args.each do |arg|
128
+ if arg.nil? == false
129
+ args[index] = arg.gsub("%20", " ")
130
+ index += 1
131
+ end
132
+ end
133
+
134
+ return args
135
+ end
136
+
137
+ # Normalizes this URI's path. Not very clean but hopefully does the trick
138
+ # https://owasp.org/www-community/attacks/Path_Traversal
139
+ # https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#normalize()
140
+ def normalize_path(path)
141
+ # Removes . any number
142
+ # path.gsub!(/\.+/, ".")
143
+ REPLACEMENTS.each do |replacement|
144
+ path.gsub!(replacement[0], replacement[1])
145
+ end
146
+ return path
147
+ end
148
+ end
@@ -0,0 +1,33 @@
1
+ require 'socket'
2
+ require 'pp'
3
+ require "supersimplehttp/version"
4
+ require_relative 'http'
5
+
6
+ module Supersimplehttp
7
+ class Error < StandardError; end
8
+ class Server
9
+ def initialize(addr, port, &block)
10
+ @server = TCPServer.new(addr, port)
11
+ if block
12
+ puts block.call()
13
+ end
14
+ run
15
+ end
16
+
17
+ def run
18
+ loop do
19
+ Thread.start(@server.accept) do |client|
20
+ request = client.readpartial(2048)
21
+
22
+ request = RequestParser.new(request).parse
23
+ response = ResponsePreparer.new.prepare_response(request)
24
+ puts "[#{Time.now.strftime("%H:%M:%S")}] #{client.peeraddr[3]} #{request.fetch(:path)} - #{response.code}"
25
+ # Pretty print request
26
+ # STDERR.puts PP.pp(request, $>, 40)
27
+ response.send(client)
28
+ client.close
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Supersimplehttp
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,40 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "supersimplehttp/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "supersimplehttp"
8
+ spec.version = Supersimplehttp::VERSION
9
+ spec.authors = ["filipwtf"]
10
+ spec.email = ["filip@egg-is-the-best.com"]
11
+
12
+ spec.summary = "Super simple http server"
13
+ spec.description = "Creates a super simple http server"
14
+ spec.homepage = "https://github.com/filipwtf/supersimplehttp"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = "https://github.com/filipwtf/supersimplehttp"
22
+ spec.metadata["changelog_uri"] = "https://github.com/filipwtf/supersimplehttp/blob/master/CHANGELOG.md"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against " \
25
+ "public gem pushes."
26
+ end
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ spec.add_development_dependency "bundler", "~> 2.1.4"
38
+ spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "minitest", "~> 5.0"
40
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: supersimplehttp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - filipwtf
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Creates a super simple http server
56
+ email:
57
+ - filip@egg-is-the-best.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitattributes"
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - CHANGELOG.md
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - example/server.rb
74
+ - example/tmp/web-server/index.html
75
+ - lib/http.rb
76
+ - lib/supersimplehttp.rb
77
+ - lib/supersimplehttp/version.rb
78
+ - supersimplehttp.gemspec
79
+ homepage: https://github.com/filipwtf/supersimplehttp
80
+ licenses:
81
+ - MIT
82
+ metadata:
83
+ homepage_uri: https://github.com/filipwtf/supersimplehttp
84
+ source_code_uri: https://github.com/filipwtf/supersimplehttp
85
+ changelog_uri: https://github.com/filipwtf/supersimplehttp/blob/master/CHANGELOG.md
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.1.4
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Super simple http server
105
+ test_files: []