0

考虑一个在 play 中编写的 Web 服务,它除了 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 决定添加 header Content-Length: 27442,但这不是真的,实际尺寸是 75211,在游戏中,我确实得到了一个尺寸仅为 27442 的主体。粗略,这不是预期的行为。所以我尝试了一个不同的工具,而不是curl我使用libwww-perlPOST的工具:

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第二次尝试时标题丢失了。无论哪种方式,我都希望请求成功。所以在 play (via) 中看到的完整标题列表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确认(特别是如果你要上传几 GB 的数据......)。curl将继续发送数据,直到它收到一个200 OK或一些错误的请求错误代码。那么为什么 play 发送200 OK响应而不等待下一个块呢?是因为 curl 指定了错误Content-Length吗?如果它完全错误......(也许这是指当前块的大小?)。那么问题出在哪里?在 curl 中还是在 play webapp 中?我该如何解决?

4

1 回答 1

2

问题出在我的 curl 命令中。当我应该使用参数时,我使用了-d参数,它是--dataor的缩写。--data-ascii--data-binary

于 2014-06-17T11:04:10.423 回答