Cocos2d-x C++ Networking Tutorial Series

  • shauket sheikh
    Likes 2

    Hi,

    Please add this reserech on networking call in cocos2dx.i see in cocos2d version less than 3.8 have issue with httprequest type it does not support Delete and Get request type in case if you have to send data in headers. if your request type is Delete or Get you can not send data in header.i found out solution for this to change some code in HttpClient-ios.mm replace following method in your code. using this method you can send header in GET and Delete call. and dont forget to set content type to application json.

    //Process Request
    static int processTask(HttpRequest *request, NSString* requestType, void *stream, long *responseCode, void *headerStream, char *errorBuffer)
    {
        //create request with url
        NSString* urlstring = [NSString stringWithUTF8String:request->getUrl()];
        NSURL *url = [NSURL URLWithString:urlstring];
    
        NSMutableURLRequest *nsrequest = [NSMutableURLRequest requestWithURL:url
                                                   cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                               timeoutInterval:HttpClient::getInstance()->getTimeoutForConnect()];
        
        //set request type
        [nsrequest setHTTPMethod:requestType];
    
        //if request type is post or put,set header and data
        if([requestType  isEqual: @"POST"] || || [requestType isEqual: @"GET"] || [requestType isEqual: @"PUT"] || [requestType isEqual: @"DELETE"])
        {
            if ([requestType isEqual: @"PUT"] || [requestType isEqual: @"GET"] || [requestType isEqual: @"DELETE"])
            {
                [nsrequest setValue: @"application/x-www-form-urlencoded" forHTTPHeaderField: @"Content-Type"];
            }
            /* get custom header data (if set) */
            std::vector<std::string> headers=request->getHeaders();
            if(!headers.empty())
            {
                /* append custom headers one by one */
                for (std::vector<std::string>::iterator it = headers.begin(); it != headers.end(); ++it)
                {
                    unsigned long i = it->find(':', 0);
                    unsigned long length = it->size();
                    std::string field = it->substr(0, i);
                    std::string value = it->substr(i+1, length-i);
                    NSString *headerField = [NSString stringWithUTF8String:field.c_str()];
                    NSString *headerValue = [NSString stringWithUTF8String:value.c_str()];
                    [nsrequest setValue:headerValue forHTTPHeaderField:headerField];
                    NSLog(@"header value and key %@:%@",headerField,[nsrequest valueForHTTPHeaderField:headerField]);
                }
            }
    
            char* requestDataBuffer = request->getRequestData();
            if (nullptr !=  requestDataBuffer && 0 != strlen(requestDataBuffer))
            {
                NSData *postData = [NSData dataWithBytes:requestDataBuffer length:request->getRequestDataSize()];
                [nsrequest setHTTPBody:postData];
            }
        }
    
        //read cookie propertities from file and set cookie
        if(!s_cookieFilename.empty())
        {
            const CookiesInfo* cookieInfo = s_cookie->getMatchCookie(request->getUrl());
            if(cookieInfo != nullptr)
            {
                NSString *domain = [NSString stringWithCString:cookieInfo->domain.c_str() encoding:[NSString defaultCStringEncoding]];
                NSString *path = [NSString stringWithCString:cookieInfo->path.c_str() encoding:[NSString defaultCStringEncoding]];
                NSString *value = [NSString stringWithCString:cookieInfo->value.c_str() encoding:[NSString defaultCStringEncoding]];
                NSString *name = [NSString stringWithCString:cookieInfo->name.c_str() encoding:[NSString defaultCStringEncoding]];
    
                // create the properties for a cookie
                NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys: name,NSHTTPCookieName,
                value, NSHTTPCookieValue, path, NSHTTPCookiePath,
                domain, NSHTTPCookieDomain,
                nil];
                
                // create the cookie from the properties
                NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:properties];
                
                // add the cookie to the cookie storage
                [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
            }
        }
        
        HttpAsynConnection *httpAsynConn = [HttpAsynConnection new];
        httpAsynConn.srcURL = urlstring;
        httpAsynConn.sslFile = nil;
        NSString *sslFile = nil;
        if(!s_sslCaFilename.empty())
        {
            long len = s_sslCaFilename.length();
            long pos = s_sslCaFilename.rfind('.', len-1);
            [sslFile initWithUTF8String:s_sslCaFilename.substr(0, pos-1).c_str()];
            httpAsynConn.sslFile = sslFile;
        }
        [httpAsynConn startRequest:nsrequest];
        
        while( httpAsynConn.finish != true)
        {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
        
        //if http connection return error
        if (httpAsynConn.responseError != nil)
        {
            NSString* errorString = [httpAsynConn.responseError localizedDescription];
            strcpy(errorBuffer, [errorString UTF8String]);
            return 0;
        }
        
        *responseCode = httpAsynConn.responseCode;
        
        //add cookie to cookies vector
        if(!s_cookieFilename.empty())
        {
            NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpAsynConn.responseHeader forURL:url];
            for (NSHTTPCookie *cookie in cookies)
            {
                //NSLog(@"Cookie: %@", cookie);
                NSString *domain = cookie.domain;
                //BOOL session = cookie.sessionOnly;
                NSString *path = cookie.path;
                BOOL secure = cookie.isSecure;
                NSDate *date = cookie.expiresDate;
                NSString *name = cookie.name;
                NSString *value = cookie.value;
                
                CookiesInfo cookieInfo;
                cookieInfo.domain = [domain cStringUsingEncoding: NSUTF8StringEncoding];
                cookieInfo.path = [path cStringUsingEncoding: NSUTF8StringEncoding];
                cookieInfo.secure = (secure == YES) ? true : false;
                cookieInfo.expires = [[NSString stringWithFormat:@"%ld", (long)[date timeIntervalSince1970]] cStringUsingEncoding: NSUTF8StringEncoding];
                cookieInfo.name = [name cStringUsingEncoding: NSUTF8StringEncoding];
                cookieInfo.value = [value cStringUsingEncoding: NSUTF8StringEncoding];
                cookieInfo.tailmatch = true;
                
                s_cookie->updateOrAddCookie(&cookieInfo);
            }
        }
        
        //handle response header
        NSMutableString *header = [NSMutableString new];
        [header appendFormat:@"HTTP/1.1 %ld %@\n", httpAsynConn.responseCode, httpAsynConn.statusString];
        for (id key in httpAsynConn.responseHeader)
        {
            [header appendFormat:@"%@: %@\n", key, [httpAsynConn.responseHeader objectForKey:key]];
        }
        if (header.length > 0)
        {
            NSRange range = NSMakeRange(header.length-1, 1);
            [header deleteCharactersInRange:range];
        }
        NSData *headerData = [header dataUsingEncoding:NSUTF8StringEncoding];
        std::vector<char> *headerBuffer = (std::vector<char>*)headerStream;
        const void* headerptr = [headerData bytes];
        long headerlen = [headerData length];
        headerBuffer->insert(headerBuffer->end(), (char*)headerptr, (char*)headerptr+headerlen);
    
        //handle response data
        std::vector<char> *recvBuffer = (std::vector<char>*)stream;
        const void* ptr = [httpAsynConn.responseData bytes];
        long len = [httpAsynConn.responseData length];
        recvBuffer->insert(recvBuffer->end(), (char*)ptr, (char*)ptr+len);
        
        return 1;
    }
    

     


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Thanks for sharing.

Login to reply