Logging into Reddit and authenticating with python works fine:
import requests
base_url = 'https://www.reddit.com/'
data = {'grant_type': 'password', 'username': 'glibg10b', 'password': '<login_password>'}
auth = requests.auth.HTTPBasicAuth('<app_key>', '<secret_key>')
res = requests.post(base_url + 'api/v1/access_token', data=data, headers={'user-agent': 'api-test by glibg10b'}, auth=auth)
print(res.status_code) # Prints 200
But doing the same in C++ with cpp-httplib doesn't work:
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
int main()
{
httplib::Client bot{ "https://www.reddit.com/" };
bot.set_basic_auth("<app_key>", "<secret_key>");
httplib::Headers headers{
{ "user-agent", "api-test by glibg10b" }
};
httplib::MultipartFormDataItems items{
{ "grant_type", "password", "", "" },
{ "username", "glibg10b", "", "" },
{ "password", "<login_password>", "", "" }
};
auto res{ bot.Post("/api/v1/access_token", headers, items) };
if (res)
std::cout << res->status << '\n';
else
std::cout << to_string(res.error()) << '\n'; // "Connection"
}
Am I missing something?
Edit: Full backtrace when error
changes from Error::Success
to Error::Connection
:
#0 httplib::detail::create_client_socket(char const*, char const*, int, int, bool, std::function<void (int)>, long, long, long, long, long, long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, httplib::Error&) (
host=0x55555564d4a0 "https://www.reddit.com/", ip=0x7fffffffd600 "", port=80, address_family=0, tcp_nodelay=false, socket_options=..., connection_timeout_sec=300, connection_timeout_usec=0, read_timeout_sec=5, read_timeout_usec=0,
write_timeout_sec=5, write_timeout_usec=0, intf="br0", error=@0x7fffffffd8c4: httplib::Error::Success) at /home/waldo/sources/reddit-api-test/httplib.h:2744
sock = -1
#1 0x0000555555571b74 in httplib::ClientImpl::create_client_socket (this=0x55555564db80, error=@0x7fffffffd8c4: httplib::Error::Success) at /home/waldo/sources/reddit-api-test/httplib.h:5821
ip = ""
it =
{first = "", second = "\000\000\000\000UU\000\000\000\000\000\000\000\000\000\000\200\334dUUU\000\000\200\334dUUU\000\000\000\000\000\000\000\000\000\000\270\334dUUU", '\000' <repeats 11 times>, "\332\377\377\377\177\000\000\n\000\000\000\377\177(\000\330\334dUUU", '\000' <repeats 11 times>, "\003[UUU\000\000\300\332\377\377\022\000\000\000,\001", '\000' <repeats 14 times>, "\005", '\000' <repeats 15 times>, "\005", '\000' <repeats 15 times>, "\020\177dUUU\000\000\026\000\000\000\000\000\000\000\036\000\000\000\000\000\000\000\340\326\377\377\377\177\000\000@\214dUUU\000\000\036\000\000\000\000\000\000\000"...}
#2 0x0000555555571c27 in httplib::ClientImpl::create_and_connect_socket (this=0x55555564db80, socket=..., error=@0x7fffffffd8c4: httplib::Error::Success) at /home/waldo/sources/reddit-api-test/httplib.h:5830
sock = 21845
#3 0x0000555555572473 in httplib::ClientImpl::send (this=0x55555564db80, req=..., res=..., error=@0x7fffffffd8c4: httplib::Error::Success) at /home/waldo/sources/reddit-api-test/httplib.h:5930
guard = {_M_device = @0x55555564dbe0}
is_alive = false
request_mutex_guard = {_M_device = @0x55555564dc08}
__PRETTY_FUNCTION__ = "bool httplib::ClientImpl::send(httplib::Request&, httplib::Response&, httplib::Error&)"
close_connection = 62
ret = false
#4 0x0000555555574e0b in httplib::ClientImpl::send_with_content_provider(httplib::Request&, char const*, unsigned long, std::function<bool (unsigned long, unsigned long, httplib::DataSink&)>, std::function<bool (unsigned long, httplib::DataSink&)>, char const*, httplib::Error&) (this=0x55555564db80, req=...,
body=0x55555564eef0 "----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"u"...,
content_length=385, content_provider=..., content_provider_without_length=..., content_type=0x55555564b170 "multipart/form-data; boundary=--cpp-httplib-multipart-data-icoEgIbPrIoB25S3", error=@0x7fffffffd8c4: httplib::Error::Success)
at /home/waldo/sources/reddit-api-test/httplib.h:6342
res = std::unique_ptr<httplib::Response> = {get() = 0x555555648c90}
#5 0x000055555557500a in httplib::ClientImpl::send_with_content_provider(char const*, char const*, std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, httplib::detail::ci, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&, char const*, unsigned long, std::function<bool (unsigned long, unsigned long, httplib::DataSink&)>, std::function<bool (unsigned long, httplib::DataSink&)>, char const*) (this=0x55555564db80, method=0x5555555d9a48 "POST",
path=0x5555555da36f "/api/v1/access_token", headers=std::multimap with 1 element = {...},
body=0x55555564eef0 "----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"u"...,
content_length=385, content_provider=..., content_provider_without_length=..., content_type=0x55555564b170 "multipart/form-data; boundary=--cpp-httplib-multipart-data-icoEgIbPrIoB25S3") at /home/waldo/sources/reddit-api-test/httplib.h:6361
req = {method = "POST", path = "/api/v1/access_token", headers = std::multimap with 2 elements = {["Content-Type"] = "multipart/form-data; boundary=--cpp-httplib-multipart-data-icoEgIbPrIoB25S3", ["user-agent"] = "api-test by glibg10b"},
body = "----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"u"..., remote_addr = "",
remote_port = -1, version = "", target = "", params = std::multimap with 0 elements, files = std::multimap with 0 elements, ranges = std::vector of length 0, capacity 0,
matches = {<std::vector<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >> = std::vector of length 0, capacity 0, _M_begin = non-dereferenceable iterator for std::vector},
response_handler = {<std::_Maybe_unary_or_binary_function<bool, httplib::Response const&>> = {<std::unary_function<httplib::Response const&, bool>> = {<No data fields>}, <No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x0, _M_const_object = 0x0, _M_function_pointer = 0x0, _M_member_pointer = NULL}, _M_pod_data = '\000' <repeats 15 times>}, _M_manager = 0x0}, _M_invoker = 0x0},
content_receiver = {<std::_Maybe_unary_or_binary_function<bool, char const*, unsigned long, unsigned long, unsigned long>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16, static _M_max_align = 8, _M_functor = {
_M_unused = {_M_object = 0x0, _M_const_object = 0x0, _M_function_pointer = 0x0, _M_member_pointer = NULL}, _M_pod_data = '\000' <repeats 15 times>}, _M_manager = 0x0}, _M_invoker = 0x0},
progress = {<std::_Maybe_unary_or_binary_function<bool, unsigned long, unsigned long>> = {<std::binary_function<unsigned long, unsigned long, bool>> = {<No data fields>}, <No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x0, _M_const_object = 0x0, _M_function_pointer = 0x0, _M_member_pointer = NULL}, _M_pod_data = '\000' <repeats 15 times>}, _M_manager = 0x0}, _M_invoker = 0x0}, ssl = 0x0,
redirect_count_ = 20, content_length_ = 0, content_provider_ = {<std::_Maybe_unary_or_binary_function<bool, unsigned long, unsigned long, httplib::DataSink&>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x0, _M_const_object = 0x0, _M_function_pointer = 0x0, _M_member_pointer = NULL}, _M_pod_data = '\000' <repeats 15 times>}, _M_manager = 0x0}, _M_invoker = 0x0},
is_chunked_content_provider_ = false, authorization_count_ = 0}
error = httplib::Error::Success
res = std::unique_ptr<httplib::Response> = {get() = 0xc9c0073e}
#6 0x0000555555575ae3 in httplib::ClientImpl::Post (this=0x55555564db80, path=0x5555555da36f "/api/v1/access_token", headers=std::multimap with 1 element = {...},
body="----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"u"...,
content_type=0x55555564b170 "multipart/form-data; boundary=--cpp-httplib-multipart-data-icoEgIbPrIoB25S3") at /home/waldo/sources/reddit-api-test/httplib.h:6622
No locals.
#7 0x0000555555576166 in httplib::ClientImpl::Post (this=0x55555564db80, path=0x5555555da36f "/api/v1/access_token", headers=std::multimap with 1 element = {...}, items=std::vector of length 3, capacity 3 = {...},
boundary="--cpp-httplib-multipart-data-icoEgIbPrIoB25S3") at /home/waldo/sources/reddit-api-test/httplib.h:6702
body = "----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n----cpp-httplib-multipart-data-icoEgIbPrIoB25S3\r\nContent-Disposition: form-data; name=\"u"...
content_type = "multipart/form-data; boundary=--cpp-httplib-multipart-data-icoEgIbPrIoB25S3"
#8 0x0000555555575ba4 in httplib::ClientImpl::Post (this=0x55555564db80, path=0x5555555da36f "/api/v1/access_token", headers=std::multimap with 1 element = {...}, items=std::vector of length 3, capacity 3 = {...})
at /home/waldo/sources/reddit-api-test/httplib.h:6671
No locals.
#9 0x0000555555578d53 in httplib::Client::Post (this=0x7fffffffde30, path=0x5555555da36f "/api/v1/access_token", headers=std::multimap with 1 element = {...}, items=std::vector of length 3, capacity 3 = {...})
at /home/waldo/sources/reddit-api-test/httplib.h:7945
No locals.
#10 0x000055555555f178 in main () at main.cpp:20
bot = {cli_ = std::unique_ptr<httplib::ClientImpl> = {get() = 0x55555564db80}, is_ssl_ = false}
headers = std::multimap with 1 element = {["user-agent"] = "api-test by glibg10b"}
items = std::vector of length 3, capacity 3 = {{name = "grant_type", content = "password", filename = "", content_type = ""}, {name = "username", content = "glibg10b", filename = "", content_type = ""}, {name = "password", content = "<login_password>",
filename = "", content_type = ""}}
res = {res_ = std::unique_ptr<httplib::Response> = {get() = 0x5b0000006e}, err_ = 4158279269, request_headers_ = std::multimap with 564 elements<error reading variable: Cannot access memory at address 0xffffffffffffffb0>}
After a whole day of searching for the answer, it turns out that I had to remove the trailing slash from "www.reddit.com/".