nile 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjUwY2UxMmFjNjc1NDJlZTY3NGMxYTUxZDA1MzBkNDBhNzRkZTAzZA==
5
+ data.tar.gz: !binary |-
6
+ NzUzNmM0MDkxMWJhZGVhNGNmODYyNzFmODg3MjZkZmMzODRkNWRlNQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTQ5MjQzODg3YWVhZjRhMDI1NGI3ODI5NmVhMTIwNjA0N2RkZTEwMWRhNTI3
10
+ N2M0Zjk0ZTQ0NmEwYzJhNTM0MTFlNWE3YTQ0ODBkYjhiZTg5ZTQ0YmRjYWYy
11
+ NWU0NGNhNGVhZmI2M2I0YzVlZTI2OTVlMjcwYTk1OTg3ZWRhZGQ=
12
+ data.tar.gz: !binary |-
13
+ NjQwODliMzAwYjU2OWU4MDQ4ZTE5MmY0OTYzYTBlYWFhMjkwMzZjZGIzMDNj
14
+ M2UzNWFlYzg5MmNkZTk2YzE0MzFmMDc1Nzg5NTcxNTdhNzI0YjhlNjM3NjJm
15
+ ZjU4YTI3ZjQwNDhiZjYxNDg5YjA5ZGM4ZDlmZmIyZjBmNDJmZTk=
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .idea
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2014 Luca Cervasio
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.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # Nile webframework
2
+
3
+ A demonstrative and basic ruby webframework implementing http daemon from scratch.
4
+
5
+ You can register a route and return the body:
6
+
7
+ ```ruby
8
+ #!/usr/bin/env ruby
9
+
10
+ require 'nile'
11
+
12
+ n = Nile::Core.new :bind => '0.0.0.0', :port => 7125
13
+ n.get '/' do
14
+ [200, {'Content-Type' => 'text/html'}, ['<h1>Hello Nile !</h1>']]
15
+ end
16
+
17
+ n.post '/status' do |env|
18
+ data = JSON.parse(env[:req][:body])
19
+ puts data
20
+ puts env[:params]
21
+ [200, {'Content-Type' => 'application/json'}, [JSON.pretty_generate({:status => 'ok'})]]
22
+ end
23
+
24
+ n.run
25
+ ```
26
+
27
+ # Using the http daemon
28
+
29
+ Nile includes an http daemon written in pure ruby from scratch, just for didactic purposes.
30
+ You can use it this way:
31
+
32
+ ```ruby
33
+ #!/usr/bin/env ruby
34
+
35
+ require 'nile'
36
+
37
+ class HttpHandler
38
+ def handle req, sock
39
+ [200, {'Content-Type' => 'text/plain'}, ['Hello from Nile !']]
40
+ end
41
+ end
42
+
43
+ http = Nile::HttpServer.new "0.0.0.0", 7125, HttpHandler.new
44
+ http.serve
45
+ ```
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nile'
4
+
5
+ n = Nile::Core.new :bind => '0.0.0.0', :port => 7125
6
+ n.get '/' do
7
+ [200, {'Content-Type' => 'text/html'}, ['<h1>Hello Nile !</h1>']]
8
+ end
9
+
10
+ n.post '/status' do |env|
11
+ data = JSON.parse(env[:req][:body])
12
+ puts data
13
+ puts env[:params]
14
+ [200, {'Content-Type' => 'application/json'}, [JSON.pretty_generate({:status => 'ok'})]]
15
+ end
16
+
17
+ n.run
data/lib/nile.rb ADDED
@@ -0,0 +1,3 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "nile")
2
+ require 'httpd'
3
+ require 'framework'
@@ -0,0 +1,90 @@
1
+ require 'singleton'
2
+ require 'json'
3
+ require 'httpd'
4
+
5
+ module Nile
6
+
7
+ class Router
8
+ include Singleton
9
+ attr_accessor :routes
10
+
11
+ def initialize
12
+ @routes = []
13
+ end
14
+
15
+ def add_route(verb, url, block)
16
+ @routes << {:verb => verb, :url => url, :cb => block}
17
+ end
18
+
19
+ def find_route verb, url
20
+ @routes.each do |route|
21
+ if route[:url] == url && route[:verb] == verb
22
+ return route
23
+ end
24
+ end
25
+ return {:cb => Proc.new { [404, {}, ["Not found"]] } }
26
+ end
27
+ end
28
+
29
+ class HttpHandler
30
+ def handle req, sock
31
+ start = Time.new
32
+ r = Router.instance
33
+
34
+ querystring = req[:url].split("?")
35
+ params = {}
36
+ if querystring[1].respond_to? :split
37
+ querystring[1].split("&").each do |param|
38
+ param =~ /(\w+)=*(.*)/
39
+ params[$1] = $2
40
+ end
41
+ end
42
+
43
+ route = r.find_route(req[:verb], querystring[0])
44
+ begin
45
+ response = route[:cb].call({:params => params, :req => req})
46
+ rescue Exception => e
47
+ response = [500, {}, ['Internal Server Error: ' + e.message]]
48
+ end
49
+
50
+ response[1]['Server'] = 'Nile 0.1'
51
+ response[1]['Content-Length'] = response[2].join("\n").length
52
+
53
+ return response
54
+ end
55
+ end
56
+
57
+ class Core
58
+ attr_accessor :router
59
+
60
+ def initialize args={}
61
+ args[:port] ||= 7125
62
+ args[:bind] ||= '127.0.0.1'
63
+ @http = Nile::HttpServer.new args[:bind], args[:port], HttpHandler.new
64
+ @router = Router.instance
65
+ end
66
+
67
+ def get url, &block
68
+ @router.add_route "GET", url, block
69
+ end
70
+
71
+ def post url, &block
72
+ @router.add_route "POST", url, block
73
+ end
74
+
75
+ def put url, &block
76
+ @router.add_route "PUT", url, block
77
+ end
78
+
79
+ def delete url, &block
80
+ @router.add_route "DELETE", url, block
81
+ end
82
+
83
+ def run
84
+ @http.serve
85
+ end
86
+
87
+ end
88
+
89
+
90
+ end
data/lib/nile/httpd.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'socket'
2
+
3
+ Thread::abort_on_exception = true
4
+
5
+ module Nile
6
+
7
+ class HttpServer
8
+
9
+ attr_accessor :bind_address, :port, :cb
10
+
11
+ def initialize (address, port, cb)
12
+ @bind_address = address
13
+ @port = port
14
+ @cb = cb
15
+ end
16
+
17
+ def serve
18
+ webserver = TCPServer.new(@bind_address, @port)
19
+ print "HttpServer running at http://#{@bind_address}:#{@port}\n"
20
+
21
+ while (client = webserver.accept)
22
+
23
+ Thread.start(client) do |client|
24
+ start = Time.new
25
+ req = read_request client
26
+ http_messages = {
27
+ 200 => 'OK',
28
+ 204 => 'No Content',
29
+ 301 => 'Moved Permanently',
30
+ 302 => 'Found',
31
+ 401 => 'Unauthorized',
32
+ 403 => 'Forbidden',
33
+ 404 => 'Not Found',
34
+ 500 => 'Internal Server Error'
35
+ }
36
+ response = @cb.handle req, client
37
+ finish = Time.new
38
+
39
+ print "handling request #{req[:url]} from #{req[:remote_ip]}:#{req[:remote_port]} (#{req[:len]} bytes) --> replying #{response[0]} #{http_messages[response[0]]} (#{response[2].join("\n").length} bytes) in #{((finish - start) * 1000.0).round(2)} ms\n"
40
+
41
+ client.write "HTTP/1.1 #{response[0]} #{http_messages[response[0]]}\r\n"
42
+ response[1].each do |k,v|
43
+ client.write "#{k}: #{v}\r\n"
44
+ end
45
+ client.write "\r\n" + response[2].join("\n")
46
+
47
+ client.close
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ def read_request sock
55
+ data = sock.recv 1024
56
+ data =~ /Content-Length: (\d+)/
57
+ content_len = $1.to_i
58
+ split_point = data.index "\r\n\r\n"
59
+
60
+ while data.length - split_point - 4 < content_len
61
+ data += sock.recv 1024
62
+ end
63
+
64
+ headers = data[0..split_point-1].split("\r\n")
65
+ first = headers[0]
66
+ headers.delete_at(0)
67
+ first =~ /(\w+)\ ([\w|\/|\?|\-|\=|\&]+)\ HTTP\//
68
+ verb = $1
69
+ url = $2
70
+
71
+ headers_by_key = {}
72
+ headers.each do |header|
73
+ header =~ /^([\w|\-]+): (.*)/
74
+ headers_by_key[$1] = $2
75
+ end
76
+
77
+ sock_domain, remote_port, remote_hostname, remote_ip = sock.peeraddr
78
+ {:verb => verb, :url => url, :headers => headers_by_key, :body => data[split_point+4..data.length], :remote_ip => remote_ip, :remote_port => remote_port, :len => content_len, :overall_len => data.length}
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,3 @@
1
+ module Nile
2
+ VERSION = "1.1.3"
3
+ end
data/nile.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ require './lib/nile/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'nile'
5
+ spec.version = Nile::VERSION
6
+ spec.date = Date.today.to_s
7
+ spec.summary = "A demonstrative and basic ruby webframework implementing http daemon from scratch"
8
+ spec.description = "A demonstrative and basic ruby webframework implementing http daemon from scratch"
9
+ spec.authors = ["Luca Cervasio"]
10
+ spec.email = 'luca.cervasio@gmail.com'
11
+ spec.files = `git ls-files`.split($/)
12
+ spec.homepage = 'https://github.com/lucacervasio/nile'
13
+ spec.license = 'MIT'
14
+
15
+ #spec.add_dependency('sourcify', '0.6.0.rc4')
16
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nile
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Luca Cervasio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A demonstrative and basic ruby webframework implementing http daemon
14
+ from scratch
15
+ email: luca.cervasio@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .gitignore
21
+ - LICENSE
22
+ - README.md
23
+ - examples/simple.rb
24
+ - lib/nile.rb
25
+ - lib/nile/framework.rb
26
+ - lib/nile/httpd.rb
27
+ - lib/nile/version.rb
28
+ - nile.gemspec
29
+ homepage: https://github.com/lucacervasio/nile
30
+ licenses:
31
+ - MIT
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.4.6
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: A demonstrative and basic ruby webframework implementing http daemon from
53
+ scratch
54
+ test_files: []