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.
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,3 @@
1
+ module RFFW
2
+ VERSION = "0.0.1"
3
+ end
data/rffw.db ADDED
Binary file
data/rffw.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rffw/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rffw"
7
+ s.version = RFFW::VERSION
8
+ s.authors = ["Guillermo Álvarez"]
9
+ s.email = ["guillermo@cientifico.net"]
10
+ s.homepage = ""
11
+ s.summary = %q{Recive files from webserver}
12
+ s.description = %q{A simple program that listen at port 80 for uploads, and save the uploaded files to disk}
13
+
14
+ s.rubyforge_project = "rffw"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,14 @@
1
+ POST /description HTTP/1.1
2
+ Host: localhost:8080
3
+ Origin: http://localhost:8080
4
+ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50
5
+ Content-Type: application/x-www-form-urlencoded
6
+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7
+ Referer: http://localhost:8080/
8
+ Accept-Language: en-us
9
+ Accept-Encoding: gzip, deflate
10
+ Cookie: __utmz=111872281.1311554639.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=111872281.2010257729.1311554639.1312453997.1312460077.19
11
+ Content-Length: 16
12
+ Connection: keep-alive
13
+
14
+ description=hola
@@ -0,0 +1,8 @@
1
+ GET / HTTP/1.1
2
+ Host: localhost:9999
3
+ User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
4
+ Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
5
+ Accept-Language: en-us
6
+ Accept-Encoding: gzip, deflate
7
+ Connection: keep-alive
8
+
@@ -0,0 +1,9 @@
1
+ GET / HTTP/1.1
2
+ Host: localhost:8081
3
+ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50
4
+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5
+ Accept-Language: en-us
6
+ Accept-Encoding: gzip, deflate
7
+ Cookie: __utmz=111872281.1311554639.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=111872281.2010257729.1311554639.1312453997.1312460077.19
8
+ Connection: keep-alive
9
+
Binary file
@@ -0,0 +1,10 @@
1
+ GET /upload_status.js?81242840-2736-2e05-7316-1c1ee25f7cff HTTP/1.1
2
+ Host: localhost:8080
3
+ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50
4
+ Accept: */*
5
+ Referer: http://localhost:8080/
6
+ Accept-Language: en-us
7
+ Accept-Encoding: gzip, deflate
8
+ Cookie: __utmz=111872281.1311554639.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=111872281.2010257729.1311554639.1312453997.1312460077.19
9
+ Connection: keep-alive
10
+
data/test/helper.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'minitest/unit'
2
+ require 'minitest/mock'
3
+ require 'rffw'
4
+ require 'stringio'
5
+ require 'tmpdir'
6
+
7
+ class MiniTest::Unit::TestCase
8
+
9
+ def fixture(name)
10
+ File.expand_path("../fixtures/#{name}", __FILE__)
11
+ end
12
+
13
+ def read(name)
14
+ File.read(fixture(name))
15
+ end
16
+
17
+ end
18
+
19
+
20
+ class IntegrationTest < MiniTest::Unit::TestCase
21
+
22
+ def setup
23
+ @port = 64444
24
+ @server_pid = fork do
25
+ $stdout = File.open("/dev/null",'w')
26
+ $stderr = $stdout
27
+ RFFW::App.start(@port,"127.0.0.1", Dir.mktmpdir("rffw_test"))
28
+ exit(0)
29
+ end
30
+ sleep 0.1
31
+ end
32
+
33
+ def teardown
34
+ Process.kill('SIGINT', @server_pid)
35
+ Process.wait(@server_pid)
36
+ end
37
+
38
+
39
+
40
+ def upload_file(name)
41
+ Fiber.new do
42
+ fixture = read(name)
43
+ socket = TCPSocket.new('127.0.0.1', @port)
44
+ socket.write fixture[0..(fixture.size/3)]
45
+ Fiber.yield
46
+
47
+ socket.write fixture[(fixture.size/3)..(fixture.size/3*2)]
48
+ Fiber.yield
49
+
50
+ socket.write fixture[(fixture.size/3*2)..-1]
51
+ Fiber.yield
52
+
53
+ begin
54
+ data = socket.read_nonblock(1024*1024*1024)
55
+ rescue Errno::EAGAIN
56
+ retry
57
+ end
58
+
59
+ Fiber.yield data
60
+ end
61
+ end
62
+
63
+ def send_request(name)
64
+ socket = TCPSocket.new('127.0.0.1', @port)
65
+ socket.write read(name)
66
+ begin
67
+ content = socket.read_nonblock(1024*1024*1024).tap{ socket.close }.split("\r\n").last.strip
68
+ rescue EOFError,Errno::EAGAIN
69
+ retry
70
+ end
71
+ end
72
+
73
+ def upload_file(name)
74
+ Fiber.new do
75
+ fixture = read(name)
76
+ socket = TCPSocket.new('127.0.0.1', @port)
77
+ socket.write fixture[0..(fixture.size/3)]
78
+ Fiber.yield
79
+
80
+ socket.write fixture[(fixture.size/3)..(fixture.size/3*2)]
81
+ Fiber.yield
82
+
83
+ socket.write fixture[(fixture.size/3*2)..-1]
84
+ Fiber.yield
85
+
86
+ data = nil
87
+ while(data == nil)
88
+ data = socket.read_nonblock(1000000) rescue nil
89
+ end
90
+ data
91
+
92
+ Fiber.yield data
93
+ end
94
+ end
95
+
96
+
97
+ end
@@ -0,0 +1,50 @@
1
+ require 'helper'
2
+
3
+ class RFFW::Server::BufferedClientTest < MiniTest::Unit::TestCase
4
+ include RFFW::Server
5
+ def setup
6
+ @socket = StringIO.new
7
+ @client = BufferedClient.new(@socket)
8
+ def @client.read_nonblock(arg) ; "h"*1000 end
9
+ def @client.close ; end
10
+ end
11
+
12
+ def teardown
13
+ BufferedClient.disconnect_all!
14
+ end
15
+
16
+ def test_on_small_data
17
+ @client.on_data
18
+ assert_equal "h"*1000, @client.buffer
19
+ assert !@client.usign_temp_file?
20
+ end
21
+
22
+ def test_on_data
23
+ def @client.read_nonblock(arg) ; "h"*2000 end
24
+ @client.on_data
25
+ assert_equal "h"*2000, @client.buffer
26
+ assert @client.usign_temp_file?
27
+ end
28
+
29
+ def test_on_data_appending
30
+ @client.on_data
31
+ assert !@client.usign_temp_file?
32
+ @client.on_data
33
+ assert @client.usign_temp_file?
34
+ assert_equal "h"*2000, @client.buffer
35
+ end
36
+
37
+ def test_clear_buffer
38
+ @client.on_data
39
+ @client.clear_buffer
40
+ assert_equal '', @client.buffer
41
+ end
42
+
43
+ def test_remove_file_on_clear_buffer
44
+ @client.on_data
45
+ @client.clear_buffer
46
+ assert !@client.usign_temp_file?
47
+ end
48
+
49
+
50
+ end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ class RFFW::Server::ClientTest < MiniTest::Unit::TestCase
4
+ include RFFW::Server
5
+
6
+ def setup
7
+ @socket = StringIO.new
8
+ def @socket.close; nil end
9
+ end
10
+
11
+ def teardown
12
+ Client.disconnect_all!
13
+ end
14
+
15
+ def test_initialize
16
+ client = Client.new(@socket)
17
+ assert client.instance_of?(Client)
18
+ end
19
+
20
+ def test_find
21
+ client = Client.new(@socket)
22
+ assert_equal Client.find(client), client
23
+ end
24
+
25
+ def test_is_enumerable
26
+ assert Client.singleton_class.included_modules.include?(Enumerable)
27
+ end
28
+
29
+ def test_each
30
+ expected = [Client.new(@socket), Client.new(@socket)]
31
+ result = []
32
+ Client.each{|c| result << c }
33
+ assert_equal expected, result
34
+ end
35
+
36
+ def test_all
37
+ expected = [Client.new(@socket), Client.new(@socket)]
38
+ assert_equal expected, Client.all
39
+ end
40
+
41
+ def test_on_disconnect
42
+ client = Client.new(@socket)
43
+ assert Client.all.any?
44
+ client.disconnect!
45
+ assert Client.all.empty?
46
+ end
47
+ end
data/test/test_db.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ class RFFW::App::DbTest < MiniTest::Unit::TestCase
4
+
5
+ include RFFW::App
6
+
7
+ def setup
8
+ Dir.chdir(Dir.mktmpdir("rffw-test")) do
9
+ @db = Db.new('test_db')
10
+ end
11
+ end
12
+
13
+
14
+ def test_get_set
15
+ assert_equal( {}, @db['12345'])
16
+ assert_equal( {:a => 3}, (@db['12345'] = {:a => 3}), 'should retun value on set')
17
+ assert_equal( {:a => 3}, @db['12345'], 'should return previous stored value on get')
18
+ end
19
+
20
+
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'helper'
2
+
3
+ class RFFW::Server::HttpClientTest < MiniTest::Unit::TestCase
4
+ include RFFW::Server
5
+
6
+ def setup
7
+ @mock_socket = MiniTest::Mock.new
8
+ @mock_socket.expect(:close, nil)
9
+ @mock_socket.expect(:read_nonblock, File.read(fixture('raw_request.txt')),[String])
10
+ @mock_socket.expect(:closed?, nil)
11
+ @mock_socket.expect(:write, nil,[String])
12
+ end
13
+
14
+ def teardown
15
+ HttpClient.disconnect_all!
16
+ end
17
+
18
+ def test_request
19
+ client = HttpClient.new(@mock_socket)
20
+ def client.buffer; File.read(File.expand_path("../fixtures/raw_request.txt",__FILE__)) ; end
21
+ client.on_data
22
+ assert File.read(fixture("raw_request.txt")), client.on_data
23
+ end
24
+
25
+
26
+ end
@@ -0,0 +1,52 @@
1
+ require 'helper'
2
+
3
+ class RFFW::Server::HttpRequestTest < MiniTest::Unit::TestCase
4
+
5
+ include RFFW::Parser
6
+
7
+ def setup
8
+ @simple_request = File.read(File.expand_path("../fixtures/raw_request.txt",__FILE__))
9
+ @request_headers = {"HTTP_METHOD"=>"GET",
10
+ "HTTP_PATH"=>"/",
11
+ "HTTP_VERSION"=>"1.1",
12
+ "Host"=>"localhost:9999",
13
+ "User-Agent"=>
14
+ "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1",
15
+ "Accept"=>
16
+ "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
17
+ "Accept-Language"=>"en-us",
18
+ "Accept-Encoding"=>"gzip, deflate",
19
+ "Connection"=>"keep-alive"}
20
+ end
21
+
22
+ def test_parse_simple_request
23
+ request = HttpRequest.new(@simple_request.dup)
24
+ assert request.headers.is_a?(Hash), "headers should be a hash"
25
+ assert request.body.is_a?(String), "body should be a string"
26
+ assert request.finish?, "request should be finished"
27
+ assert_equal(@request_headers, request.headers)
28
+ %w(attachments upload_content_lenght body_size upload_progress).each do |method|
29
+ assert_raises(HttpRequest::OnlyForPosts, "#{method} should raise exception for get requests.") { request.send(method.to_sym) }
30
+ end
31
+
32
+ assert_equal "1.1", request.version
33
+ assert_equal "/", request.path
34
+ assert_equal true, request.keep_alive?
35
+ assert_equal "GET", request.method
36
+ assert_equal '', request.query
37
+ assert_equal '/', request.url
38
+ assert_kind_of URI, request.uri
39
+ end
40
+
41
+ def test_incomplete_request
42
+ raw_request = @simple_request[0..(@simple_request.size/2)]
43
+ request = HttpRequest.new(raw_request)
44
+ assert !request.finish?
45
+ end
46
+
47
+ def test_post_form_data
48
+ request = HttpRequest.new(read('post_form_data.http'))
49
+ assert_equal( {"description"=>"hola"}, request.post_form_data)
50
+
51
+ end
52
+ end
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+
3
+ class RFFW::Server::MimeTest < MiniTest::Unit::TestCase
4
+ include RFFW::Parser
5
+
6
+ def setup
7
+ @data = File.read(File.expand_path('../fixtures/mime_image.data', __FILE__))
8
+ @image_data = File.read(File.expand_path('../fixtures/mime_image.png', __FILE__)).force_encoding("BINARY")
9
+ end
10
+
11
+ def test_mime_parser
12
+ attachments = MimeParser.parse(@data)
13
+ attachment = attachments.first
14
+ expected_header = "form-data; name=\"file\"; filename=\"Screen shot 2011-08-05 at 5.42.34 AM.png\""
15
+ image_type = "image/png"
16
+
17
+ assert_equal 1, attachments.size
18
+ assert_equal expected_header, attachment.content_disposition
19
+ assert_equal image_type, attachment.content_type
20
+ assert_equal @image_data, attachment.to_s, "to be equal"
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ require 'helper'
2
+
3
+ class RecordTest < MiniTest::Unit::TestCase
4
+ include RFFW::App
5
+
6
+ def setup
7
+ RFFW::App.start_db(Dir.mktmpdir("rffw_test"))
8
+ end
9
+
10
+ def test_update_or_create_by_id_on_create
11
+ record = Record.update_or_create_by_id('1234', {"mime_type" => "text/plain", "filename" => "hello_world.txt"}, 'HOLA MUNDO')
12
+ assert_equal '1234', record.id
13
+ assert_equal 'text/plain', record.mime_type
14
+ assert_equal 'hello_world.txt', record.filename
15
+ assert_equal 'HOLA MUNDO', record.body
16
+ end
17
+
18
+
19
+
20
+ def test_update_or_create_by_id_on_update
21
+ record = Record.update_or_create_by_id('1234', {"mime_type" => "text/plain", "filename" => "hello_world.txt"}, 'HOLA MUNDO')
22
+ record = Record.update_or_create_by_id('1234', {"description" => "good file"})
23
+
24
+ assert_equal 'good file', record.description
25
+ assert_equal '1234', record.id
26
+ assert_equal 'text/plain', record.mime_type
27
+ assert_equal 'hello_world.txt', record.filename
28
+ assert_equal 'HOLA MUNDO', record.body
29
+ end
30
+
31
+ def test_find_by_id
32
+ record = Record.update_or_create_by_id('1234', {"mime_type" => "text/plain", "filename" => "hello_world.txt"}, 'HOLA MUNDO')
33
+
34
+ record = Record.find_by_id('1234')
35
+ assert_equal nil, record.description
36
+ assert_equal '1234', record.id
37
+ assert_equal 'text/plain', record.mime_type
38
+ assert_equal 'hello_world.txt', record.filename
39
+ assert_equal 'HOLA MUNDO', record.body
40
+ end
41
+
42
+ def test_new
43
+ record = Record.new('123', {'asdf' => 3})
44
+ assert record.new?, "should be new"
45
+
46
+ record = Record.update_or_create_by_id('890123', {'asdf' => 3})
47
+ assert !record.new?, "should not be new on existing record"
48
+ end
49
+ end