2011-10-15 2 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); 
} 
} 
} 

하지만 수 없습니다를 사용 했어요. 인증 HTTP 서버와 통신하기 위해 상태 코드를 어떻게 처리합니까?

미리 감사드립니다. Vaibhav.

답변

2

-(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]; 
} 

가 서버에 전송하고 함께

을 모두 퍼팅 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); 
} 

에 인증을 추가 응답

-(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]; 
} 

을 다시 읽기 CFHTTPMessageRef 구축

-(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 링크를 참조하십시오.