Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Re: why is my download request using HTTP POST is split in header and body ?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: why is my download request using HTTP POST is split in header and body ?

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);

// 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));


// 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
} else {
// Error occurred

Good luck - REW
macnetworkprog mailing list | email@hidden
Do not post admin requests to the list. They will be ignored.

 >why is my download request using HTTP POST is split in header and body ? (From: "Hans Loonen" <email@hidden>)

Visit the Apple Store online or at retail locations.

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.