2011-02-01 15 views
5

Supponiamo che io voglio usare curl per mettere un file ad un webservice questo modoSinatra e http PUT

curl -v --location --upload-file file.txt http://localhost:4567/upload/filename 

a Sinatra che posso fare:

#!/usr/bin/env ruby 

require 'rubygems' 
require 'sinatra' 

put '/upload/:id' do 
    # 
    # tbd 
    # 
end 

Come posso leggere il file di flusso?

più o meno voglio qualcosa di simile: http://www.php.net/manual/en/features.file-upload.put-method.php#56985

+0

[Questa domanda] (http://stackoverflow.com/questions/4795205/streaming-web-uploads-to-socket-with-rack) implica che ciò che si desidera non può essere fatto, ma non lo so ancora abbastanza per essere abbastanza sicuro da postarlo come risposta. – Phrogz

+0

@Phrogz Ho appena trovato questo: http://groups.google.com/group/rack-devel/msg/600825afa08474d8 - ho pensato che potresti essere interessato. – matt

risposta

4

L'esempio più semplice è la scrittura nella directory currect si esegue Sinatra con alcun controllo per i file esistenti ... basta sovrascrivere.

#!/usr/bin/env ruby 

require 'rubygems' 
require 'sinatra' 

put '/upload/:id' do 
    File.open(params[:id], 'w+') do |file| 
    file.write(request.body.read) 
    end 
end 

Inoltre, è possibile lasciare la porzione nome del file nel comando ricciolo e sarà compilarlo per voi con il nome del file. Foe esempio:

curl -v --location --upload-file file.txt http://localhost:4567/upload/ 

si tradurrà in scrittura del file di http://localhost:4567/upload/file.txt

+0

Il blocco di instradamento attende di essere eseguito fino al termine della richiesta o consente di trasmettere i risultati non appena arrivano? – Phrogz

+0

Non so dello streaming ... Ho perso quel dettaglio – Ben

2
require 'rubygems' 
require 'sinatra' 
require 'ftools' 

put '/upload' do 
    tempfile = params['file'][:tempfile] 
    filename = params['file'][:filename] 
    File.mv(tempfile.path,File.join(File.expand_path(File.dirname(File.dirname(__FILE__))),"public","#{filename}")) 
    redirect '/' 
end 

In questo modo, non deve preoccuparsi della dimensione del file, dal momento che non è aperto (readed) in memoria, ma appena spostato dalla directory temporanea alla posizione giusta, saltando un blocco cruciale. In effetti, il codice php fa la stessa cosa, legge il file in blocchi da 1k e lo memorizza in un nuovo file, ma poiché il file è lo stesso, è inutile. Per provare puoi seguire la risposta di Ben.

Problemi correlati