Proxy Server Authentication
Proxy Server Authentication
- Subject: Proxy Server Authentication
- From: Joe Merritt <email@hidden>
- Date: Thu, 19 Jun 2003 08:56:26 -0700
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.