Завить, играть и ожидать 100 продолжить заголовок
Рассмотрим веб-сервис, написанный в игре, за исключением запроса POST (для загрузки). Теперь, когда я тестировал это с изображением среднего размера (~75K), я обнаружил странное поведение. ну, код говорит яснее, чем длинные объяснения, поэтому:
$ curl -vX POST localhost:9000/path/to/upload/API -H "Content-Type: image/jpeg" -d @/path/to/mascot.jpg
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9000 (#0)
> POST /path/to/upload/API HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9000
> Accept: */*
> Content-Type: image/jpeg
> Content-Length: 27442
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Content-Length: 16
<
* Connection #0 to host localhost left intact
{"success":true}
как видите, curl решает добавить заголовок Content-Length: 27442
, но это неправда, реальный размер 75211, и в игре я действительно получил тело размером только 27442. грубо говоря, это не предполагаемое поведение. поэтому я попробовал другой инструмент, а не curl
Я использовал POST
инструмент из libwww-perl:
cat /path/to/mascot.jpg | POST -uUsSeE -c image/jpeg http://localhost:9000/path/to/upload/API
POST http://localhost:9000/path/to/upload/API
User-Agent: lwp-request/6.03 libwww-perl/6.05
Content-Length: 75211
Content-Type: image/jpeg
200 OK
Content-Length: 16
Content-Type: application/json; charset=utf-8
Client-Date: Mon, 16 Jun 2014 09:21:00 GMT
Client-Peer: 127.0.0.1:9000
Client-Response-Num: 1
{"success":true}
этот запрос был выполнен поэтому я начал уделять больше внимания различиям между инструментами. для начинающих: Content-Length
заголовок был правильным, но также Expect
заголовок отсутствовал со второй попытки. Я хочу, чтобы запрос был успешным в любом случае. так что полный список заголовков, как видно в игре (через request.headers
) является:
для завитка:
ArrayBuffer((Content-Length,ArrayBuffer(27442)),
(Accept,ArrayBuffer(*/*)),
(Content-Type,ArrayBuffer(image/jpeg)),
(Expect,ArrayBuffer(100-continue)),
(User-Agent,ArrayBuffer(curl/7.35.0)),
(Host,ArrayBuffer(localhost:9000)))
для libwww-perl POST:
ArrayBuffer((TE,ArrayBuffer(deflate,gzip;q=0.3)),
(Connection,ArrayBuffer(TE, close)),
(Content-Length,ArrayBuffer(75211)),
(Content-Type,ArrayBuffer(image/jpeg)),
(User-Agent,ArrayBuffer(lwp-request/6.03 libwww-perl/6.05)),
(Host,ArrayBuffer(localhost:9000)))
Итак, мои нынешние мысли таковы: более простой инструмент Perl использовал один запрос, что является плохой практикой. лучший способ будет ждать 100 continue
подтверждение (особенно если вы собираетесь загрузить несколько ГБ данных...). curl
будет продолжать отправлять данные, пока не получит 200 OK
или неправильный код ошибки запроса. Так почему игра посылает 200 OK
ответ, не дожидаясь следующего куска? это потому, что curl указывает неправильное Content-Length
? если это вообще неправильно... (возможно, это относится к размеру текущего чанка?). так в чем же проблема? в скручиваемости или в игровом веб-приложении? и как мне это исправить?
1 ответ
Проблема была в моей команде curl. Я использовал -d
аргумент, который является коротким для --data
или же --data-ascii
когда я должен был использовать --data-binary
аргумент.