thin_upload 0.0.1.pre1
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/Gemfile +7 -0
- data/Gemfile.lock +31 -0
- data/Manifest +44 -0
- data/README.rdoc +40 -0
- data/Rakefile +33 -0
- data/html/README_rdoc.html +133 -0
- data/html/Thin.html +149 -0
- data/html/Thin/Request.html +537 -0
- data/html/Thin/Server.html +194 -0
- data/html/created.rid +4 -0
- data/html/images/brick.png +0 -0
- data/html/images/brick_link.png +0 -0
- data/html/images/bug.png +0 -0
- data/html/images/bullet_black.png +0 -0
- data/html/images/bullet_toggle_minus.png +0 -0
- data/html/images/bullet_toggle_plus.png +0 -0
- data/html/images/date.png +0 -0
- data/html/images/find.png +0 -0
- data/html/images/loadingAnimation.gif +0 -0
- data/html/images/macFFBgHack.png +0 -0
- data/html/images/package.png +0 -0
- data/html/images/page_green.png +0 -0
- data/html/images/page_white_text.png +0 -0
- data/html/images/page_white_width.png +0 -0
- data/html/images/plugin.png +0 -0
- data/html/images/ruby.png +0 -0
- data/html/images/tag_green.png +0 -0
- data/html/images/wrench.png +0 -0
- data/html/images/wrench_orange.png +0 -0
- data/html/images/zoom.png +0 -0
- data/html/index.html +124 -0
- data/html/js/darkfish.js +116 -0
- data/html/js/jquery.js +32 -0
- data/html/js/quicksearch.js +114 -0
- data/html/js/thickbox-compressed.js +10 -0
- data/html/lib/thin_upload/parser_rb.html +54 -0
- data/html/lib/thin_upload/request_rb.html +54 -0
- data/html/lib/thin_upload_rb.html +54 -0
- data/html/rdoc.css +763 -0
- data/lib/thin_upload.rb +3 -0
- data/lib/thin_upload/request.rb +93 -0
- data/test/test_helper.rb +30 -0
- data/test/thin_upload/request_test.rb +91 -0
- data/thin_upload.gemspec +33 -0
- metadata +111 -0
data/lib/thin_upload.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#Thin module from thin server
|
2
|
+
module Thin
|
3
|
+
# The Request class takes part of the Thin module which is responsible
|
4
|
+
# for incomming web requests for thin server.
|
5
|
+
# The class is opened up here for adding functionality to track
|
6
|
+
# progress of file uploads.
|
7
|
+
|
8
|
+
class Request
|
9
|
+
#Freeze Rack header for progress hash
|
10
|
+
RACK_PROGRESS = 'rack.progress'.freeze
|
11
|
+
|
12
|
+
#Freeze some regexps
|
13
|
+
#regexp to identify file upload
|
14
|
+
POST_REQUEST_REGEXP = /uuid\"\r\n\r\n(.*)\r/i.freeze
|
15
|
+
#regexp to identify upload progress requests
|
16
|
+
GET_REQUEST_REGEXP = /uuid=(.*) /.freeze
|
17
|
+
attr_reader :parser
|
18
|
+
attr_accessor :data_buffer
|
19
|
+
|
20
|
+
# +new_parse+ method extends the original +parse+ method's
|
21
|
+
# functionality with the upload progress tracking
|
22
|
+
# Arguments:
|
23
|
+
# data: (String)
|
24
|
+
|
25
|
+
def new_parse(data)
|
26
|
+
scan_content(data) unless uuid_found_or_limit_reached?
|
27
|
+
success = thin_parse(data) #execute the the original +parse+ method
|
28
|
+
store_progress(@upload_uuid)
|
29
|
+
cleanup_progress_hash(@request_uuid)
|
30
|
+
success #returns the result from Thin's parse method
|
31
|
+
end
|
32
|
+
|
33
|
+
# The +Thin+'s +parse+ method is aliased to +thin_parse+
|
34
|
+
# and the +new_parse+ method is aliased to +parse+
|
35
|
+
alias_method :thin_parse, :parse
|
36
|
+
alias_method :parse, :new_parse
|
37
|
+
|
38
|
+
# Scans unparsed data for uuids, the unparsed data
|
39
|
+
# is stored in a string for buffering purposes
|
40
|
+
# which is deleted after the uuid has been found.
|
41
|
+
# Arguments:
|
42
|
+
# data: (String)
|
43
|
+
|
44
|
+
def scan_content(data)
|
45
|
+
@data_buffer = @data_buffer.to_s + data
|
46
|
+
@upload_uuid ||= @data_buffer.scan(POST_REQUEST_REGEXP).flatten.first
|
47
|
+
@request_uuid ||= @data_buffer.scan(GET_REQUEST_REGEXP).flatten.first
|
48
|
+
end
|
49
|
+
|
50
|
+
# Checking if we still have to search for uuid's
|
51
|
+
# Arguments:
|
52
|
+
# none
|
53
|
+
def uuid_found_or_limit_reached?
|
54
|
+
if @upload_uuid || @request_uuid || (body.size > MAX_BODY)
|
55
|
+
@data_buffer = nil
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calculating the progress based on +content_length+ and received body size +body.size+
|
63
|
+
# Arguments:
|
64
|
+
# none
|
65
|
+
def progress
|
66
|
+
((body.size/content_length.to_f)*100).to_i
|
67
|
+
end
|
68
|
+
|
69
|
+
# progress can be accessed via +request.env['rack.progress']+ in the app
|
70
|
+
# Arguments:
|
71
|
+
# uuid: (String)
|
72
|
+
def store_progress(uuid)
|
73
|
+
Thin::Server::progress[uuid] = progress if uuid #storing the progress with the uiid
|
74
|
+
@env.merge!(RACK_PROGRESS=>Thin::Server::progress.clone) if finished? #merging the progress hash into the environment
|
75
|
+
end
|
76
|
+
|
77
|
+
# deleting progress entry from +Thin::Server::progress+ if the upload is finished and the result was requested
|
78
|
+
# Arguments:
|
79
|
+
# data: (String)
|
80
|
+
def cleanup_progress_hash(req_uuid)
|
81
|
+
Thin::Server::progress.delete(req_uuid) if Thin::Server::progress[req_uuid] == 100 && finished?#delete when progress is returned and 100%
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
module Thin
|
86
|
+
# Thin's server class
|
87
|
+
class Server
|
88
|
+
#adding a hash to store all the upload progress in the server
|
89
|
+
def self.progress
|
90
|
+
@@progress||={}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'thin'
|
3
|
+
require 'thin_upload'
|
4
|
+
|
5
|
+
def upload_data_string
|
6
|
+
"form-data; name=\"uuid\"\r\n\r\n#{uuid}\r\n-----------------------------"
|
7
|
+
end
|
8
|
+
|
9
|
+
def post_request(body)
|
10
|
+
"POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/html\r\nContent-Length: #{body.size}\r\n\r\n#{body}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def big_post_request(body)
|
14
|
+
"POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/html\r\nContent-Length: #{Thin::Request::MAX_BODY+1}\r\n\r\n#{body}"
|
15
|
+
end
|
16
|
+
def get_request(url)
|
17
|
+
"GET #{url} HTTP/1.1\r\nHost: localhost:3000\r\n\r\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def uuid
|
22
|
+
"2ce89350-cb31-012e-dc4a-64b9e8c7c202"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create and parse a request
|
26
|
+
def new_request(data)
|
27
|
+
request = Thin::Request.new
|
28
|
+
request.parse(data)
|
29
|
+
request
|
30
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RequestTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@request = new_request(post_request("a"*100))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_scan_uuid_on_url_request
|
10
|
+
@request.scan_content(get_request("?uuid=#{uuid}"))
|
11
|
+
assert_equal @request.instance_variable_get(:@request_uuid), uuid
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_scan_uuid_on_form_request
|
15
|
+
@request.scan_content(upload_data_string)
|
16
|
+
assert_equal @request.instance_variable_get(:@upload_uuid), uuid
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_store_data_in_buffer
|
20
|
+
content = "content"
|
21
|
+
content2 = "content2"
|
22
|
+
@request.parse(content)
|
23
|
+
assert @request.data_buffer.match(/#{content}$/)
|
24
|
+
@request.parse(content2)
|
25
|
+
assert @request.data_buffer.match(/#{content+content2}$/)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_clear_data_from_buffer_when_url_uuid_found
|
29
|
+
content = "content"
|
30
|
+
@request.parse(content)
|
31
|
+
assert @request.data_buffer.match(/#{content}$/)
|
32
|
+
@request.parse(get_request("?uuid=#{uuid}"))
|
33
|
+
assert_equal @request.instance_variable_get(:@request_uuid), uuid
|
34
|
+
@request.parse content
|
35
|
+
assert_equal @request.data_buffer, nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_clear_data_from_buffer_when_form_uuid_found
|
39
|
+
content = "content"
|
40
|
+
@request.parse(content)
|
41
|
+
assert @request.data_buffer.match(/#{content}$/)
|
42
|
+
@request.parse post_request(upload_data_string)
|
43
|
+
assert_equal @request.instance_variable_get(:@upload_uuid), uuid
|
44
|
+
@request.parse content
|
45
|
+
assert_equal @request.data_buffer, nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_stop_parsing_when_body_size_limit_reached
|
49
|
+
@request = new_request(post_request("a"))
|
50
|
+
assert !@request.uuid_found_or_limit_reached?
|
51
|
+
@request.body << "a" * (Thin::Request::MAX_BODY+1)
|
52
|
+
assert @request.uuid_found_or_limit_reached?
|
53
|
+
assert_equal @request.instance_variable_get(:@data_buffer), nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_calculate_progress
|
57
|
+
@request.instance_variable_set(:@body, "a"*20)
|
58
|
+
assert_equal @request.progress, 20
|
59
|
+
@request.instance_variable_set(:@body, "a"*45)
|
60
|
+
assert_equal @request.progress, 45
|
61
|
+
@request.instance_variable_set(:@body, "a"*100)
|
62
|
+
assert_equal @request.progress, 100
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_store_progress
|
66
|
+
@request.instance_variable_set(:@body, "a"*50)
|
67
|
+
@request.store_progress(uuid)
|
68
|
+
assert_equal Thin::Server::progress[uuid], 50
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_progress_is_returned_on_parse_finish
|
72
|
+
Thin::Server::progress['my_id'] = 45
|
73
|
+
assert @request.finished?
|
74
|
+
@request.store_progress(uuid)
|
75
|
+
assert_equal @request.env[Thin::Request::RACK_PROGRESS]['my_id'], 45
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_progress_is_deleted_when_it_was_finished_and_requested
|
79
|
+
Thin::Server::progress[uuid] = 100
|
80
|
+
assert @request.parse post_request("uuid=#{uuid} ")
|
81
|
+
assert_equal @request.env[Thin::Request::RACK_PROGRESS][uuid], 100
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_progress_is_returned_when_its_finished_and_not_was_requested_yet
|
85
|
+
Thin::Server::progress[uuid] = 100
|
86
|
+
@request = Thin::Request.new
|
87
|
+
assert @request.parse(get_request("/progress?uuid=#{uuid}"))
|
88
|
+
assert_equal Thin::Server::progress.has_key?(uuid), false
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/thin_upload.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{thin_upload}
|
5
|
+
s.version = "0.0.1.pre1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = [%q{Dombi Attila}]
|
9
|
+
s.date = %q{2011-10-19}
|
10
|
+
s.description = %q{thin_upload provides upload progress measuring functionality for thin ruby server, progresses can be accessed via rack middleware.}
|
11
|
+
s.email = %q{dombesz.attila-at-gmail.com}
|
12
|
+
s.extra_rdoc_files = [%q{README.rdoc}, %q{lib/thin_upload.rb}, %q{lib/thin_upload/request.rb}]
|
13
|
+
s.files = [%q{Gemfile}, %q{Gemfile.lock}, %q{Manifest}, %q{README.rdoc}, %q{Rakefile}, %q{html/README_rdoc.html}, %q{html/Thin.html}, %q{html/Thin/Request.html}, %q{html/Thin/Server.html}, %q{html/created.rid}, %q{html/images/brick.png}, %q{html/images/brick_link.png}, %q{html/images/bug.png}, %q{html/images/bullet_black.png}, %q{html/images/bullet_toggle_minus.png}, %q{html/images/bullet_toggle_plus.png}, %q{html/images/date.png}, %q{html/images/find.png}, %q{html/images/loadingAnimation.gif}, %q{html/images/macFFBgHack.png}, %q{html/images/package.png}, %q{html/images/page_green.png}, %q{html/images/page_white_text.png}, %q{html/images/page_white_width.png}, %q{html/images/plugin.png}, %q{html/images/ruby.png}, %q{html/images/tag_green.png}, %q{html/images/wrench.png}, %q{html/images/wrench_orange.png}, %q{html/images/zoom.png}, %q{html/index.html}, %q{html/js/darkfish.js}, %q{html/js/jquery.js}, %q{html/js/quicksearch.js}, %q{html/js/thickbox-compressed.js}, %q{html/lib/thin_upload/parser_rb.html}, %q{html/lib/thin_upload/request_rb.html}, %q{html/lib/thin_upload_rb.html}, %q{html/rdoc.css}, %q{lib/thin_upload.rb}, %q{lib/thin_upload/request.rb}, %q{test/test_helper.rb}, %q{test/thin_upload/request_test.rb}, %q{thin_upload.gemspec}]
|
14
|
+
s.homepage = %q{https://github.com/dombesz/thin_upload}
|
15
|
+
s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Thin_upload}, %q{--main}, %q{README.rdoc}]
|
16
|
+
s.require_paths = [%q{lib}]
|
17
|
+
s.rubyforge_project = %q{thin_upload}
|
18
|
+
s.rubygems_version = %q{1.8.8}
|
19
|
+
s.summary = %q{Upload progress meter for thin ruby server.}
|
20
|
+
s.test_files = [%q{test/test_helper.rb}, %q{test/thin_upload/request_test.rb}]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<thin>, [">= 0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<thin>, [">= 0"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<thin>, [">= 0"])
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thin_upload
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre1
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dombi Attila
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-19 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thin
|
16
|
+
requirement: &2162587720 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2162587720
|
25
|
+
description: thin_upload provides upload progress measuring functionality for thin
|
26
|
+
ruby server, progresses can be accessed via rack middleware.
|
27
|
+
email: dombesz.attila-at-gmail.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README.rdoc
|
32
|
+
- lib/thin_upload.rb
|
33
|
+
- lib/thin_upload/request.rb
|
34
|
+
files:
|
35
|
+
- Gemfile
|
36
|
+
- Gemfile.lock
|
37
|
+
- Manifest
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- html/README_rdoc.html
|
41
|
+
- html/Thin.html
|
42
|
+
- html/Thin/Request.html
|
43
|
+
- html/Thin/Server.html
|
44
|
+
- html/created.rid
|
45
|
+
- html/images/brick.png
|
46
|
+
- html/images/brick_link.png
|
47
|
+
- html/images/bug.png
|
48
|
+
- html/images/bullet_black.png
|
49
|
+
- html/images/bullet_toggle_minus.png
|
50
|
+
- html/images/bullet_toggle_plus.png
|
51
|
+
- html/images/date.png
|
52
|
+
- html/images/find.png
|
53
|
+
- html/images/loadingAnimation.gif
|
54
|
+
- html/images/macFFBgHack.png
|
55
|
+
- html/images/package.png
|
56
|
+
- html/images/page_green.png
|
57
|
+
- html/images/page_white_text.png
|
58
|
+
- html/images/page_white_width.png
|
59
|
+
- html/images/plugin.png
|
60
|
+
- html/images/ruby.png
|
61
|
+
- html/images/tag_green.png
|
62
|
+
- html/images/wrench.png
|
63
|
+
- html/images/wrench_orange.png
|
64
|
+
- html/images/zoom.png
|
65
|
+
- html/index.html
|
66
|
+
- html/js/darkfish.js
|
67
|
+
- html/js/jquery.js
|
68
|
+
- html/js/quicksearch.js
|
69
|
+
- html/js/thickbox-compressed.js
|
70
|
+
- html/lib/thin_upload/parser_rb.html
|
71
|
+
- html/lib/thin_upload/request_rb.html
|
72
|
+
- html/lib/thin_upload_rb.html
|
73
|
+
- html/rdoc.css
|
74
|
+
- lib/thin_upload.rb
|
75
|
+
- lib/thin_upload/request.rb
|
76
|
+
- test/test_helper.rb
|
77
|
+
- test/thin_upload/request_test.rb
|
78
|
+
- thin_upload.gemspec
|
79
|
+
homepage: https://github.com/dombesz/thin_upload
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --line-numbers
|
84
|
+
- --inline-source
|
85
|
+
- --title
|
86
|
+
- Thin_upload
|
87
|
+
- --main
|
88
|
+
- README.rdoc
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1.2'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project: thin_upload
|
105
|
+
rubygems_version: 1.8.8
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: Upload progress meter for thin ruby server.
|
109
|
+
test_files:
|
110
|
+
- test/test_helper.rb
|
111
|
+
- test/thin_upload/request_test.rb
|