attache 2.1.1 → 2.2.0
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.
- 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
|