modporter-plugin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/mod_porter.rb +99 -0
  2. metadata +47 -0
data/lib/mod_porter.rb ADDED
@@ -0,0 +1,99 @@
1
+ require 'strscan'
2
+
3
+ module ModPorter
4
+ class InvalidSignature < StandardError
5
+ end
6
+
7
+ class UnknownError < StandardError
8
+ end
9
+
10
+ class UploadedFile
11
+ attr_accessor :path, :content_type, :original_filename
12
+
13
+ def initialize(options)
14
+ @path = options[:path]
15
+ @original_filename = options[:filename]
16
+ @content_type = options[:content_type]
17
+ end
18
+
19
+ def to_tempfile
20
+ return File.new(self.path)
21
+ end
22
+
23
+ def size
24
+ File.size(self.path)
25
+ end
26
+ end
27
+
28
+ module ClassMethods
29
+ def porter_secret(val)
30
+ self.mod_porter_secret = val
31
+ end
32
+ end
33
+
34
+ module Filter
35
+ def self.included(base)
36
+ base.superclass_delegating_accessor :mod_porter_secret
37
+ base.before_filter :normalize_mod_porters
38
+ base.extend ModPorter::ClassMethods
39
+ end
40
+
41
+ def normalize_mod_porters
42
+ x_uploads_header = request.headers["X-Uploads"] || request.headers["HTTP_X_UPLOADS"]
43
+ return if x_uploads_header.blank?
44
+
45
+ porter_params = x_uploads_header.split(",").uniq
46
+ logger.info("Processing #{porter_params.inspect}")
47
+
48
+ porter_params.each do |file_param|
49
+ s = StringScanner.new(file_param)
50
+
51
+ path = []
52
+ path << s.scan(/\w+/).to_sym
53
+
54
+ while !s.eos?
55
+ if arr = s.scan(/\[\]/)
56
+ path << [] # We have an array
57
+ elsif key = s.scan(/\[(\w+)\]/)
58
+ path << s[1].to_sym
59
+ else
60
+ raise ModPorter::UnknownError.new("Something went wrong when scaling the file uploads")
61
+ end
62
+ end
63
+
64
+ last = path.pop
65
+
66
+ h = path.inject(params) do |hash, value|
67
+ if value.is_a?(Array)
68
+ hash
69
+ else
70
+ hash[value]
71
+ end
72
+ end
73
+
74
+ if last.is_a?(Array)
75
+ h.map! do |e|
76
+ check_signature!(e)
77
+ UploadedFile.new(e)
78
+ end
79
+ else
80
+ while h.is_a?(Array)
81
+ h = h.first # WTF. file[][some1], file[][some2]. Maybe this work.
82
+ end
83
+
84
+ check_signature!(h[last])
85
+ h[last] = UploadedFile.new(h[last])
86
+ end
87
+ end
88
+ end
89
+
90
+ def check_signature!(options)
91
+ expected_digest = Digest::SHA1.digest("#{options[:path]}#{self.class.mod_porter_secret}")
92
+ base64_encoded_digest = ActiveSupport::Base64.encode64(expected_digest).chomp
93
+
94
+ if options[:signature] != base64_encoded_digest
95
+ raise ModPorter::InvalidSignature.new("#{options[:signature]} != #{base64_encoded_digest}")
96
+ end
97
+ end
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: modporter-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Koziarski
9
+ - Pratik Naik
10
+ - Kun Xi
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2011-05-22 00:00:00.000000000 Z
15
+ dependencies: []
16
+ description: Rails plugin for ModPorter.
17
+ email: kunxi@kunxi.org
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/mod_porter.rb
23
+ homepage: http://rubygems.org/gems/modporter-plugin
24
+ licenses: []
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 1.8.10
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: Rails plugin for ModPorter.
47
+ test_files: []