2017-05-01 2 views
0

Ich versuche, eine Abrufanforderung an acounts.google.com zu senden, um eine Bibliothek für C++ OAuth implementieren zu können.Senden eines GET-Befehls an einen SSL-Server, um das Ergebnis zu erhalten

ich den folgenden Code aus diesem Post bekommen: Creating a HTTPS request using Boost Asio and OpenSSL und modifiziert es wie folgt:

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; 
     } 
    } 

} 

Das Problem, das ich habe, ist wie folgt:

1- Die Ergebnisse, die ich bekommen habe ist nicht Was ich bekomme, wenn ich https://accounts.google.com/o/oauth2/v2/auth mit einem Webbrowser besuche. Ich immer im Wesentlichen eine Nachricht, dass sie nicht die angeforderte URL finden/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> 

Wie sollte ich Setup die GET lobe, so kann ich das gleiche Ergebnis, dass ich mit einem Browser immer bin?

2- Die Anwendung hängt von Server Abrufen von Daten, offenbar die folgende Schleife ist nicht richtig:

do 
{ 
     char buf[1024]; 
     size_t bytes_transferred = ssock.read_some(buffer(buf), ec); 
     if (!ec) response.append(buf, buf + bytes_transferred); 
} while (!ec); 

Was ist der richtige Weg, Antwort-vom Webserver des Lesens, das schnell ist und alle Daten lesen?

Edit 1

Als Referenz auf akzeptierte Antwort basiert, fest ich das Problem des korrekten GET-Headers, wie unten dargestellt:

// 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

Eine HTTP/1.1-Anfrage * muss * einen 'Host'-Header haben, der offensichtlich fehlt. –

+0

@SteffenUllrich Danke, Wie kann ich es beheben? – mans

Antwort

0

A HTTP/1.1-Anforderung einen Host Header muss . Ein einfaches Experiment mit OpenSSL wird das Problem zeigen, das heißt die fehlenden Header:

$ 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> 

Beim Hinzufügen des Host Header stattdessen wir eine andere Antwort erhalten:

$ 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< 

Abgesehen davon, dass HTTP/1.1 implizit verwendet HTTP keep-alive, dh Server und Client können die Verbindung nach der Antwort offen halten. Dies bedeutet, dass Sie nicht bis zum Ende der Verbindung lesen sollten, sondern stattdessen den HTTP-Header richtig analysieren, den Header Content-length und/oder den Header Transfer-Encoding extrahieren und sich entsprechend ihrer Werte verhalten sollten. Oder wenn Sie es einfacher wollen, verwenden Sie stattdessen HTTP/1.0.

Weitere Informationen finden Sie unter the HTTP/1.1 standard.

Verwandte Themen