Re: URLAccess Stalls
Re: URLAccess Stalls
- Subject: Re: URLAccess Stalls
- From: Jim Luther <email@hidden>
- Date: Thu, 5 Jan 2006 14:21:12 -0800
Zack,
I don't think this is a bug.
First, it looks like you are using tcpflow to look at the packets.
tcpflow throws an extra blank line into it's output between packets.
That's the extra "\r\n between the header and body of a POST request"
you are seeing.
Second, an HTTP message can be split into multiple tcp packets and it
will not make any difference to the contents of the data stream. It's
just slightly more overhead for short messages (messages that would
fit into one tcp packet) because the message is sent in two packets
instead of one.
CFNetwork's HTTP code sends the message headers and message body to
socket as two separate writes -- that's why you end up with two tcp
packets. Before Tiger, this could cause performance problems because
"Nagel's Algorithm" was enabled by default on the sockets CFNetwork
used for HTTP transactions (see TCP/IP Illustrated, Volume 1, section
19.4 for a full description of Nagel's Algorithm) -- That could
cause a delay between the packet with the message headers and the
packet with the message body. In Tiger, we disabled "Nagel's
Algorithm" on the sockets used for HTTP (and FTP) by setting the
TCP_NODELAY socket option on sockets, so the packets are now sent
back to back with no delays. We've got a Radar performance bug open
<rdar://problem/3864399> "CFHTTP should write small bodies and
headers in one write call" to improve that behavior in the future.
- Jim Luther
On Jan 5, 2006, at 1:34 PM, email@hidden wrote:
On Dec 16, 2005, at 7:24 AM, Peter Sichel wrote:
On 12/14/05, Marc Krochmal wrote:
There were other reasons to deprecate URL Access besides the three I
listed. Those were just some examples.
Did anyone at Apple ever resolve why URL Access broke in 10.4 ???
It's all very nice to deprecate older technology, but you still
have to
figure out what broke in case there's a more serious underlying
bug in
10.4 . Some of my customers are reporting seemingly random stalls
under
10.4 in Distributed Objects messaging that has worked for ages.
Hi all, I finally bit the bullet and added code in my http wrapper
class to use CFNetwork, CFHTTPMessage and CFReadStream. It took
half a day of research to learn how it all works, and then half a
day to import the CoreFoundation and CoreServices bundles for the
constants and functions needed, since I am using CodeWarrior and
Carbon. It took another full day, noon to 2 am, to fill in all of
the OS X sections of my class. It's taken another day of testing
so far to get it working, but I am not quite there yet because I
have uncovered a bug in CFNetwork that I am not sure Apple is aware
of. So anyway, figure on at least 3 full days to convert your
URLAccess code to CFNetwork, which is not too bad I guess, and
CFNetwork is MUCH faster than URLAccess. BTW https is working
fine, it's all working quite well actually, except:
***CFNetwork either inserts an extra \r\n between the header and
body of a POST request, or is sending the header and body in 2
steps***
So I am at the end of the line because none of the forms on my site
work, and I dunno where to go from here unless someone can help me
solve this bug. Here are all of the gory details:
-------------------------------------------------------------
I build the request by calling these lines:
////////////////////
CFHTTPMessageRef messageRef
char requestBody = "user=test&pass=test";
CFDataRef dataRef;
messageRef = CFHTTPMessageCreateRequest( kCFAllocatorDefault, CFSTR
("POST"), CFSTR("http://mysite.com"), kCFHTTPVersion1_1 );
dataRef = CFDataCreateWithBytesNoCopy( nil, (unsigned char*)
requestBody , strlen( requestBody ), kCFAllocatorNull );
CFHTTPMessageSetBody( messageRef, dataRef );
readStreamRef = CFReadStreamCreateForHTTPRequest
( kCFAllocatorDefault, messageRef );
CFReadStreamOpen( readStreamRef );
// then later:
header = nil;
while( !header )
{
CFReadStreamHasBytesAvailable( readStreamRef ); // tickle the
download to give it time to load header
messageRef = CFReadStreamCopyProperty( readStreamRef,
kCFStreamPropertyHTTPResponseHeader );
if( messageRef )
{
dataRef = CFHTTPMessageCopySerializedMessage( messageRef ); //
messageRef only contains the header here
if( dataRef )
{
size = CFDataGetLength( dataRef );
header = CFDataGetBytePtr( dataRef ); // header is received
}
}
}
////////////////////
I receive the header from the server just fine, but my
authentication failed because the POST was not sent correctly.
Here is a packet trace to my website, using:
sudo /usr/local/bin/tcpflow -i en0 -c port 80
I have cleaned it up a bit and replaced the site name and IP
address of the site with mysite.com and 1.2.3.4. I am sending a
POST request with a body of:
user=test&pass=test
Which emulates the form I use on the website. Here is the complete
transaction:
////////////////////
POST /index.php HTTP/1.1
User-Agent: CFNetwork/4.0
Content-Length: 19
Connection: close
Host: mysite.com
192.168.000.002.55331-001.002.003.004.00080: user=test&pass=test
001.002.003.004.00080-192.168.000.002.55331: HTTP/1.1 200 OK
Date: Thu, 05 Jan 2006 20:49:49 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-16 mod_ssl/
2.0.54 OpenSSL/0.9.7e
X-Powered-By: PHP/4.3.10-16
Content-Length: 3
Connection: close
Content-Type: text/html
***
////////////////////
The "***" at the end is a place where I call this in php on the
server:
<?php echo '*'.$_POST['user'].'*'.$_POST['pass'].'*'."\n" ?>
In this case, php is not getting the username or password. The
reason this fails is because the lines that say:
////////////////////
Host: mysite.com
192.168.000.002.55331-001.002.003.004.00080: user=test&pass=test
001.002.003.004.00080-192.168.000.002.55331: HTTP/1.1 200 OK
...
***
////////////////////
Are wrong. For some reason CFReadStream has either sent the
request in 2 parts, or has added an extra \r\n to the request
between mysite.com and user=test&pass=test (the header and body,
respectively) in the first trace. It should read:
////////////////////
Host: mysite.com
user=test&pass=test
001.002.003.004.00080-192.168.000.002.55331: HTTP/1.1 200 OK
...
*test*test*
////////////////////
Notice there is one less \r\n in the second trace, which is
correct. This is a pretty catastrophic error, and I am either
doing something completely wrong, or I have no idea how CFNetwork
can use web forms with POST. Sorry for such a verbose letter.
Does anyone know what is going on, or how to fix this? Thanx,
----------------------------------------------------------------------
--
Zack Morris Z Sculpt Entertainment This
Space
email@hidden http://www.zsculpt.com For
Rent
----------------------------------------------------------------------
--
If the doors of perception were cleansed, everything would appear
to man
as it is, infinite. -William Blake, The Marriage of Heaven and Hell
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40apple.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden