Skip to content

"400 Bad Request" using simple Graph API call over https #149

@bbogart

Description

@bbogart

I've been trying to get RESTC-CPP to work with the Meta Graph API and I can't get anywhere. My GET request is simple: "https://graph.facebook.com/v15.0/me?access_token=[token]"

this works fine if I paste it right in the browser, and also using curl in a terminal:

curl -v -i -X GET "https://graph.facebook.com/v15.0/me?access_token=[token]"

I thought it may be headers, so I tried sending the headers sent by the browser and also those sent by curl.

In all cases when I try and do this in RESTC-cpp I get the error:

Caught exception: Request failed with HTTP error: 400 Bad Request

Except when I used the encoding header:

.Header("Accept-Encoding", "gzip, deflate, br")

Which results in a different error message:

Caught exception: Unsupported compression.

Here is the output of my CURL call with verbose info (token redacted):


*   Trying 2a03:2880:f001:6:face:b00c:0:2:443...
* TCP_NODELAY set
*   Trying 157.240.3.20:443...
* TCP_NODELAY set
* Connected to graph.facebook.com (157.240.3.20) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=Menlo Park; O=Meta Platforms, Inc.; CN=*.facebook.com
*  start date: Jan  9 00:00:00 2023 GMT
*  expire date: Feb 13 23:59:59 2023 GMT
*  subjectAltName: host "graph.facebook.com" matched cert's "*.facebook.com"
*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55a05ff3e2f0)
> GET /v15.0/me?access_token=[token] HTTP/2
> Host: graph.facebook.com
> user-agent: curl/7.68.0
> accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
HTTP/2 200 
< etag: "bc30657262eee6b93b9aff07f8939bc14f5cd015"
etag: "bc30657262eee6b93b9aff07f8939bc14f5cd015"
< content-type: application/json; charset=UTF-8
content-type: application/json; charset=UTF-8
< vary: Origin
vary: Origin
< x-business-use-case-usage: {"100765302885321":[{"type":"pages","call_count":1,"total_cputime":1,"total_time":1,"estimated_time_to_regain_access":0}]}
x-business-use-case-usage: {"100765302885321":[{"type":"pages","call_count":1,"total_cputime":1,"total_time":1,"estimated_time_to_regain_access":0}]}
< x-fb-rlafr: 0
x-fb-rlafr: 0
< access-control-allow-origin: *
access-control-allow-origin: *
< facebook-api-version: v15.0
facebook-api-version: v15.0
< strict-transport-security: max-age=15552000; preload
strict-transport-security: max-age=15552000; preload
< pragma: no-cache
pragma: no-cache
< cache-control: private, no-cache, no-store, must-revalidate
cache-control: private, no-cache, no-store, must-revalidate
< expires: Sat, 01 Jan 2000 00:00:00 GMT
expires: Sat, 01 Jan 2000 00:00:00 GMT
< x-fb-request-id: AelbwCDPgnsSaCUH362jVHf
x-fb-request-id: AelbwCDPgnsSaCUH362jVHf
< x-fb-trace-id: GrY4l/GOYNg
x-fb-trace-id: GrY4l/GOYNg
< x-fb-rev: 1006914144
x-fb-rev: 1006914144
< x-fb-debug: cCFxQ+O2TeqKG8GkarpBJJxbOJR+GAPPPlbK/sSTdCY1R966Eo8d3Szj61aKBkmHDHbH9t3KkjCTO0wgpV15bA==
x-fb-debug: cCFxQ+O2TeqKG8GkarpBJJxbOJR+GAPPPlbK/sSTdCY1R966Eo8d3Szj61aKBkmHDHbH9t3KkjCTO0wgpV15bA==
< content-length: 54
content-length: 54
< date: Sat, 04 Feb 2023 20:00:33 GMT
date: Sat, 04 Feb 2023 20:00:33 GMT
< priority: u=3,i
priority: u=3,i
< alt-svc: h3=":443"; ma=86400
alt-svc: h3=":443"; ma=86400

< 
* Connection #0 to host graph.facebook.com left intact

The only thing that stands out to me is the explicit "HTTP/2"...

Here's my current code, token redacted:

/*   Build with: g++ gitExample.cpp -o gitExample -ggdb -std=c++14 `curl-config --libs` -lrestc-cpp -lz -lssl -lcrypto -lpthread -lboost_system -lboost_program_options -lboost_filesystem -lboost_date_time -lboost_context -lboost_coroutine -lboost_chrono -lboost_log -lboost_thread -lboost_log_setup -lboost_regex -lboost_atomic -lpthread 
*/

#include <iostream>
#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/RequestBuilder.h" 

using namespace std;
using namespace restc_cpp;


void DoSomethingInteresting(Context& ctx) {

    try {
        auto reply = RequestBuilder(ctx)
        .Get("https://graph.facebook.com/v15.0/me?access_token=[token]")

        // Add some headers for good taste
        .Header("content-type","application/json; charset=UTF-8")
        .Header("Host", "graph.facebook.com")
        .Header("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0")
        .Header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8")
        .Header("Accept-Language", "en-CA,en-US;q=0.7,en;q=0.3")
        //.Header("Accept-Encoding", "gzip, deflate, br")
        .Header("DNT", "1")
        .Header("Connection", "keep-alive")
        .Header("Upgrade-Insecure-Requests", "1")
        .Header("Sec-Fetch-Dest", "document")
        .Header("Sec-Fetch-Mode", "navigate")
        .Header("Sec-Fetch-Site", "none")
        .Header("Sec-Fetch-User", "?1")
        .Header("TE", "trailers")

        // Send the request
        .Execute();

        // Asynchronously fetch the entire data-set and return it as a string.
        auto json = reply->GetBodyAsString();

        // Just dump the data.
        cout << "Received data: " << json << endl;
        
    } catch (const exception& ex) {
        clog << "Caught exception: " << ex.what() << endl;
    }
}

int main() {

    // Create a REST client
    auto RESTClient = RestClient::Create();
    
    // Create a co-routine that runs in a thread
    RESTClient->Process( DoSomethingInteresting );

    // Wait for the thread to finish and return.
    RESTClient->CloseWhenReady(true);
    
    return 0;
}

Any help appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions