我正在尝试向acounts.google.com发送一个get请求,以便能够为C ++ OAuth实现一个库来学习它。
我从这篇文章中获得了以下代码:Creating a HTTPS request using Boost Asio and OpenSSL并将其修改为:
int main()
{
try
{
std::string request = "/o/oauth2/v2/auth";
boost::system::error_code ec;
using namespace boost::asio;
// what we need
io_service svc;
ssl::context ctx(svc, ssl::context::method::sslv23_client);
ssl::stream<ip::tcp::socket> ssock(svc, ctx);
ip::tcp::resolver resolver(svc);
auto it = resolver.resolve({ "accounts.google.com", "443" }); // https://accouts.google.com:443
boost::asio::connect(ssock.lowest_layer(), it);
ssock.handshake(ssl::stream_base::handshake_type::client);
// send request
std::string fullResuest = "GET " + request + " HTTP/1.1\r\n\r\n";
boost::asio::write(ssock, buffer(fullResuest));
// read response
std::string response;
do
{
char buf[1024];
size_t bytes_transferred = ssock.read_some(buffer(buf), ec);
if (!ec) response.append(buf, buf + bytes_transferred);
std::cout << "Response received: '" << response << "'\n"; // I add this to see what I am getting from the server, so it should not be here.
} while (!ec);
// print and exit
std::cout << "Response received: '" << response << "'\n";
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
if (std::string const * extra = boost::get_error_info<my_tag_error_info>(e))
{
std::cout << *extra << std::endl;
}
}
}
我遇到的问题如下:
1-当我使用网络浏览器访问https://accounts.google.com/o/oauth2/v2/auth时,我得到的结果不是我得到的结果。我基本上收到一条消息,说他们找不到所请求的URL / o / oauth2 / v2 / auth
<p>The requested URL <code>/o/oauth2/v2/auth</code> was not found on this server. <ins>ThatÔÇÖs all we know.</ins>
我应该如何设置GET表示,以便获得与浏览器相同的结果?
2-应用程序挂起从服务器获取数据,显然以下循环不正确:
do
{
char buf[1024];
size_t bytes_transferred = ssock.read_some(buffer(buf), ec);
if (!ec) response.append(buf, buf + bytes_transferred);
} while (!ec);
从Web服务器读取响应的正确方法是什么?快速读取所有数据?
根据接受的答案进行参考,我使用正确的GET标题解决了问题,如下所示:
// send request
std::string fullResuest = "GET " + request + " HTTP/1.1\r\n";
fullResuest+= "Host: " + server + "\r\n";
fullResuest += "Accept: */*\r\n";
fullResuest += "Connection: close\r\n\r\n";
boost::asio::write(ssock, buffer(fullResuest));
答案 0 :(得分:0)
HTTP / 1.1请求必须具有Host
标头。使用OpenSSL的简单实验将显示问题,即缺少标题:
$ openssl s_client -connect accounts.google.com:443
...
GET /o/oauth2/v2/auth HTTP/1.1
... The requested URL <code>/o/oauth2/v2/auth</code> was not found on this server. <ins>That’s all we know.</ins>
添加Host
标题后,我们会得到不同的回复:
$ openssl s_client -connect accounts.google.com:443
...
GET /o/oauth2/v2/auth HTTP/1.1
Host: accounts.google.com
... >Required parameter is missing: response_type<
除了HTTP / 1.1隐式使用HTTP keep-alive之外,服务器和客户端可能会在响应完成后保持连接打开。这意味着您不应该在连接结束之前阅读,而应该正确解析HTTP标头,提取Content-length
标头和/或Transfer-Encoding
标头并根据其值进行操作。或者,如果您希望它更简单,请使用HTTP / 1.0。
有关详细信息,请参阅the HTTP/1.1 standard。