attache 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1438a328d3cedfa04d52dcbe33d1b168be8ccd98
4
- data.tar.gz: 0676c54d6050a8280247fa4e48ade32ec749edaf
3
+ metadata.gz: 228685a6b1038b73b233cf5165570252f271f447
4
+ data.tar.gz: df3611d3b73a8c2120b9fda08fab214bfaa55ecb
5
5
  SHA512:
6
- metadata.gz: 25f7bdb0321d6850f7e42002fa54670654260f670023d3a119b587302f704efc303f2ef2c6ba8bcb852d77b7f35a66f11332b6fd2dc260940f94090ed25f523b
7
- data.tar.gz: bea5d1625b2235168897f5978de5fb1dbb62a5a9ec65af10a1264e7204c5397939b0d5447129ca2fff3b72e79c09956f90298f533c6815788f108cf97a007a32
6
+ metadata.gz: d8556bbf47617561a3bafd4bacb72ae3445e52357ee1acd5e5fd92473f4d1fbfe9336a86a3c6af30df01392a207a3be05881d88290c3cbf95dff3335dc515899
7
+ data.tar.gz: 71ec695990a228854eb3ba24fdcb5462f70b106670fa370d08d89584e04ae7e4ab8f9d5788cbf800f6d312a0fc6093bd8e82a86af27b8e8f605907de28199ee8
data/README.md CHANGED
@@ -67,7 +67,7 @@ NOTE: some config files will be written into your current directory (see RubyGem
67
67
 
68
68
  #### Source code
69
69
 
70
- You can checkout the source code and run it like a regular [a Procfile-based app](ddollar.github.io/foreman/)
70
+ You can checkout the source code and run it like a regular [a Procfile-based app](https://ddollar.github.io/foreman/):
71
71
 
72
72
  ```
73
73
  git clone https://github.com/choonkeat/attache.git
@@ -143,7 +143,11 @@ Users will upload files directly into the `attache` server from their browser, b
143
143
  > ```
144
144
  > PUT /upload?file=image123.jpg
145
145
  > ```
146
- > file content is the http request body
146
+ > file content is the http request body as raw binary (preferred) or encoded as base64 uri like this:
147
+ > ```
148
+ > PUT /upload?file=image123.jpg
149
+ > data:image/jpeg;base64,/9j/4QBiR....
150
+ > ```
147
151
 
148
152
  The main app front end will receive a unique `path` for each uploaded file - the only information to store in the main app database.
149
153
 
@@ -152,6 +156,16 @@ The main app front end will receive a unique `path` for each uploaded file - the
152
156
  > ```
153
157
  > json response from attache after upload.
154
158
 
159
+ ##### Upload by url
160
+
161
+ > ```
162
+ > GET /upload_url?url=https://example.com/logo.png
163
+ > ```
164
+
165
+ Attache will download the file from `url` supplied and uploads it through the regular `/upload` handler. So be expecting the same json response after upload. works with `GET`, `POST`, `PUT`.
166
+
167
+ Data URIs (aka base64 encoded file binaries) can also be uploaded to the same `/upload_url` endpoint through the same `url` parameter.
168
+
155
169
  #### Download
156
170
 
157
171
  Whenever the main app wants to display the uploaded file, constrained to a particular size, it will use a helper method provided by the `attache` lib. e.g. `embed_attache(path)` which will generate the necessary, barebones markup.
data/config.ru CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'attache'
2
2
 
3
3
  use Attache::Delete
4
+ use Attache::UploadUrl
4
5
  use Attache::Upload
5
6
  use Attache::Download
6
7
  use Attache::Tus::Upload
@@ -4,6 +4,8 @@ require 'securerandom'
4
4
  require 'disk_store'
5
5
  require 'fileutils'
6
6
  require 'paperclip'
7
+ require 'net/http'
8
+ require 'tempfile'
7
9
  require 'sidekiq'
8
10
  require 'tmpdir'
9
11
  require 'logger'
@@ -50,6 +52,7 @@ require 'attache/job'
50
52
  require 'attache/resize_job'
51
53
  require 'attache/base'
52
54
  require 'attache/vhost'
55
+ require 'attache/upload_url'
53
56
  require 'attache/upload'
54
57
  require 'attache/delete'
55
58
  require 'attache/backup'
@@ -9,7 +9,7 @@ class Attache::Upload < Attache::Base
9
9
  case env['REQUEST_METHOD']
10
10
  when 'POST', 'PUT', 'PATCH'
11
11
  request = Rack::Request.new(env)
12
- params = request.params
12
+ params = request.GET # stay away from parsing body
13
13
  return config.unauthorized unless config.authorized?(params)
14
14
 
15
15
  relpath = generate_relpath(Attache::Upload.sanitize params['file'])
@@ -0,0 +1,67 @@
1
+ class Attache::UploadUrl < Attache::Base
2
+ def initialize(app)
3
+ @app = app
4
+ end
5
+
6
+ def _call(env, config)
7
+ case env['PATH_INFO']
8
+ when '/upload_url'
9
+
10
+ # always pretend to be `POST /upload`
11
+ env['PATH_INFO'] = '/upload'
12
+ env['REQUEST_METHOD'] = 'POST'
13
+
14
+ request = Rack::Request.new(env)
15
+ params = request.params
16
+ return config.unauthorized unless config.authorized?(params)
17
+
18
+ if params['url']
19
+ file, filename, content_type = download_file(params['url'])
20
+ filename = "index" if filename == '/'
21
+
22
+ env['CONTENT_TYPE'] = content_type || content_type_of(file.path)
23
+ env['rack.request.query_hash'] = (env['rack.request.query_hash'] || {}).merge('file' => filename)
24
+ env['rack.input'] = file
25
+ end
26
+ end
27
+ @app.call(env)
28
+ end
29
+
30
+ MAX_DEPTH = 30
31
+ def download_file(url, depth = 0)
32
+ raise Net::HTTPError, "Too many redirects" if depth > MAX_DEPTH
33
+ Attache.logger.info "Upload GET #{url}"
34
+
35
+ if url.match /\Adata:([^;,]+|)(;base64|),/
36
+ # data:[<mediatype>][;base64],<data>
37
+ # http://tools.ietf.org/html/rfc2397
38
+
39
+ data = URI.decode(url[url.index(',')+1..-1])
40
+ data = Base64.decode64(data) if $2 == ';base64'
41
+ content_type = ($1 == '' ? "text/plain" : $1)
42
+ filename = "data.#{content_type.gsub(/\W+/, '.')}"
43
+ return [StringIO.new(data), filename, content_type]
44
+ end
45
+
46
+ uri = uri.kind_of?(URI::Generic) ? url : URI.parse(url)
47
+ http = Net::HTTP.new(uri.host, uri.port)
48
+ http.use_ssl = true if uri.scheme == 'https'
49
+ req = Net::HTTP::Get.new(uri.request_uri)
50
+ req.initialize_http_header({"User-Agent" => ENV['USER_AGENT']}) if ENV['USER_AGENT']
51
+ req.basic_auth(uri.user, uri.password) if uri.user || uri.password
52
+ res = http.request(req)
53
+ case res.code
54
+ when /\A30[1,2]\z/
55
+ download_file URI.join(url, res['Location']).to_s, depth + 1
56
+
57
+ when /\A2\d\d\z/
58
+ f = Tempfile.new(["upload_url", File.extname(uri.path)])
59
+ f.write(res.body)
60
+ f.close
61
+ [f.tap(&:open), File.basename(uri.path)]
62
+
63
+ else
64
+ raise Net::HTTPError, "Failed #{res.code}"
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module Attache
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attache
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - choonkeat
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-05 00:00:00.000000000 Z
11
+ date: 2016-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -275,6 +275,7 @@ files:
275
275
  - lib/attache/tus.rb
276
276
  - lib/attache/tus/upload.rb
277
277
  - lib/attache/upload.rb
278
+ - lib/attache/upload_url.rb
278
279
  - lib/attache/version.rb
279
280
  - lib/attache/vhost.rb
280
281
  - public/index.html