J'expérimente avec CGI et le codage chunked (champ d'en-tête HTTP "Transfer-Encoding: chunked"). De cette façon, les fichiers peuvent être envoyés sans en-tête de longueur de contenu. J'ai écrit une application CGI minimaliste dans Ruby, pour l'essayer. Mon code est le suivant (chunked.rb):cURL: encodage malformé trouvé dans l'encodage en bloc, pourquoi?
#!/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
}
Je pris l'idée et l'exemple de format CHUNKED d'ici: https://www.jmarshall.com/easy/http/
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]
Comme mon application CGI réside dans Apache répertoire cgi-bin, je peut émettre cURL:
curl http://example.com/cgi-bin/chunked.rb -O -J
cURL doit reassamble le fichier image.jpg d'origine des morceaux, mais malheureusement, le fichier enregistré est pas terminé, il est plus petit que l'original, et je reçois un Erro message r aussi de cURL:
curl: (56) Malformed encoding found in chunked-encoding
Cependant quand je change de ligne data=f.read(32)
à quelque chose comme data=f.read(1024*50)
, puis le fichier est enregistré correctement. L'utilisation d'un autre fichier plus gros du serveur rend l'application CGI inutilisable, j'ai encore reçu le même message d'erreur. Que puis-je faire pour que mon application CGI fonctionne et pour envoyer le fichier correctement?
Après la longueur et les données, le séparateur doit être un 'CRLF' (\ r \ n). 'puts' ajoute juste un' LF' (\ n), ce qui peut être le problème. Est-ce que cela fonctionne si vous mettez '\ r \ n' après chaque longueur et chaque segment de données? – drew010
En fait, il devrait fonctionner "\ r \ n" et "\ n" aussi. Mais problème résolu, c'est un "gotcha" Ruby. Au lieu de "STDOUT.puts data" J'ai dû utiliser "STDOUT.print data" suivi d'un "puts". C'est parce que lorsque les données se terminent accidentellement avec un "\ n", ruby n'ajoute pas de "\ n" supplémentaire. Et parfois cela arrive, quand la taille du morceau interfère avec "\ n" octets dans le fichier binaire. – Konstantin
Content que vous soyez sur la bonne voie - bon travail pour que ça marche. – drew010