class Attache::UploadUrl
Constants
- MAX_DEPTH
Public Class Methods
new(app)
click to toggle source
# File lib/attache/upload_url.rb, line 2 def initialize(app) @app = app end
Public Instance Methods
_call(env, config)
click to toggle source
# File lib/attache/upload_url.rb, line 6 def _call(env, config) case env['PATH_INFO'] when '/upload_url' # always pretend to be `POST /upload` env['PATH_INFO'] = '/upload' env['REQUEST_METHOD'] = 'POST' request = Rack::Request.new(env) params = request.params return config.unauthorized unless config.authorized?(params) if params['url'] file, filename, content_type = download_file(params['url']) filename = "index" if filename == '/' env['CONTENT_TYPE'] = content_type || content_type_of(file.path) env['rack.request.query_hash'] = (env['rack.request.query_hash'] || {}).merge('file' => filename) env['rack.input'] = file end end @app.call(env) end
download_file(url, depth = 0)
click to toggle source
# File lib/attache/upload_url.rb, line 31 def download_file(url, depth = 0) raise Net::HTTPError, "Too many redirects" if depth > MAX_DEPTH Attache.logger.info "Upload GET #{url}" if url.match /\Adata:([^;,]+|)(;base64|),/ # data:[<mediatype>][;base64],<data> # http://tools.ietf.org/html/rfc2397 data = URI.decode(url[url.index(',')+1..-1]) data = Base64.decode64(data) if $2 == ';base64' content_type = ($1 == '' ? "text/plain" : $1) filename = "data.#{content_type.gsub(/\W+/, '.')}" return [StringIO.new(data), filename, content_type] end uri = uri.kind_of?(URI::Generic) ? url : URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' req = Net::HTTP::Get.new(uri.request_uri) req.initialize_http_header({"User-Agent" => ENV['USER_AGENT']}) if ENV['USER_AGENT'] req.basic_auth(uri.user, uri.password) if uri.user || uri.password res = http.request(req) case res.code when /\A30[1,2]\z/ download_file URI.join(url, res['Location']).to_s, depth + 1 when /\A2\d\d\z/ f = Tempfile.new(["upload_url", File.extname(uri.path)]) f.write(res.body) f.close [f.tap(&:open), File.basename(uri.path)] else raise Net::HTTPError, "Failed #{res.code}" end end