2011-10-15 93 views
2

我正在創建下載應用程序。 我正面臨代理驗證問題。 我得到407響應代碼,即所需的代理身份驗證。我有有效的代理認證詳細信息。可可:處理407 http響應cfnetwork

以下是代碼流程:

1. Create Http request using CFHTTPMessageCreateRequest 
2. Set necessary header field values like Cache-Control, Accept-Ranges, Range & User-Agent using CFHTTPMessageSetHeaderFieldValue 
3. Create read stream using CFReadStreamCreateForHTTPRequest 
4. Set proxy server URL & port properties on read stream using CFReadStreamSetProperty 
5. Set kCFStreamPropertyHTTPShouldAutoredirect to kCFBooleanTrue using CFReadStreamSetProperty 
6. open read stream using CFReadStreamOpen 
7. In a loop wait for stream to get opened 

while (1) 
{ 
    if (kCFStreamStatusOpen == CFReadStreamGetStatus) 
    { 
      if (CFReadStreamHasBytesAvailable) 
      { 
       Get Http response header using CFReadStreamCopyProperty 
       Get response code using CFHTTPMessageGetResponseStatusCode 
       if (200 || 206 is response code) 
       SUCCESS 
       else check if response code is 407. 
      } 
     } 
} 

我嘗試使用下面的代碼

if (407 == nsiStatusCode) 
{ 
CFStreamError err; 
cfAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, cfHttpResponse); 
if ((cfAuthentication) && (CFHTTPAuthenticationIsValid(cfAuthentication, &err))) 
{ 
if (CFHTTPAuthenticationRequiresUserNameAndPassword(cfAuthentication)) 
{ 
CFHTTPMessageApplyCredentials(cfHttpRequest, cfAuthentication, (CFStringRef)pnsUserName, (CFStringRef)pnsPassword, &err); 
} 
} 
} 

,但不能使它工作。 如何處理407狀態碼以便與驗證HTTP服務器進行通信?

在此先感謝。 Vaibhav。

回答

2

構建CFHTTPMessageRef

-(CFHTTPMessageRef)buildMessage 
{ 
    NSURL *myURL = [NSURL URLWithString:@"http://myurl.com"]; 
    NSData *dataToPost = [[NSString stringWithString:@"POST Data It Doesn't Matter What It Is"] dataUsingEncoding:NSUTF8StringEncoding]; 


    //Create with the default allocator (NULL), a post request, 
    //the URL, and pick either 
    //kCFHTTPVersion1_0 or kCFHTTPVersion1_1 
    CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CSTR("POST"), (CFURLRef)myURL, kCFHTTPVersion1_1); 


    CFHTTPMessageSetBody(request, (CFDataRef)dataToPost); 


    //Unfortunately, this isn't smart enough to set reasonable headers for you 
    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("HOST"), (CFStringRef)[myURL host]); 
    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Length"), (CFStringRef)[NSString stringWithFormat:"%d", [dataToPost length]); 
    CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("charset=utf-8")); 


    return [NSMakeCollectable(request) autorelease]; 
} 

它發送到服務器,並回讀響應

-(CFHTTPMessageRef)performHTTPRequest:(CFHTTPMessageRef)request 
{ 
    CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request); 
    CFReadStreamOpen(requestStream); 


    NSMutableData *responseBytes = [NSMutableData data]; 


    CFIndex numBytesRead = 0 ; 
    do 
    { 
     UInt8 buf[1024]; 
     numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf)); 


     if(numBytesRead > 0) 
     [responseBytes appendBytes:buf length:numBytesRead]; 


    } while(numBytesRead > 0); 


    CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader); 
    CFHTTPMessageSetBody(response, (CFDataRef)responseBytes); 


    CFReadStreamClose(requestStream); 
CFRelease(requestStream); 


    return [NSMakeCollectable(response) autorelease]; 
} 

添加認證HTTP請求

-(void)addAuthenticationToRequest:(CFHTTPMessageRef)request withResponse:(CFHTTPMessageRef)response 
{ 
    CFHTTPAuthenticationRef authentication = CFHTTPAuthenticationCreateFromResponse(NULL, response); 
    [NSMakeCollectable(authentication) autorelease]; 


    CFStreamError err; 
    Boolean success = CFHTTPMessageApplyCredentials(request, authentication, CFSTR("username"), CFSTR("password"), &err); 
} 

全部放在一起

-(void)magicHappens 
{ 
    CFHTTPMessageRef request = [self buildMessage]; 
    CFHTTPMessageRef response = [self performHTTPRequest: request]; 


    UInt32 statusCode; 
    statusCode = CFHTTPMessageGetResponseStatusCode(response); 


    //An HTTP status code of 401 or 407 indicates that authentication is 
    //required I use an auth count to make sure we don't get stuck in an  
    //infinite loop if our credentials are bad. Sometimes, making the  
    //request more than once lets it go through. 
    //I admit I don't know why. 


    int authCount = 0; 
    while((statusCode == 401 || statusCode == 407) && authCount < 3) 
    { 
     request = [self buildMessage]; 
     [self addAuthenticationToRequest:request withResponse:response]; 


     response = [self performHTTPRequest: request]; 
     statusCode = CFHTTPMessageGetResponseStatusCode; 
     authCount++; 
    } 


    NSData *responseBodyData = [(NSData*)CFHTTPMessageCopyBody(response) autorelease]; 
    NSString *responseBody = [[[NSString alloc] initWithData:responseBodyData encoding:NSUTF8StringEncoding] autorelease]; 


    NSLog(responseBody); 
} 

請參閱this的鏈接。