使用CURL进行GET请求

尼尔斯J.

我的Minecraft服务器程序遇到了这个令人讨厌的问题。当您尝试登录我的Minecraft服务器时,我尝试从minecraft.com获得登录响应。一切都很好,可以进行设置,例如验证令牌密钥和共享机密。

我只是无法获得获取请求以使用curl :(

这就是我所拥有的:

    requestString.append("GET /session/minecraft/hasJoined?username=");
    requestString.append(player.Username);
    requestString.append("&");
    requestString.append("serverId=");
    requestString.append(player.loginHash);
    requestString.append(" HTTP/1.0\r\n");
    std::cout << requestString << std::endl;


    curl_easy_setopt(curl, CURLOPT_URL, "https://sessionserver.mojang.com");
    list = curl_slist_append(list, requestString.c_str());
    list = curl_slist_append(list, "User-Agent: MinecraftServerPP\r\n");
    list = curl_slist_append(list, "Connection: close\r\n");
    list = curl_slist_append(list, "\r\n");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
    curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem");

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &_write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

我从服务器上获得了成功,但没有包含所需数据的json对象。

雷米·勒博(Remy Lebeau)

为什么将GET请求行放在HTTP标头中?它根本不属于那里,实际上libCURL文档甚至指出了这一点:

CURLOPT_HTTPHEADER的解释

请求中的第一行(包含方法,通常是GET或POST)不是标头,因此无法使用此选项替换。仅请求行之后的行是标头。在此标题列表中添加此方法行只会导致您的请求发送无效的标题使用CURLOPT_CUSTOMREQUEST更改方法。

您当前的代码正在发送GET与此类似的请求:

GET / HTTP / 1.1
主持人:sessionserver.mojang.com
GET / session / minecraft / hasJoined?username = <用户名>&serverId = <loginHash> HTTP / 1.0
用户代理:MinecraftServerPP
连接方式:关闭

这就是为什么您没有得到期望的响应的原因。您实际上不是在请求/session/minecraft/hasJoined资源,而是在实际上在请求根/资源。

您应该发送这样的GET请求:

GET / session / minecraft / hasJoined?username = <用户名>&serverId = <loginHash> HTTP / 1.0
主持人:sessionserver.mojang.com
用户代理:MinecraftServerPP
连接方式:关闭

为此,您需要将完整的URL传递CURLOPT_URLlibCURL并GET为您处理该行。您可以使用CURLOPT_HTTPGET以确保GET实际使用。

另外,CURLOPT_HTTP_VERSION如果要指定特定的HTTP版本,则应该使用

此外,虽然你可以使用CURLOPT_HTTPHEADERUser-AgentConnection标题,你应该是使用CURLOPT_USERAGENTCURLOPT_FORBID_REUSE替代。

尝试以下方法:

url = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=");
url.append(player.Username); // <-- NOTE: see further below!
url.append("&serverId=");
url.append(player.loginHash); // <-- NOTE: see further below!
std::cout << url << std::endl;

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); 
curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem");

curl_easy_setopt(curl, CURLOPT_USERAGENT, "MinecraftServerPP");

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &_write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

如此说来,您还需要考虑其他逻辑以正确处理CURLOPT_URL

传递指向要使用的URL的指针。该参数应该是一个char *到一个零终止的字符串,该字符串必须以以下格式进行URL编码

scheme://主机:端口/路径

有关格式的更多说明,请参见RFC 3986

在发出传输之前,libcurl不会验证语法或使用此变量。即使您在此处设置了一个疯狂的值,curl_easy_setopt仍会返回CURLE_OK

特别是,RFC的以下部分与您的代码有关:

2.1。百分比编码

当八位字节的相应字符在允许的集合之外或用作组件的定界符或在组件之内时,百分比编码机制用于表示该组件中的数据八位字节百分比编码的八位位组被编码为一个字符三元组,由百分比字符“%”组成,后跟代表该八位位组的数值的两个十六进制数字。例如,“%20”是二进制八位字节“ 00100000”(ABNF:%x20)的百分比编码,它在US-ASCII中对应于空格字符(SP)。第2.4节介绍了何时应用百分比编码和解码。

pct编码=“%”十六进制十六进制

大写十六进制数字“ A”至“ F”分别等效于小写数字“ a”至“ f”。如果两个URI仅在百分比编码的八位字节中使用的十六进制数字有所不同,则它们是等效的。为了保持一致性,URI生产者和规范化者应对所有百分比编码使用大写十六进制数字。

2.4。何时编码或解码

在正常情况下,唯一的一次对URI中的八位字节进行百分比编码是在从其组成部分生成URI的过程中。这是在实现确定哪些保留字符用作子组件定界符以及哪些可以安全用作数据时。一旦生成,URI始终采用百分比编码形式。

取消引用URI时,必须对方案特定的取消引用过程(如果有的话)重要的组件和子组件进行解析和分离,然后才能安全地解码这些组件中的百分比编码八位字节,否则可能会将数据误认为组件定界符。唯一的例外是与未保留集中的字符相对应的百分比编码八位字节,可以随时对其进行解码。例如,对应于波浪号(​​“〜”)字符的八位字节通常由较早的URI处理实现编码为“%7E”;可以将“%7E”替换为“〜”,而无需更改其解释。

因为百分号(“%”)用作百分号编码八位位组的指示符,所以必须将该百分号编码为“%25”才能将该八位位组用作URI中的数据。实现不得多次对同一字符串进行百分比编码或解码,因为对已解码的字符串进行解码可能会导致将百分比数据八位位组误解为百分比编码的开始,反之亦然。百分比编码的字符串。

queryURL组成部分在3.4节中定义

查询= *(pchar /“ /” /“?”)

pchar第3.3节中定义

pchar =保留/ pct编码/ sub-delims /“:” /“ @”

unreserved第2.3节中定义

未保留= ALPHA / DIGIT /“-” /“。/“ _” /“〜”

sub-delims第2.2节中定义

sub-delims =“!” /“ $” /“&” /“'” /“(” /“)” /“ *” /“ +” /“,” /“;” /“ =”

因此,如果您的player.Usernameplayer.loginHash字符串中的任何字符不在这些允许的字符范围内,则在将它们放入URL的查询字符串时必须对它们进行百分比编码。例如:

std::string encodeForUrlQuery(std::string s)
{
    static const char* allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&'()*+,;=:@/?";

    // this is just an example, in practice you should first convert the
    // input string to Unicode and charset-encode it, usually to UTF-8,
    // and then percent-encode the resulting octets...

    std::string::size_type idx = s.find_first_not_of(allowed);
    while (idx != std::string::npos)
    {
        std::ostringstream oss;
        oss << '%' << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (int)s[idx];
        std::string encoded = oss.str();
        s.replace(idx, 1, encoded);
        idx = s.find_first_not_of(allowed, idx+encoded.length());
    }
    return s;
}

url = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=");
url.append(encodeForUrlQuery(player.Username));
url.append("&serverId=");
url.append(encodeForUrlQuery(player.loginHash));
std::cout << url << std::endl;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用CURL发出带有查询参数的GET请求

来自分类Dev

如何正确使用Siege对GET请求进行基准测试?

来自分类Dev

如何使用AFNetworking-2.0进行JSON编码的GET请求?

来自分类Dev

使用AFNetwork进行GET请求并保存响应

来自分类Dev

如何使用cURL在PHP中同时使用GET和POST参数发出请求?

来自分类Dev

使用boost :: asio发送HTTP GET请求,类似于cURL

来自分类Dev

在PHP中使用file_get_contents进行PUT请求的错误请求

来自分类Dev

PHP在URL中使用cURL和GET请求

来自分类Dev

如何使用curl在php中调试get请求

来自分类Dev

强制cURL在代理上对HTTPs请求使用GET

来自分类Dev

php curl -X GET与请求正文

来自分类Dev

使用XMLHttpRequest对var进行get请求,但还会创建回车

来自分类Dev

如何使用线程处理多个GET请求并进行比较

来自分类Dev

为什么我在使用Guzzle进行多个请求时遇到cURL错误77?

来自分类Dev

如何使用GraphQL Yoga进行多个嵌套查询(GET请求)?

来自分类Dev

如何在请求正文中使用JSON进行GET请求

来自分类Dev

使用curl模拟HTTP请求

来自分类Dev

尝试使用NSURL在objC中进行GET请求

来自分类Dev

使用curl放置请求

来自分类Dev

在PHP中使用file_get_contents进行PUT请求的错误请求

来自分类Dev

在GET请求中进行for循环

来自分类Dev

使用cURL命令进行POST,并在请求中嵌入数据

来自分类Dev

我如何使用Node.js请求模块进行curl调用

来自分类Dev

PHP Curl GET 请求不返回数据

来自分类Dev

如果我使用 Ajax 进行 http 请求,curl `-u` 可以转换成什么?

来自分类Dev

使用 Curl PHP 的 Soap 请求

来自分类Dev

使用 curl 请求 mysql

来自分类Dev

在 CURL 中使用参数的 GET 请求

来自分类Dev

如何使用 Get 请求对附加参数进行绑定

Related 相关文章

热门标签

归档