Based on an answer to another question I am using curl to stream the stdout
of one process as the entity of a POST
request:
myDataGeneratingApp \
| curl -H "Content-Type: application/json" -H "Transfer-Encoding: chunked" -X POST -d @- http://localhost:12000
Unfortunately, curl is waiting for EOF
from the stdout before it begins sending the data. I know this because I can run my application stand-alone and data comes out to the console immediately but when I pipe to curl there is a significant delay before the service begins receiving data.
How can I use curl to stream data immediately as it becomes available from the standard out of the application? If not possible in curl then is there another solution (e.g. wget)?
Best Answer
Looking through the curl code transfer.c it seems that the program is able to repackage request data (from curl to the server) using the chunking protocol, where each chunk of data is prefixed by the length of the chunk in ascii hexadecimal, and suffixed by
\r\n
.It seems the way to make it use this in a streaming way, after connecting to the server is with
-T -
. Consider this example:This script sends 5 blocks of data, each beginning with the date and padded to 512 bytes by
dd
, to a pipe, wherestrace
runscurl -T -
to read the pipe. In the terminal we can seewhich shows the connection, and the headers sent. In particular
curl
has not provided aContent-length:
header, but anExpect:
header to which the server (apache) has repliedContinue
. Immediately after comes the first 512 bytes (200 in hex) of data:Looking in the
strace
output file we see each timestampedread
from the pipe, andsendto
write to the connection:As you can see they are spaced out by 1 second, showing that the data is being sent as it is being received. You must just have at least 512 bytes to send, as the data is being read by
fread()
.