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,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