Re: Proxy Server Authentication
Re: Proxy Server Authentication
- Subject: Re: Proxy Server Authentication
- From: "Jim O'Connor" <email@hidden>
- Date: Sat, 21 Jun 2003 16:56:53 -0500
It is interesting to note that Internet Explorer, using OpenTransport, can
deal with https through a proxy, but Safari using CFNetwork (one would
suppose) doesn't.
>
I am having trouble getting a proxy server that requires authentication to
>
behave properly when the destination address is an https site. The nature of
>
the problem is this:
>
>
1. I have a proxy server set up that requires authentication.
>
2. I have my network proxy configuration set up to use this proxy server for
>
both http and https.
>
3. I am using the CFNetwork CFHTTP an CFReadStream classes to set up a post to
>
the destination server.
>
4. I am setting the proxy server on the stream to match the settings in my
>
network configuration.
>
5. I am using a POST to attempt to send and receive XML from the destination
>
6. After reading the bytes, I check the response, looking for a 407 status, so
>
I can deal with the authentication requirement.
>
7. What actually happens is that I never get the 407 from the proxy server.
>
Instead I typically get <0 bytes read.
>
8. If I change the destination server address to be http: instead of https: I
>
do get the 407 response code. But this will not work as my destination server
>
needs to be https.
>
9. Also, using http, allows me to catch the response and force the
>
authentication, but I then continue to get a 407 response.
>
>
Here is the code:
>
>
void Post(void)
>
{
>
CFHTTPMessageRef messageRef = NULL;
>
CFReadStreamRef readStreamRef = NULL;
>
>
vector<char> buffer;
>
>
ostringstream ostm;
>
//ostm << "https://" << g_destMachine << ":" << g_destPort << g_destURL;
>
ostm << "https://" << g_destMachine << g_destURL;
>
//ostm << "http://" << g_destMachine << g_destURL;
>
std::string url = ostm.str();
>
>
std::ostringstream urlStm;
>
urlStm << "XML=" << "<xml> </xml>";
>
>
std::string test = urlStm.str();
>
CFURLRef urlRef = ::CFURLCreateWithBytes( kCFAllocatorDefault, (const
>
UInt8*)url.c_str(), strlen(url.c_str()), CFStringGetSystemEncoding(), NULL );
>
CFDataRef data = ::CFDataCreate( kCFAllocatorDefault, (const
>
UInt8*)test.c_str(), strlen( test.c_str() ) );
>
>
messageRef = CFHTTPMessageCreateRequest( kCFAllocatorDefault, CFSTR("POST"),
>
urlRef, kCFHTTPVersion1_1 );
>
>
CFHTTPMessageSetBody(messageRef, data);
>
>
// Create the stream for the request.
>
readStreamRef = CFReadStreamCreateForHTTPRequest( kCFAllocatorDefault,
>
messageRef );
>
>
>
Boolean tryAgain;
>
>
>
do
>
{
>
tryAgain = false;
>
>
// Check for proxy settings
>
CFHTTPReadStreamSetProxy(readStreamRef, CFSTR("192.168.104.111"), 80);
>
>
>
// Schedule the stream
>
CFReadStreamScheduleWithRunLoop( readStreamRef, CFRunLoopGetCurrent(),
>
kCFRunLoopCommonModes );
>
>
// Start the HTTP connection
>
CFReadStreamOpen( readStreamRef );
>
>
UInt8 rawBuf[2048];
>
>
do {
>
CFStreamStatus rStatus = CFReadStreamGetStatus(readStreamRef);
>
>
CFIndex rcvd;
>
rcvd = 0;
>
>
// Continue pumping along while waiting to open
>
if ((rStatus == kCFStreamStatusOpening))
>
continue;
>
>
if ((rStatus == kCFStreamStatusError) ||
>
(rStatus == kCFStreamStatusClosed) ||
>
(rStatus == kCFStreamStatusAtEnd)) {
>
break;
>
}
>
>
// Keep trying to receive the data
>
CFIndex bytesRead = ::CFReadStreamRead(readStreamRef, rawBuf, sizeof(rawBuf));
>
>
// Check to see if an error occurred
>
if (bytesRead <= 0)
>
{
>
// An error has occurred.
>
CFStreamError myErr = CFReadStreamGetError(readStreamRef);
>
if (myErr.domain == kCFStreamErrorDomainPOSIX) {
>
int i = 0;
>
// Interpret myErr.error as a UNIX errno.
>
} else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
>
int i = 0;
>
} else if (myErr.domain == kCFStreamErrorDomainHTTP ) {
>
int i = 0;
>
} else if (myErr.domain == kCFStreamErrorDomainSSL ) {
>
int i = 0;
>
}
>
}
>
else
>
{
>
CFHTTPMessageRef response = (CFHTTPMessageRef)
>
::CFReadStreamCopyProperty(readStreamRef,
>
kCFStreamPropertyHTTPResponseHeader);
>
>
if ( response != NULL )
>
{
>
UInt32 statusCode = ::CFHTTPMessageGetResponseStatusCode(response);
>
>
// if the proxy server requires authentication, we need to send the
>
authentication data
>
if ( statusCode == 407 )
>
{
>
// close the stream
>
CFReadStreamClose(readStreamRef);
>
CFRelease(readStreamRef);
>
readStreamRef = NULL;
>
>
// add authentication
>
if ( CFHTTPMessageAddAuthentication(messageRef, response, CFSTR("Foo"),
>
CFSTR("Bar"),
>
kCFHTTPAuthenticationSchemeBasic, TRUE) )
>
{
>
readStreamRef = CFReadStreamCreateForHTTPRequest( kCFAllocatorDefault,
>
messageRef );
>
>
tryAgain = true;
>
>
break;
>
}
>
else
>
{
>
// handle error
>
}
>
}
>
}
>
}
>
>
if (bytesRead <= 0)
>
break;
>
>
copy(rawBuf, rawBuf+bytesRead, insert_iterator<vector<char> >(buffer,
>
buffer.end()));
>
>
} while (1);
>
>
} while (tryAgain);
>
>
// Close the streams
>
::CFReadStreamClose(readStreamRef);
>
>
if ( messageRef != NULL )
>
::CFRelease( messageRef );
>
>
}
>
_______________________________________________
>
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.
_______________________________________________
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.