C ++ LibCurl GET из сокета - PullRequest
       11

C ++ LibCurl GET из сокета

0 голосов
/ 22 ноября 2010

Я хотел бы преобразовать этот код (используя язык сценариев с расширением Sockets) в C ++, используя LibCurl.Я использовал LibCurl только один раз, поэтому я немного растерялся, что еще мне понадобится.Главное, что я путаю, так это то, что я должен использовать curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers);чтобы отправить это, или если мне понадобится извлечь сокет, то отправьте его через него.

Вот соответствующий фрагмент из скрипта ...

public OnSocketConnected(Handle:socket, any:friendId) 
{
    decl String:CommunityId[32];
    FriendIDToCommunityId(friendId, CommunityId, sizeof(CommunityId));

    decl String:query[2048];
    decl String:cookieString[100];
    decl String:inviterString[32];
    decl String:groupString[32];

    GetConVarString(cookie, cookieString, sizeof(cookieString));
    GetConVarString(inviter, inviterString, sizeof(inviterString));
    GetConVarString(group, groupString, sizeof(groupString));


    Format(query, sizeof(query), "GET /actions/GroupInvite?type=groupInvite&inviter=%s&invitee=%s&group=%s HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: steamLogin=%s\r\n\r\n", inviterString, CommunityId, groupString, cookieString);
    SocketSend(socket, query);
    LogMessage("%s", query);
}

и здесьэто то, что я имею в C ++ до сих пор.Похоже, мне сначала нужно извлечь сокет, но я не очень разбираюсь в сетевом кодировании, поэтому я не совсем уверен, куда мне нужно идти отсюда.

void InviteToGroup(const char *szUserSteamID, const char *szInviterSteamID, const char *steamUser, const char *steamPass)
{
    CURL *curl;
    CURLcode res, result;
    //int sockfd; /* socket */
    char errorBuffer[CURL_ERROR_SIZE];

    const char *szUserID = GetCommunityID(szUserSteamID); // User's Steam Community ID
    const char *szInviterID = GetCommunityID(szInviterSteamID); // Inviter's Steam Community ID
    char *szGroupID = "";
    GetGroupCommunityID(1254745, &szGroupID); // Group Steam Community ID
    const char *szCookie = "76561198018111441%7C%7CC7D70E74A3F592F3E130CCF4CAACD4A7B9CAD993"; // Steam Community Login Cookie

    char *buffer = new char[512];

    // Create the GET request
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "GET /actions/GroupInvite?type=groupInvite&inviter=");
    snprintf(buffer, sizeof(buffer), "%s&invitee=%s&group=%s ", szInviterID, szUserID, szGroupID);
    headers = curl_slist_append(headers, buffer);
    headers = curl_slist_append(headers, "HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: ");
    snprintf(buffer, sizeof(buffer), "steamLogin=%s\r\n\r\n", szCookie);
    headers = curl_slist_append(headers, buffer);

    delete buffer;

    // Init CURL
    curl = curl_easy_init();

    if(curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, "https://www.steamcommunity.com");
        curl_easy_setopt(curl, CURLOPT_PORT, 443); // Check this before using
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
        //curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); // No transfer, just extract the socket

        // Find out if we need to use Proxy stuff here

        char *userpass = new char[64];
        snprintf(userpass, sizeof(userpass), "%s:%s", steamUser, steamPass);
        curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Attempt to Connect the Steam Community Server
        res = curl_easy_perform(curl);

        if (res == CURLE_OK)
            Msg("Connected Successfully!\n");
        else
            Msg("Connection Failed! Error: %s\n", errorBuffer);

        // Close the connection
        curl_easy_cleanup(curl);
    }
}

1 Ответ

0 голосов
/ 22 ноября 2010

Таким образом, здесь исправления, так как ваш C ++ неверен, что будет означать, что ваш код не будет работать.

sizeof (char *) - это размер указателя, а не длина строки.Таким образом, ваш snprintf будет печатать до 4 символов в 32-битной системе, которая будет содержать нулевой терминатор, так что вы фактически получите только строку длиной 3.

Если вы собираетесь использовать, "должно быть большимДостаточно "буфера", не выделяйте его новым.Вы можете использовать std :: vector, если хотите использовать snprintf, затем проверить возвращаемое значение snprintf, которое является длиной фактической строки, которая будет записана, а затем увеличить размер буфера, если необходимо (до возвращаемого значения + 1).

vector<char> buffer;
size_t required = 511; 
do 
{ 
    buffer.resize( required + 1 );
    required = snprintf( &buffer[0], buffer.size(), formatstr, ... );
}
while( required >= buffer.size() );

Нет необходимости «освобождать» буфер в конце (что, кстати, вы сделали неправильно), поскольку vector сделает это автоматически.

Теперь вы передаете & buffer [0] дляфункция, она будет указывать на строку с нулевым символом в конце и будет доступна для записи, если API требует char *, а не const char *.(однако libcurl принимает ... в качестве 3-го параметра для curl_easy_setopt, чтобы вы могли передавать «что угодно». Поэтому вам следует быть осторожным, поскольку компилятор не предупредит вас, если вы случайно передадите std :: stringстанд :: вектор).

...