cURL and paste
cURL and paste...two great tastes that apparently don't go well at all together!
I've been writing a bunch of simple wsgi apps lately, some of which handle file uploads.
Take this tiny application:
import webob
def app(environ, start_response):
req = webob.Request(environ)
req.body_file.read()
return webob.Response("OK!")(environ, start_response)
import paste.httpserver
paste.httpserver.serve(app, port=8090)
Then throw some files at it with cURL:
[catlee] % for f in $(find -type f); do time curl -s -o /dev/null --data-binary @$f http://localhost:8090; done
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.00s user 0.00s system 0% cpu 1.013 total
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 63% cpu 0.013 total
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 64% cpu 0.012 total
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 81% cpu 0.015 total
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 0% cpu 1.014 total
curl -s -o /dev/null --data-binary @$f http://localhost:8090 0.00s user 0.00s system 0% cpu 1.009 total
Huh? Some files take a second to upload?
I discovered after much digging, and rewriting my (more complicated) app several times, that the problem is that cURL sends an extra "Expect: 100-continue" header. This is supposed to let a web server respond with "100 Continue" immediately or reject an upload based on the request headers.
The problem is that paste's httpserver doesn't send this by default, and so cURL will wait for a second before giving up and sending the rest of the request.
The magic to turn this off is the '-0' to cURL, which forces HTTP/1.0 mode:
[catlee] % for f in $(find -type f); do time curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090; done
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.00s user 0.00s system 66% cpu 0.012 total
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 64% cpu 0.012 total
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.00s user 0.01s system 58% cpu 0.014 total
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 66% cpu 0.012 total
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.00s user 0.00s system 59% cpu 0.013 total
curl -0 -s -o /dev/null --data-binary @$f http://localhost:8090 0.01s user 0.00s system 65% cpu 0.012 total
Comments