rffw 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/README.md +60 -0
  5. data/Rakefile +41 -0
  6. data/bin/rffw +16 -0
  7. data/lib/rffw.rb +7 -0
  8. data/lib/rffw/app.rb +36 -0
  9. data/lib/rffw/app/app_handler.rb +59 -0
  10. data/lib/rffw/app/data/images/bg.png +0 -0
  11. data/lib/rffw/app/data/index.html +56 -0
  12. data/lib/rffw/app/data/javascripts/application.js +110 -0
  13. data/lib/rffw/app/data/stylesheets/style.css +338 -0
  14. data/lib/rffw/app/data/template.html +42 -0
  15. data/lib/rffw/app/db.rb +19 -0
  16. data/lib/rffw/app/description_handler.rb +12 -0
  17. data/lib/rffw/app/dir_handler.rb +36 -0
  18. data/lib/rffw/app/record.rb +43 -0
  19. data/lib/rffw/app/show_handler.rb +25 -0
  20. data/lib/rffw/app/upload_handler.rb +32 -0
  21. data/lib/rffw/app/upload_status_handler.rb +40 -0
  22. data/lib/rffw/app/urlencode_chars.data +224 -0
  23. data/lib/rffw/app/view_helpers.rb +30 -0
  24. data/lib/rffw/parser.rb +9 -0
  25. data/lib/rffw/parser/http_request.rb +137 -0
  26. data/lib/rffw/parser/http_response.rb +29 -0
  27. data/lib/rffw/parser/mime_parser.rb +46 -0
  28. data/lib/rffw/server.rb +15 -0
  29. data/lib/rffw/server/buffered_client.rb +57 -0
  30. data/lib/rffw/server/client.rb +53 -0
  31. data/lib/rffw/server/http_client.rb +49 -0
  32. data/lib/rffw/server/server.rb +46 -0
  33. data/lib/rffw/version.rb +3 -0
  34. data/rffw.db +0 -0
  35. data/rffw.gemspec +21 -0
  36. data/test/fixtures/image.jpg +0 -0
  37. data/test/fixtures/mime_image.data +0 -0
  38. data/test/fixtures/mime_image.png +0 -0
  39. data/test/fixtures/post_form_data.http +14 -0
  40. data/test/fixtures/raw_request.txt +8 -0
  41. data/test/fixtures/request.http +9 -0
  42. data/test/fixtures/upload.http +0 -0
  43. data/test/fixtures/upload_status_request.http +10 -0
  44. data/test/helper.rb +97 -0
  45. data/test/test_buffered_client.rb +50 -0
  46. data/test/test_client.rb +47 -0
  47. data/test/test_db.rb +21 -0
  48. data/test/test_http_client.rb +26 -0
  49. data/test/test_http_request.rb +52 -0
  50. data/test/test_mime_parser.rb +22 -0
  51. data/test/test_record.rb +49 -0
  52. data/test/test_upload_status_handler.rb +18 -0
  53. data/test/test_uploader_handler.rb +10 -0
  54. data/test/test_view_helpers.rb +24 -0
  55. 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&amp;v1' rel='stylesheet' type='text/css'>
13
+ <link href='http://fonts.googleapis.com/css?family=The+Girl+Next+Door&amp;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>
@@ -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
+ ÿ