rffw 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.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.md +60 -0
- data/Rakefile +41 -0
- data/bin/rffw +16 -0
- data/lib/rffw.rb +7 -0
- data/lib/rffw/app.rb +36 -0
- data/lib/rffw/app/app_handler.rb +59 -0
- data/lib/rffw/app/data/images/bg.png +0 -0
- data/lib/rffw/app/data/index.html +56 -0
- data/lib/rffw/app/data/javascripts/application.js +110 -0
- data/lib/rffw/app/data/stylesheets/style.css +338 -0
- data/lib/rffw/app/data/template.html +42 -0
- data/lib/rffw/app/db.rb +19 -0
- data/lib/rffw/app/description_handler.rb +12 -0
- data/lib/rffw/app/dir_handler.rb +36 -0
- data/lib/rffw/app/record.rb +43 -0
- data/lib/rffw/app/show_handler.rb +25 -0
- data/lib/rffw/app/upload_handler.rb +32 -0
- data/lib/rffw/app/upload_status_handler.rb +40 -0
- data/lib/rffw/app/urlencode_chars.data +224 -0
- data/lib/rffw/app/view_helpers.rb +30 -0
- data/lib/rffw/parser.rb +9 -0
- data/lib/rffw/parser/http_request.rb +137 -0
- data/lib/rffw/parser/http_response.rb +29 -0
- data/lib/rffw/parser/mime_parser.rb +46 -0
- data/lib/rffw/server.rb +15 -0
- data/lib/rffw/server/buffered_client.rb +57 -0
- data/lib/rffw/server/client.rb +53 -0
- data/lib/rffw/server/http_client.rb +49 -0
- data/lib/rffw/server/server.rb +46 -0
- data/lib/rffw/version.rb +3 -0
- data/rffw.db +0 -0
- data/rffw.gemspec +21 -0
- data/test/fixtures/image.jpg +0 -0
- data/test/fixtures/mime_image.data +0 -0
- data/test/fixtures/mime_image.png +0 -0
- data/test/fixtures/post_form_data.http +14 -0
- data/test/fixtures/raw_request.txt +8 -0
- data/test/fixtures/request.http +9 -0
- data/test/fixtures/upload.http +0 -0
- data/test/fixtures/upload_status_request.http +10 -0
- data/test/helper.rb +97 -0
- data/test/test_buffered_client.rb +50 -0
- data/test/test_client.rb +47 -0
- data/test/test_db.rb +21 -0
- data/test/test_http_client.rb +26 -0
- data/test/test_http_request.rb +52 -0
- data/test/test_mime_parser.rb +22 -0
- data/test/test_record.rb +49 -0
- data/test/test_upload_status_handler.rb +18 -0
- data/test/test_uploader_handler.rb +10 -0
- data/test/test_view_helpers.rb +24 -0
- metadata +122 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
+
<meta name="description" content="Recive files from webserver">
|
8
|
+
<meta name="author" content="Guillermo Álvarez Fernández <guillermo@cientifico.net>">
|
9
|
+
|
10
|
+
<title>rffw</title>
|
11
|
+
|
12
|
+
<link href='http://fonts.googleapis.com/css?family=Josefin+Sans:light,lightitalic,regular,regularitalic,bold&v1' rel='stylesheet' type='text/css'>
|
13
|
+
<link href='http://fonts.googleapis.com/css?family=The+Girl+Next+Door&v1' rel='stylesheet' type='text/css'>
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="/stylesheets/style.css?v=2">
|
16
|
+
<script type="text/javascript" charset="utf-8" src="/javascripts/application.js"></script>
|
17
|
+
|
18
|
+
<style>
|
19
|
+
|
20
|
+
</style>
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
|
24
|
+
<div id="wrapper">
|
25
|
+
|
26
|
+
<header>
|
27
|
+
<h1>rffw</h1>
|
28
|
+
<h2>Recive files from webserver</h2>
|
29
|
+
</header>
|
30
|
+
<section class="center">
|
31
|
+
<p>
|
32
|
+
THE_BODYer
|
33
|
+
</p>
|
34
|
+
</section>
|
35
|
+
<div id="push"></div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<footer>
|
39
|
+
<p>You can conact me at <a href="mailto:guillermo@cientifico.net">guillermo@cientifico.net</a>.</p>
|
40
|
+
</footer>
|
41
|
+
</body>
|
42
|
+
</html>
|
data/lib/rffw/app/db.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'dbm'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class RFFW::App::Db < DBM
|
5
|
+
|
6
|
+
class OnlyHashAllowed < StandardError ; end
|
7
|
+
|
8
|
+
EMPTY_MARSHAKED_HASH = Marshal.dump({})
|
9
|
+
|
10
|
+
def [](key)
|
11
|
+
value = Marshal.load(super(key) || EMPTY_MARSHAKED_HASH)
|
12
|
+
value.is_a?(Hash) ? value : {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(key,value)
|
16
|
+
raise OnlyHashAllowed unless value.is_a?(Hash)
|
17
|
+
super(key, Marshal.dump(value))
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RFFW::App::DescriptionHandler
|
2
|
+
include RFFW::Parser
|
3
|
+
include RFFW::App
|
4
|
+
|
5
|
+
def description_handle(request)
|
6
|
+
Record.update_or_create_by_id(request.query, request.post_form_data)
|
7
|
+
to_path = "/show?#{request.query}"
|
8
|
+
HttpResponse.new("Redirect to #{to_path}", 302, {"Location" => to_path})
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RFFW::App::DirHandler
|
2
|
+
include RFFW::Parser
|
3
|
+
|
4
|
+
def dir_handle(request)
|
5
|
+
file = request.path == '/' ? '/index.html' : request.path
|
6
|
+
if file = file_info(file)
|
7
|
+
mime, content = file
|
8
|
+
HttpResponse.new(content, 200, {"Content-Type" => mime}, request.keep_alive? ? "1.1" : "1.0")
|
9
|
+
else
|
10
|
+
HttpResponse.new("File not found", 404)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def file_info(file)
|
17
|
+
file_path = File.expand_path("../data/#{file}",__FILE__)
|
18
|
+
if File.file?(file_path)
|
19
|
+
content = File.read(file_path)
|
20
|
+
mime = get_mime(file_path)
|
21
|
+
[mime,content]
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_mime(file)
|
28
|
+
case file.split('.').last.downcase
|
29
|
+
when 'png' then 'image/png'
|
30
|
+
when 'html' then 'text/html'
|
31
|
+
when 'js' then 'application/javascript'
|
32
|
+
when 'css' then 'text/css'
|
33
|
+
else 'text/html'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class RFFW::App::Record
|
2
|
+
|
3
|
+
ATTRIBUTES = %w(mime_type filename description)
|
4
|
+
|
5
|
+
attr_reader :id
|
6
|
+
attr_accessor :attributes
|
7
|
+
|
8
|
+
def initialize(id, hash = {})
|
9
|
+
@id = id
|
10
|
+
@attributes = hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def new?
|
14
|
+
RFFW::App.db[id].empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_by_id(id)
|
18
|
+
new(id, RFFW::App.db[id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.update_or_create_by_id(id, hash, body = nil)
|
22
|
+
find_by_id(id).tap{ |record|
|
23
|
+
record.body = body unless body.nil?
|
24
|
+
record.attributes = record.attributes.merge(hash) unless hash.nil?
|
25
|
+
RFFW::App.db[id] = record.attributes
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def body=(body)
|
30
|
+
File.open(@id,'w'){|f| f.write body}
|
31
|
+
end
|
32
|
+
|
33
|
+
ATTRIBUTES.each do |attr_name|
|
34
|
+
define_method(attr_name.to_sym) do
|
35
|
+
@attributes[attr_name]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def body
|
41
|
+
File.read(@id) if File.file?(@id)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RFFW::App::ShowHandler
|
2
|
+
include RFFW::Parser
|
3
|
+
include RFFW::App
|
4
|
+
include RFFW::App::ViewHelpers
|
5
|
+
|
6
|
+
def show_handle(request)
|
7
|
+
id, options = request.query.split("&")
|
8
|
+
record = Record.find_by_id(id) unless id.nil?
|
9
|
+
return HttpResponse.new(in_template("not found"), 404) if !record || record.new?
|
10
|
+
|
11
|
+
if options == "download"
|
12
|
+
HttpResponse.new(record.body.force_encoding("BINARY"), 200, {"Content-Type" => record.mime_type})
|
13
|
+
else
|
14
|
+
body = "<h1><a href=\"/show?#{record.id}&download\">#{record.filename}</a></h1><p>#{strip_tags(uri_unescape(record.description))}</p>"
|
15
|
+
HttpResponse.new(in_template(body))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def in_template(content)
|
22
|
+
File.read(File.expand_path("../data/template.html",__FILE__)).gsub("THE_BODYer", content)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RFFW::App::UploadHandler
|
2
|
+
include RFFW::Parser
|
3
|
+
include RFFW::App
|
4
|
+
|
5
|
+
def upload_handle(request)
|
6
|
+
if request.query.nil? || request.query.empty?
|
7
|
+
HttpResponse.new("File not found", 404)
|
8
|
+
else
|
9
|
+
id = request.query
|
10
|
+
attachment = request.attachments.first
|
11
|
+
if attachment
|
12
|
+
Record.update_or_create_by_id(id, {"mime_type" => attachment.content_type, "filename" => attachment.filename}, attachment.to_s)
|
13
|
+
HttpResponse.new("So... Ok. Excelent.",202)
|
14
|
+
else
|
15
|
+
HttpResponse.new("415 Unsupported Media Type", 415)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def uploading_data?
|
21
|
+
request && request.post? && request.path == "/upload"
|
22
|
+
end
|
23
|
+
|
24
|
+
def uploads_for_query(query)
|
25
|
+
self.class.select do |socket|
|
26
|
+
socket.respond_to?(:uploading_data?) &&
|
27
|
+
socket.uploading_data? &&
|
28
|
+
socket.request.query == query
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RFFW::App::UploadStatusHandler
|
2
|
+
include RFFW::Parser
|
3
|
+
include RFFW::App::UploadHandler
|
4
|
+
|
5
|
+
def upload_status_handle(request)
|
6
|
+
uploads = uploads_for_id(request.query)
|
7
|
+
|
8
|
+
attributes = Record.find_by_id(request.query).attributes || {}
|
9
|
+
attributes["progress"] = uploads.first.request.upload_progress if uploads.any?
|
10
|
+
|
11
|
+
if attributes.keys.any?
|
12
|
+
HttpResponse.new(hash_to_json(attributes).to_s, 200)
|
13
|
+
else
|
14
|
+
HttpResponse.new("Not found upload.", 404)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def hash_to_json(hash)
|
22
|
+
values = hash.map{|k,v| %{"#{escape_json(k.to_s)}": "#{escape_json(v.to_s)}"} }.join(", ")
|
23
|
+
"{ #{values} }"
|
24
|
+
end
|
25
|
+
|
26
|
+
def escape_json(code)
|
27
|
+
code.gsub('"','\"')
|
28
|
+
end
|
29
|
+
|
30
|
+
def uploads_for_id(id)
|
31
|
+
RFFW::App::AppHandler.select do |connection|
|
32
|
+
connection.is_a?(RFFW::App::AppHandler) &&
|
33
|
+
connection.respond_to?(:request) &&
|
34
|
+
connection.request &&
|
35
|
+
connection.request.post? &&
|
36
|
+
connection.request.path == "/upload" &&
|
37
|
+
connection.request.query == request.query
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
|
2
|
+
!
|
3
|
+
"
|
4
|
+
#
|
5
|
+
$
|
6
|
+
%
|
7
|
+
&
|
8
|
+
'
|
9
|
+
(
|
10
|
+
)
|
11
|
+
*
|
12
|
+
+
|
13
|
+
,
|
14
|
+
-
|
15
|
+
.
|
16
|
+
/
|
17
|
+
0
|
18
|
+
1
|
19
|
+
2
|
20
|
+
3
|
21
|
+
4
|
22
|
+
5
|
23
|
+
6
|
24
|
+
7
|
25
|
+
8
|
26
|
+
9
|
27
|
+
:
|
28
|
+
;
|
29
|
+
<
|
30
|
+
=
|
31
|
+
>
|
32
|
+
?
|
33
|
+
@
|
34
|
+
A
|
35
|
+
B
|
36
|
+
C
|
37
|
+
D
|
38
|
+
E
|
39
|
+
F
|
40
|
+
G
|
41
|
+
H
|
42
|
+
I
|
43
|
+
J
|
44
|
+
K
|
45
|
+
L
|
46
|
+
M
|
47
|
+
N
|
48
|
+
O
|
49
|
+
P
|
50
|
+
Q
|
51
|
+
R
|
52
|
+
S
|
53
|
+
T
|
54
|
+
U
|
55
|
+
V
|
56
|
+
W
|
57
|
+
X
|
58
|
+
Y
|
59
|
+
Z
|
60
|
+
[
|
61
|
+
\
|
62
|
+
]
|
63
|
+
^
|
64
|
+
_
|
65
|
+
`
|
66
|
+
a
|
67
|
+
b
|
68
|
+
c
|
69
|
+
d
|
70
|
+
e
|
71
|
+
f
|
72
|
+
g
|
73
|
+
h
|
74
|
+
i
|
75
|
+
j
|
76
|
+
k
|
77
|
+
l
|
78
|
+
m
|
79
|
+
n
|
80
|
+
o
|
81
|
+
p
|
82
|
+
q
|
83
|
+
r
|
84
|
+
s
|
85
|
+
t
|
86
|
+
u
|
87
|
+
v
|
88
|
+
w
|
89
|
+
x
|
90
|
+
y
|
91
|
+
z
|
92
|
+
{
|
93
|
+
|
|
94
|
+
}
|
95
|
+
~
|
96
|
+
|
97
|
+
€
|
98
|
+
|
99
|
+
‚
|
100
|
+
ƒ
|
101
|
+
„
|
102
|
+
…
|
103
|
+
†
|
104
|
+
‡
|
105
|
+
ˆ
|
106
|
+
‰
|
107
|
+
Š
|
108
|
+
‹
|
109
|
+
Œ
|
110
|
+
|
111
|
+
Ž
|
112
|
+
|
113
|
+
|
114
|
+
‘
|
115
|
+
’
|
116
|
+
“
|
117
|
+
”
|
118
|
+
•
|
119
|
+
–
|
120
|
+
—
|
121
|
+
˜
|
122
|
+
™
|
123
|
+
š
|
124
|
+
›
|
125
|
+
œ
|
126
|
+
|
127
|
+
ž
|
128
|
+
Ÿ
|
129
|
+
|
130
|
+
¡
|
131
|
+
¢
|
132
|
+
£
|
133
|
+
|
134
|
+
¥
|
135
|
+
|
|
136
|
+
§
|
137
|
+
¨
|
138
|
+
©
|
139
|
+
ª
|
140
|
+
«
|
141
|
+
¬
|
142
|
+
¯
|
143
|
+
®
|
144
|
+
¯
|
145
|
+
°
|
146
|
+
±
|
147
|
+
²
|
148
|
+
³
|
149
|
+
´
|
150
|
+
µ
|
151
|
+
¶
|
152
|
+
·
|
153
|
+
¸
|
154
|
+
¹
|
155
|
+
º
|
156
|
+
»
|
157
|
+
¼
|
158
|
+
½
|
159
|
+
¾
|
160
|
+
¿
|
161
|
+
À
|
162
|
+
Á
|
163
|
+
Â
|
164
|
+
Ã
|
165
|
+
Ä
|
166
|
+
Å
|
167
|
+
Æ
|
168
|
+
Ç
|
169
|
+
È
|
170
|
+
É
|
171
|
+
Ê
|
172
|
+
Ë
|
173
|
+
Ì
|
174
|
+
Í
|
175
|
+
Î
|
176
|
+
Ï
|
177
|
+
Ð
|
178
|
+
Ñ
|
179
|
+
Ò
|
180
|
+
Ó
|
181
|
+
Ô
|
182
|
+
Õ
|
183
|
+
Ö
|
184
|
+
|
185
|
+
Ø
|
186
|
+
Ù
|
187
|
+
Ú
|
188
|
+
Û
|
189
|
+
Ü
|
190
|
+
Ý
|
191
|
+
Þ
|
192
|
+
ß
|
193
|
+
à
|
194
|
+
á
|
195
|
+
â
|
196
|
+
ã
|
197
|
+
ä
|
198
|
+
å
|
199
|
+
æ
|
200
|
+
ç
|
201
|
+
è
|
202
|
+
é
|
203
|
+
ê
|
204
|
+
ë
|
205
|
+
ì
|
206
|
+
í
|
207
|
+
î
|
208
|
+
ï
|
209
|
+
ð
|
210
|
+
ñ
|
211
|
+
ò
|
212
|
+
ó
|
213
|
+
ô
|
214
|
+
õ
|
215
|
+
ö
|
216
|
+
÷
|
217
|
+
ø
|
218
|
+
ù
|
219
|
+
ú
|
220
|
+
û
|
221
|
+
ü
|
222
|
+
ý
|
223
|
+
þ
|
224
|
+
ÿ
|