Re: why is my download request using HTTP POST is split in header and body ?
Re: why is my download request using HTTP POST is split in header and body ?
- Subject: Re: why is my download request using HTTP POST is split in header and body ?
- From: Becky Willrich <email@hidden>
- Date: Thu, 13 May 2004 09:09:31 -0700
When I run this code I do not get proper answers. To see what's wrong
I run
a sniffer (ettercap) the sniffer shows that the header part is sent to
the
server, then the server reponds with "HTTP/1.1 400 Bad request", and
then my
code simply continues with sending the message body.
To me it seems that header and body should be sent in 1 transfer
instead of
being split in two parts.
Does anyone have an idea why this happens?
I don't know what to tell you - the placing of packet boundaries is
ultimately determined by the BSD socket layer within the core OS, and
the printer is definitely (very) buggy to require that the entire
request be transmitted in a single packet - it should be ignoring the
packet boundaries, and relying instead on the Content-Length
transmitted in the header. CFNetwork doesn't explicitly tell the
socket layer to split the packets between the header and the body, but
I can understand from its call pattern why that's happening. No HTTP
server of any kind should ever care about where the packet boundaries
lie - that's part of the whole point of TCP.
First and foremost, see if there's an update to the printer and if this
is a known problem. Second, there are a couple things you can try.
You can try tweaking the high and low water marks on the actual socket
used by CFNetwork to see if you can artificially get the data to all
transmit as a single packet. I'm not optimistic about this approach,
though - it's difficult to get a hold of the socket before any bytes
have been transmitted, and the first transmission will presumably be
the headers (without the body). Your other choice is to use
CFHTTPMessage to simply serialize the request and deserialize the
incoming response, but not use CFHTTPStream (i.e. open a socket stream
yourself). That will look something like this (error checking code
omitted):
// build the HTTP request as you do currently
CFDataRef requestData = CFHTTPMessageCopySerializedMessage(httpRequest);
CFReadStreamRef socketReadStream;
CFWriteStreamRef socketWriteStream;
CFHTTPMessageRef response = CFHTTPMessageCreateEmpty(NULL, FALSE);
CFStreamCreatePairWithSocketToHost(NULL, printerIPAddressAsString,
printerPort, &socketReadStream, &socketWriteStream);
CFReadStreamOpen(socketReadStream);
CFWriteStreamOpen(socketWriteStream);
// This will attempt to write the entire request data in one chunk;
hopefully this will cause the BSD socket layer to send the request as a
single packet.
// In practice, you should check the return value from
CFWriteStreamWrite and ensure that it equals the total length of the
request, and if not, call CFWriteStreamWrite again to transmit the
remainder, but that's left as an exercise for the reader.
CFWriteStreamWrite(socketWriteStream, CFDataGetBytePtr(requestData),
CFDataGetLength(requestData));
CFWriteStreamClose(socketWriteStream);
CFRelease(socketWriteStream);
// This is an example of reading from the read stream synchronously;
depending on your surrounding code, you'll probably want to do this
asynchronously instead
char buffer[BUFSIZE];
int bytesRead = CFReadStreamRead(socketReadStream, buffer, BUFSIZE);
if (bytesRead > 0) {
CFHTTPMessageAppendBytes(response, buffer, bytesRead);
} else if (bytesRead == 0) {
// All done
finishUp();
} else {
// Error occurred
handleError();
}
Good luck - REW
_______________________________________________
macnetworkprog mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/macnetworkprog
Do not post admin requests to the list. They will be ignored.