Pobieraj?c je i sprawdzaj?c rozmiar pobranego pliku - to jedyny pewny sposób. Opcjonalnie, je?li w odpowiedzi zostanie wys?any nag?ówek Content-length oraz je?li dane nie s? kompresowane oraz je?li dane nie s? wysy?ane fragmentami (nag?ówek Transfer-encoding ustawiony na chunked), to mo?na przyj??, ?e Content-length wskazuje rozmiar pobieranego zasobu. Mam nadziej?, ?e niczego nie pomin??em (HTTP jest dosy? obszernym standardem, a ja nie mam g?owy z gumy). Podobnie jak w pierwszym przypadku mo?na spróbowa? przez HEAD, je?li serwer obs?uguje.
Generalnie nie polecam robi? tego r?cznie. Je?li mimo wszystko masz zamiar, to przeanalizuj, jak robi? to istniej?ce narz?dzia.
edit:
Przyk?ady. Do testów u?yj? sobie takiego, 122-bajtowego pliku:$ cat /dev/urandom | head -c 90 | base64 | tee test.txt
cg03NbiQ+MrTlfxsr5udrR0iHIrI2ps6VQY+f6E0VroJ72OpM0o3Xa6ZN8IxBPssv+rMNp0jWRFh
IzPnTAIZ635mn19w5tqsMN3aSeigwjnNLaR3M2g0xBpw
$ scp -P 59184 test.txt ciach@s19.vdl.pl:public_html/pub
Host key fingerprint is SHA256:k5EOPPoL3Gstn4Ldq0vJVdv7dNO+wFb3mUHz6UKqNXM
+---[ECDSA 256]---+
| |
| . . |
| + o . o |
| . + + o . +|
| . S . .. +o|
| . + o . +.o B|
| oo*o =.E.=+|
| .o=oo.o =ooo.|
| .=*+o ..o|
+----[SHA256]-----+
ciach@s19.vdl.pl's password:
test.txt 100% 122 2.0KB/s 00:00
$ curl http://www.coderscity.pl/pub/test.txt
cg03NbiQ+MrTlfxsr5udrR0iHIrI2ps6VQY+f6E0VroJ72OpM0o3Xa6ZN8IxBPssv+rMNp0jWRFh
IzPnTAIZ635mn19w5tqsMN3aSeigwjnNLaR3M2g0xBpw
Próbujemy, czy obs?uguje HEAD:ncat www.coderscity.pl 80 <<EOD
> OPTIONS * HTTP/1.1
> Host: www.coderscity.pl
>
> EOD
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2017 22:44:24 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain
Có?... nie obs?uguje globalnie OPTIONS ;). Ale mo?emy spróbowa? jeszcze na samym zasobie docelowym:$ ncat www.coderscity.pl 80 <<EOD
> OPTIONS /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
>
> EOD
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2017 22:46:05 GMT
Server: Apache
Allow: GET,HEAD,POST,OPTIONS
Vary: Accept-Encoding,User-Agent
Content-Length: 0
Content-Type: text/plain
No to wiemy, ?e HEAD jest obs?ugiwane. Zatem u?yjmy:$ ncat www.coderscity.pl 80 <<EOD
> HEAD /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
>
> EOD
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2017 22:21:49 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Content-Length: 122
Vary: Accept-Encoding,User-Agent
Content-Type: text/plain
Dowiedzieli?my si? niechc?cy, ?e ma mo?liwo?? obs?ugi pobierania odpowiedzi po kawa?ku: nag?ówek Accept-Ranges. Ale nie ka?dy serwer jest tak uczynny, ?e nie proszony podaje tak? informacj? - czasami wi?c mo?e by? potrzebne zapytanie wprost, wysy?aj?c nag?ówek Range bez ?adnych parametrów:$ ncat www.coderscity.pl 80 <<EOD
> HEAD /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
> Range:
>
> EOD
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2017 22:23:36 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Content-Length: 122
Vary: Accept-Encoding,User-Agent
Content-Type: text/plain
Gdyby serwer nie obs?ugiwa? HEAD, trzeba u?y? GET. Tutaj oczywi?cie powstaje k?opot, bo je?eli u?yjemy GET, to dostaniemy ca?? odpowied?, czyli mijamy si? z celem. Je?li jednak chcemy wykona? wiele zapyta? do ró?nych zasobów, to stosowna informacja dotycz?ca jednego z nich daje nadziej?, ?e dla innych jest podobnie. Ale tylko nadziej? - bo nie musi tak wcale by?. Przyk?adowo phpBB nie radzi sobie z Range i zawsze wysy?a ca?o??, st?d w pierwszym przyk?adzie by?o brak nag?ówka Accept-Ranges. Jedyna pewna metoda to wystartowanie na ?lepo z Range i zobaczenie, co si? stanie.
Pobranie fragmentu:$ ncat www.coderscity.pl 80 <<EOD
> GET /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
> Range: bytes=0-9
>
> EOD
HTTP/1.1 206 Partial Content
Date: Sun, 05 Feb 2017 22:28:41 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Content-Length: 10
Vary: Accept-Encoding,User-Agent
Content-Range: bytes 0-9/122
Content-Type: text/plain
cg03NbiQ+M
Nakazali?my pobranie bajtów 0-9 (pierwsze 10 bajtów). Otrzymali?my pierwsze 10 bajtów. Mo?emy te? pobra? ze ?rodka:$ ncat www.coderscity.pl 80 <<EOD
> GET /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
> Range: bytes=100-109
>
> EOD
HTTP/1.1 206 Partial Content
Date: Sun, 05 Feb 2017 22:30:41 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Content-Length: 10
Vary: Accept-Encoding,User-Agent
Content-Range: bytes 100-109/122
Content-Type: text/plain
aSeigwjnNL
Zwró? uwag? na to, ?e Content-range zawiera te? informacj? o rozmiarze ca?ej odpowiedzi.
I tutaj przechodzimy do ostatniego pytania: rozmiar pobieranego zasobu. W pierwszym zapytaniu, przez metod? HEAD, otrzymali?my Content-Length równy 122. Poniewa? reszta podanych wcze?niej warunków zosta?a spe?niona, to jest to d?ugo?? tego zasobu. Alternatywnie, je?li pobieramy tylko cz???, to Content-Range mo?e nam wskaza? pe?ny rozmiar. Ale to nie musi by? prawd?:$ ncat www.coderscity.pl 80 <<EOD
> GET /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
> Accept-Encoding: gzip, defalte
>
> EOD
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2017 22:33:55 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 139
Content-Type: text/plain
(... zgzipowane dane)
Mamy Content-Encoding równy "gzip". Content-Length wskazuje rozmiar przesy?anych danych, nie oryginalnej wiadomo?ci! St?d mamy 139 bajtów. I nie, Content-Range w niczym tutaj nie pomo?e:$ ncat www.coderscity.pl 80 <<EOD
> GET /pub/test.txt HTTP/1.1
> Host: www.coderscity.pl
> Accept-Encoding: gzip, deflate
> Range: bytes=100-109
>
> EOD
HTTP/1.1 206 Partial Content
Date: Sun, 05 Feb 2017 22:36:03 GMT
Server: Apache
Last-Modified: Sun, 05 Feb 2017 22:16:54 GMT
Accept-Ranges: bytes
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Range: bytes 100-109/139
Content-Length: 10
Content-Type: text/plain
(... zgzipowane dane)