Replacing CURL method for XBMC friendly code..
#1
I was wondering if someone can help me convert this method to something more XBMC friendly. I need to drop CURL for XBMC built-in/exposed functions as CURL is causing XBMC to crash on certain platforms/versions. I'm a beginner at CPP programming so any help/guidance is greatly appreciated.

Thanks to whomever replies.

Code:
static size_t data_write(void* buf, size_t size, size_t nmemb, void* userp)
{
    if(userp)
    {
        std::ostream& os = *static_cast<std::ostream*>(userp);
        std::streamsize len = size * nmemb;
        if(os.write(static_cast<char*>(buf), len))
            return len;
    }

    return 0;
}

CURLcode cPVRClient::GetAuthenticatedURL(const CStdString &url, ostringstream &strContent, long timeout)
{
    CURLcode    code(CURLE_FAILED_INIT);
    CURL       *curl        = curl_easy_init();
    char       *buffer;
    char       *errorBuffer = 0;
    string      strSuccess  = "Login Complete";

    if (curl)
    {
        if (CURLE_OK == (curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str()))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_HEADER, 1))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &strContent))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout))
                && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "")))
        {
            code = curl_easy_perform(curl);

            m_strUrl = strContent.str();
            size_t found = m_strUrl.find(strSuccess.c_str());
            if (found == std::string::npos)
            {
                XBMC->Log(LOG_ERROR, "Authentication Failure.");
                return CURLE_URL_MALFORMAT;
            }

            istringstream ss(m_strUrl);
            string line;
            size_t cc;
            while (getline(ss, line))
            {
                cc = line.find("Set-Cookie:");
                if (cc != std::string::npos)
                {
                    cc = line.find("PHPSESSID=");
                    if (cc != std::string::npos)
                    {
                        m_strPHPSessId = line.substr(line.find("PHPSESSID="), line.length() - 1);
                    }
                    else
                    {
                        m_strToken = line.substr(line.find("token"), line.length() - 1);
                    }
                }
            }

            char   params[100];
            char   chans[256];

            strContent.clear();
            strContent.str("");

            string strId = m_strToken.substr(0, m_strToken.find_first_of(";"));
            sprintf(chans, "http://mydomain.myhost.com?%s", strId.c_str());

            if (CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_COOKIE, m_strToken.c_str()))
                    && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_COOKIE, m_strPHPSessId.c_str()))
                    && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, chans)))
            {
                code = curl_easy_perform(curl);
            }
        }
        curl_easy_cleanup(curl);
    }

    return code;
}
Reply
#2
Found some good examples on sockets through google.. will give them a try later this evening.
Reply
#3
So I'm trying to write a socket function to connect to port 80 of a host and mimic what you would get using a telnet, so I can retrieve the cookie values from the header, unfortunately my socket function can't create a connection to any host. Telnet works fine so there should be no reason why it shouldn't work. Can a CPP pro take a look and tell me where I went wrong?

Code:
char               *message;
    struct hostent     *he;
    struct sockaddr_in  server;
    int                 sockfd;

    if ((he = gethostbyname("google.com")) == NULL)
    {
        XBMC->Log(LOG_DEBUG, "->Socket(): Can't resolve host.");
        return E_FAILED;
    }

    memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
    server.sin_family = AF_INET;
    server.sin_port = htons(80);

    if (connect(sockfd, (struct sockaddr *)&server, sizeof(server)))
    {
        XBMC->Log(LOG_DEBUG, "->Socket(): Can't connect to %s", he->h_name);
        return E_FAILED;
    }

    sprintf(message, "GET /%s%s HTTP/1.1\r\nHost: google.com\r\n\r\n", url.c_str(), arguments.c_str());
    if (send(sockfd, message, strlen(message), 0) < 0)
    {
        XBMC->Log(LOG_DEBUG, "->Socket(): Login failed.");
        return E_FAILED;
    }

    //Receive a reply from the server
    //Now receive full data
    int total_recv = recv_timeout(sockfd, 4, response);

    return E_SUCCESS;

and the logs..
Code:
00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->GetLiveStreamURL(uid=198886810)
00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->CloseLiveStream: uid=-1
00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->OpenLiveStream(id=252, name=CW)
00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->Authenticate()
00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->GetURL(): http://10.2.1.64:8080/login
00:26:54 T:140388178323200   DEBUG: CurlFile::Open(0x7fae9c0069a0) http://10.2.1.64:8080/login
--> 00:26:54 T:140388178323200   DEBUG: AddOnLog: RTV PVR: ->Socket(): Can't connect to google.com
00:26:54 T:140388178323200   ERROR: CDVDInputStreamPVRManager::Open - error opening []
Reply
#4
You're checking connect() returns true, not false.
Reply
#5
Thanks.. I'll give it a try.
Reply

Logout Mark Read Team Forum Stats Members Help
Replacing CURL method for XBMC friendly code..0