2015-11-29 37 views
0

我正在嘗試使用CGI和分塊編碼(「Transfer-Encoding:chunked」HTTP標頭字段)。這種方式可以在沒有內容長度標頭的情況下發送文件。我在Ruby中編寫了一個簡約的CGI應用程序,試用它。我的代碼如下(chunked.rb):cURL:在分塊編碼中發現格式不正確,爲什麼?

#!/usr/bin/ruby 

puts "Date: Fri, 28 Nov 2015 09:59:59 GMT" 
puts "Content-Type: application/octet-stream; charset=\"ASCII-8BIT\"" 
puts "Content-Disposition: attachment; filename=image.jpg" 
puts "Transfer-Encoding: chunked" 
puts 

File.open("image.jpg","rb"){|f| 
while data=f.read(32) 
    STDOUT.puts data.size.to_s(16) 
    STDOUT.puts data 
end 
STDOUT.puts "0" 
STDOUT.puts 
} 

我把這個想法和分塊從這裏格式例如:​​

HTTP/1.1 200 OK 
Date: Fri, 31 Dec 1999 23:59:59 GMT 
Content-Type: text/plain 
Transfer-Encoding: chunked 

1a; ignore-stuff-here 
abcdefghijklmnopqrstuvwxyz 
10 
1234567890abcdef 
0 
some-footer: some-value 
another-footer: another-value 
[blank line here] 

正如我的CGI應用程序駐留在Apache的cgi-bin目錄,我可以發出捲曲:

curl http://example.com/cgi-bin/chunked.rb -O -J 

捲曲應reassamble從塊的原始文件image.jpg的,但不幸的是已保存的文件不完整,它比原來的小,我得到一個埃羅從捲曲太[R消息:

curl: (56) Malformed encoding found in chunked-encoding 

但是當我改變行data=f.read(32)喜歡的東西data=f.read(1024*50),然後文件正確保存。使用另一個來自服務器的更大文件使得CGI應用程序再次失效,我再次收到相同的錯誤消息。我能做些什麼來使我的CGI應用程序正常工作,並正確發送文件?

+1

長度和數據之後,隔板應該是一個'CRLF'(\ r \ n)中。 'puts'只是附加一個'LF'(\ n),這可能是問題所在。如果在每個長度和數據塊之後放置'\ r \ n',它會起作用嗎? – drew010

+0

實際上它也應該工作「\ r \ n」和「\ n」。但問題解決了,這是一個Ruby「陷阱」。而不是「STDOUT.puts數據」 我不得不使用「STDOUT.print數據」,然後是「puts」。這是因爲當數據意外地以「\ n」結尾時,ruby不會添加額外的「\ n」。有時會發生這種情況,當塊大小干擾二進制文件中的「\ n」字節時。 – Konstantin

+0

很高興讓你在正確的道路上 - 好工作讓它工作。 – drew010

回答

2

所以工作實例:

puts "Date: Fri, 28 Nov 2015 09:59:59 GMT" 
    puts "Content-Type: application/octet-stream; charset=\"ASCII-8BIT\"" 
    puts "Content-Disposition: attachment; filename=image.jpg" 
    puts "Transfer-Encoding: chunked" 
    puts 

    File.open("image.jpg","rb"){|f| 
    while data=f.read(32) 
     STDOUT.puts data.size.to_s(16) 
     STDOUT.print data 
     STDOUT.puts 
    end 
    STDOUT.puts "0" 
    STDOUT.puts 
    } 
相關問題