minimal-http-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|