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 +4 -4
- data/README.md +16 -2
- data/config.ru +1 -0
- data/lib/attache.rb +3 -0
- data/lib/attache/upload.rb +1 -1
- data/lib/attache/upload_url.rb +67 -0
- data/lib/attache/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 228685a6b1038b73b233cf5165570252f271f447
|
4
|
+
data.tar.gz: df3611d3b73a8c2120b9fda08fab214bfaa55ecb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/lib/attache.rb
CHANGED
@@ -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'
|
data/lib/attache/upload.rb
CHANGED
@@ -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.
|
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
|
data/lib/attache/version.rb
CHANGED
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.
|
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-
|
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
|