minimal-http-ruby 0.0.1
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 +7 -0
- data/examples/server.rb +16 -0
- data/http/coffee/test.coffee +113 -0
- data/http/css/test.css +0 -0
- data/http/haml/index.haml +4 -0
- data/http/index.html +1 -0
- data/http/json/demo.rb +9 -0
- data/http/json/sse_demo.rb +12 -0
- data/lib/minimal-http-ruby.rb +184 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1f40406e10604533501b92608abd1d3590ccdb98
|
4
|
+
data.tar.gz: 5f6e51aa38ae21900bd6b9769106547b7b9d29e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d18d30f0b956c9fc38d916aac65054c35a160bacc3a4378eb8be1fa3c41c7792deccce9b815f4f610098cd8d9900716202af7785c4df32d2bdc67eea94d2e33d
|
7
|
+
data.tar.gz: c07837025723effe06f0b8548b072ae648019206baa58ae7e06f6163c278244c2bf37e27b4269ab95ba2edeb5c100fd4561ad34ff3118ef895225f01c26a6c38
|
data/examples/server.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encode: UTF-8
|
3
|
+
|
4
|
+
|
5
|
+
if File.file? './lib/minimal-http-ruby.rb'
|
6
|
+
require './lib/minimal-http-ruby.rb'
|
7
|
+
puts "using local http lib"
|
8
|
+
else
|
9
|
+
require 'minimal-http-ruby'
|
10
|
+
end
|
11
|
+
|
12
|
+
minimal_http_server http_port: 8088, http_path: "./http/"
|
13
|
+
|
14
|
+
loop do
|
15
|
+
sleep 1
|
16
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
now=0
|
3
|
+
xx=123
|
4
|
+
|
5
|
+
update_status = (data) ->
|
6
|
+
console.log data.jes
|
7
|
+
console.log data.clients
|
8
|
+
#console.log data.logpos
|
9
|
+
now=data.now
|
10
|
+
html="<table><tr><th>uri</th><th>state</th><th>stamp</th><th>last_send</th><th>counter_send</th><th>last_recv</th><th>counter_recv</th></tr>"
|
11
|
+
for k,v of data.clients
|
12
|
+
html+="<tr>"
|
13
|
+
html+="<td>#{k}</td>"
|
14
|
+
html+="<td>#{v.state}</td>"
|
15
|
+
html+="<td>#{now-v.stamp}</td>"
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
if v.last_send
|
20
|
+
html+="<td>#{now-v.last_send}</td>"
|
21
|
+
else
|
22
|
+
html+="<td></td>"
|
23
|
+
html+="<td>#{v.counter_send}</td>"
|
24
|
+
|
25
|
+
if v.last_recv
|
26
|
+
html+="<td>#{now-v.last_recv}</td>"
|
27
|
+
else
|
28
|
+
html+="<td></td>"
|
29
|
+
html+="<td>#{v.counter_recv}</td>"
|
30
|
+
|
31
|
+
html+="</tr>"
|
32
|
+
html+="</table>"
|
33
|
+
#console.log html
|
34
|
+
$(".clients").html(html)
|
35
|
+
|
36
|
+
html="<table><tr><th>gw_id</th><th>uri</th><th>source</th><th>stamp</th><th>last_use</th><th>last_ping</th><th>last_send</th><th>counter_send</th><th>last_recv</th><th>counter_recv</th></tr>"
|
37
|
+
for k,v of data.gateways
|
38
|
+
k=parseInt(k,10)
|
39
|
+
col="white"
|
40
|
+
if data.active_gw_id== k
|
41
|
+
col="#d0ffd0"
|
42
|
+
html+="<tr bgcolor='#{col}'>"
|
43
|
+
html+="<td>#{k}</td>"
|
44
|
+
html+="<td>#{v.uri}</td>"
|
45
|
+
html+="<td>#{v.source}</td>"
|
46
|
+
html+="<td>#{now-v.stamp}</td>"
|
47
|
+
if v.last_use
|
48
|
+
html+="<td>#{now-v.last_use}</td>"
|
49
|
+
else
|
50
|
+
html+="<td></td>"
|
51
|
+
if v.last_ping
|
52
|
+
html+="<td>#{now-v.last_ping}</td>"
|
53
|
+
else
|
54
|
+
html+="<td></td>"
|
55
|
+
|
56
|
+
if v.last_send
|
57
|
+
html+="<td>#{now-v.last_send}</td>"
|
58
|
+
else
|
59
|
+
html+="<td></td>"
|
60
|
+
html+="<td>#{v.counter_send}</td>"
|
61
|
+
|
62
|
+
if v.last_recv
|
63
|
+
html+="<td>#{now-v.last_recv}</td>"
|
64
|
+
else
|
65
|
+
html+="<td></td>"
|
66
|
+
html+="<td>#{v.counter_recv}</td>"
|
67
|
+
html+="</tr>"
|
68
|
+
if data.jes[1]==0
|
69
|
+
$(".log").html("")
|
70
|
+
for l in data.loglines
|
71
|
+
#console.log l
|
72
|
+
$(".log").prepend(l.text+"\n")
|
73
|
+
html+="</table>"
|
74
|
+
#console.log html
|
75
|
+
$(".data").html(html)
|
76
|
+
$(".info").html("State: #{data.state}, gw: #{data.active_gw_id}, app: #{data.options.app_name}, ")
|
77
|
+
|
78
|
+
|
79
|
+
@ajax = (obj) ->
|
80
|
+
console.log "doin ajax"
|
81
|
+
form=$(obj).closest("form")
|
82
|
+
key=form.attr('id')
|
83
|
+
q=$( form ).serialize()
|
84
|
+
console.log q
|
85
|
+
$.ajax
|
86
|
+
url: "/action.json?#{q}"
|
87
|
+
type: "GET"
|
88
|
+
processData: false
|
89
|
+
contentType: false
|
90
|
+
success: (data) ->
|
91
|
+
console.log "ajax returns: ", data
|
92
|
+
|
93
|
+
return
|
94
|
+
error: (xhr, ajaxOptions, thrownError) ->
|
95
|
+
alert thrownError
|
96
|
+
return
|
97
|
+
|
98
|
+
|
99
|
+
$ ->
|
100
|
+
console.log "tadaa"
|
101
|
+
#update_gw()
|
102
|
+
#setInterval(->
|
103
|
+
# update_gw()
|
104
|
+
# return
|
105
|
+
#, 200000)
|
106
|
+
stream = new EventSource("/gateways.json")
|
107
|
+
stream.addEventListener "message", (event) ->
|
108
|
+
update_status($.parseJSON(event.data))
|
109
|
+
return
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
data/http/css/test.css
ADDED
File without changes
|
data/http/index.html
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
oukei
|
data/http/json/demo.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encode: UTF-8
|
3
|
+
|
4
|
+
require "haml"
|
5
|
+
require "coffee-script"
|
6
|
+
require "pp"
|
7
|
+
require 'socket'
|
8
|
+
require 'json'
|
9
|
+
require 'uri'
|
10
|
+
require 'ipaddr'
|
11
|
+
require 'time'
|
12
|
+
require 'thread'
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
def minimal_http_server options={}
|
17
|
+
prev_t={}
|
18
|
+
cache={}
|
19
|
+
ports=['127.0.0.1']
|
20
|
+
if Socket.method_defined? :getifaddrs
|
21
|
+
ports=Socket.getifaddrs.map { |i| i.addr.ip_address if i.addr.ipv4? }.compact
|
22
|
+
puts "Starting HTTP services at port #{options[:http_port]}, server IPs: #{ports}"
|
23
|
+
else
|
24
|
+
puts "Starting HTTP services at port #{options[:http_port]}."
|
25
|
+
end
|
26
|
+
if options[:http_path]
|
27
|
+
$http_dir=options[:http_path]
|
28
|
+
elsif File.directory? './http'
|
29
|
+
$http_dir="http/"
|
30
|
+
else
|
31
|
+
$http_dir = File.join( Gem.loaded_specs['mqtt-sn-ruby'].full_gem_path, 'http/')
|
32
|
+
end
|
33
|
+
puts "Serving pages from home directory: '#{$http_dir}'"
|
34
|
+
statuses={ "200" => "OK", "404" => "Not Found", "500" => "Internal Server Error"}
|
35
|
+
Thread.new(options[:http_port],options[:app_name]) do |http_port,http_app|
|
36
|
+
server = TCPServer.new("0.0.0.0",http_port)
|
37
|
+
@http_sessions={}
|
38
|
+
http_session_counter=1
|
39
|
+
loop do
|
40
|
+
Thread.start(server.accept) do |client|
|
41
|
+
begin
|
42
|
+
@start=Time.now
|
43
|
+
client_port= client.peeraddr[1]
|
44
|
+
client_ip= client.peeraddr[2]
|
45
|
+
raw=client.gets
|
46
|
+
if not raw
|
47
|
+
puts "#{client_ip}:#{client_port} #{Time.now.iso8601} ?? nil request?"
|
48
|
+
client.close
|
49
|
+
next
|
50
|
+
end
|
51
|
+
raw=raw.chop
|
52
|
+
method,req,http_proto = raw.split " "
|
53
|
+
status="200"
|
54
|
+
type="text/html"
|
55
|
+
req="/#{http_app||'index'}.html" if req=="/" or req=="/index.htm" or req=="/index.html"
|
56
|
+
req,argss=req.split "\?"
|
57
|
+
args={}
|
58
|
+
if argss
|
59
|
+
argss.split("&").each do |a|
|
60
|
+
if a
|
61
|
+
k,v=URI.decode(a).force_encoding("UTF-8").split "="
|
62
|
+
args[k]=v
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
if req[/\.html$/] and File.file?(fn="#{$http_dir}haml#{req.gsub('.html','.haml')}")
|
67
|
+
contents = File.read(fn) # never cached -- may be dynamically generated
|
68
|
+
response=Haml::Engine.new(contents).render
|
69
|
+
elsif req[/\.js$/] and File.file?(fn="#{$http_dir}coffee#{req.gsub('.js','.coffee')}")
|
70
|
+
type="application/javascript"
|
71
|
+
t=File.mtime(fn)
|
72
|
+
if not prev_t[fn] or prev_t[fn]<t
|
73
|
+
contents = File.read(fn)
|
74
|
+
begin
|
75
|
+
response=CoffeeScript.compile contents
|
76
|
+
prev_t[fn]=t
|
77
|
+
cache[fn]=response
|
78
|
+
rescue => e
|
79
|
+
type="text/html"
|
80
|
+
status="500"
|
81
|
+
response="Coffee Compile error: #{e}"
|
82
|
+
end
|
83
|
+
else
|
84
|
+
response=cache[fn]
|
85
|
+
end
|
86
|
+
elsif req[/^\/(.+)\.json$/] and File.file?(fn="#{$http_dir}json#{req.gsub('.json','.rb')}")
|
87
|
+
req[/\/(.+).json$/]
|
88
|
+
act=$1
|
89
|
+
t=File.mtime(fn)
|
90
|
+
if not prev_t[fn] or prev_t[fn]<t
|
91
|
+
begin
|
92
|
+
load_ok=load fn
|
93
|
+
prev_t[fn]=t
|
94
|
+
rescue Exception => e
|
95
|
+
puts "**** RELOAD #{fn} failed: #{e}"
|
96
|
+
pp e.backtrace
|
97
|
+
response=[{act: :error, msg:"Error loading JSON",alert: "Load error #{e} in #{fn}"}].to_json
|
98
|
+
type="application/json"
|
99
|
+
status="404"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
if type!="text/event-stream" and status=="200"
|
103
|
+
begin
|
104
|
+
type,response=eval "json_#{act} [method,req,http_proto],args,0,0" #event handlers get called with zero session => init :)
|
105
|
+
rescue => e
|
106
|
+
puts "**** AJAX EXEC #{fn} failed: #{e}"
|
107
|
+
pp e.backtrace
|
108
|
+
response=[{act: :error, msg:"Error executing JSON",alert: "Syntax error '#{e}' in '#{fn}'"}].to_json
|
109
|
+
type="application/json"
|
110
|
+
end
|
111
|
+
response=response.to_json
|
112
|
+
end
|
113
|
+
elsif File.file?(fnc="#{$http_dir}#{req}")
|
114
|
+
type="text/css" if req[/\.css$/]
|
115
|
+
t=File.mtime(fnc)
|
116
|
+
if not prev_t[fnc] or prev_t[fnc]<t
|
117
|
+
contents = File.read(fnc)
|
118
|
+
response=contents
|
119
|
+
prev_t[fnc]=t
|
120
|
+
cache[fnc]=response
|
121
|
+
else
|
122
|
+
response=cache[fnc]
|
123
|
+
end
|
124
|
+
else
|
125
|
+
status="404"
|
126
|
+
response="Not Found: #{req}"
|
127
|
+
end
|
128
|
+
client.print "HTTP/1.1 #{status} #{statuses[status]||'???'}\r\nContent-Type: #{type}\r\n"
|
129
|
+
if type!="text/event-stream"
|
130
|
+
client.print "Content-Length: #{response.bytesize}\r\n"
|
131
|
+
client.print "Connection: close\r\n"
|
132
|
+
client.print "\r\n"
|
133
|
+
client.print response
|
134
|
+
else
|
135
|
+
client.print "Expires: -1\r\n"
|
136
|
+
client.print "\r\n"
|
137
|
+
begin
|
138
|
+
my_session=client.peeraddr[1]
|
139
|
+
if not @http_sessions[my_session]
|
140
|
+
#puts "**************** new port #{my_session}"
|
141
|
+
@http_sessions[my_session]={client_port:client.peeraddr[1],client_ip:client.peeraddr[2] , log_position:0 }
|
142
|
+
end
|
143
|
+
my_event=0
|
144
|
+
loop do
|
145
|
+
begin
|
146
|
+
type,response=eval "json_#{act} raw,args,my_session,my_event"
|
147
|
+
my_event+=1
|
148
|
+
rescue => e
|
149
|
+
puts "**** AJAX EXEC #{fn} failed: #{e}"
|
150
|
+
puts "#{e.backtrace[0..2]}"
|
151
|
+
pp e.backtrace
|
152
|
+
response=[{act: :error, msg:"Error executing JSON",alert: "Syntax error '#{e}' in '#{fn}'"}].to_json
|
153
|
+
end
|
154
|
+
if not response or response==[] or response=={}
|
155
|
+
else
|
156
|
+
client.print "retry: 1000\n"
|
157
|
+
client.print "data: #{response.to_json}\n\n"
|
158
|
+
end
|
159
|
+
sleep 1
|
160
|
+
break if my_event>100
|
161
|
+
end
|
162
|
+
rescue => e
|
163
|
+
puts "stream #{client} died #{e}"
|
164
|
+
pp e.backtrace
|
165
|
+
end
|
166
|
+
end
|
167
|
+
dur=sprintf "%.2f",(Time.now.to_f-@start.to_f)
|
168
|
+
puts "#{client_ip}:#{client_port} #{Time.now.iso8601} \"#{method} #{req}\" #{status} #{response.bytesize} \"#{type}\" #{dur}"
|
169
|
+
client.close
|
170
|
+
rescue Exception =>e
|
171
|
+
response="Error '#{e}'"
|
172
|
+
status="500"
|
173
|
+
type="text/html"
|
174
|
+
dur=sprintf "%.2f",(Time.now.to_f-@start.to_f)
|
175
|
+
puts "#{client_ip}:#{client_port} #{Time.now.iso8601} \"#{method} #{req}\" #{status} #{response.bytesize} \"#{type}\" #{dur}"
|
176
|
+
client.print "HTTP/1.1 #{status} #{statuses[status]||'???'}\r\nContent-Type: #{type}\r\n\r\n"
|
177
|
+
client.print response
|
178
|
+
client.close
|
179
|
+
pp e.backtrace
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minimal-http-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ari Siitonen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Minimal Http Server Class with Ryby: Haml & Coffeescript & SSE & AJAX
|
14
|
+
-- well under 200 lines of code!'
|
15
|
+
email: jalopuuverstas@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- examples/server.rb
|
21
|
+
- http/coffee/test.coffee
|
22
|
+
- http/css/test.css
|
23
|
+
- http/haml/index.haml
|
24
|
+
- http/index.html
|
25
|
+
- http/json/demo.rb
|
26
|
+
- http/json/sse_demo.rb
|
27
|
+
- lib/minimal-http-ruby.rb
|
28
|
+
homepage: https://github.com/arisi/minimal-hhtp-ruby
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.2.2
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: Minimal Http Server Coffeescript,Ajax,Haml,SSE
|
52
|
+
test_files: []
|