How to make a GET request to Cloudant from Erlang over HTTPS
I've been bashing my head off this one for a while now ... I am able to get and post to couchdb on my local machine but now I want to switch to using Cloudant which requires a connection over https.
I want to understand what's going on, so would prefer to use httpc or similar for the moment rather than, say, couchbeam but I just can't seem to penetrate the Erlang documentation around connecting over SSL and any examples are over plain HTTP ... Cloudant don't seem to have any Erlang-specific documentation either.
I have looked at the topic How do I do an HTTPS request with Erlang but the example given is not working for me - I get the following error report:
ฐ=ERROR REPORT==== 10-May-2011::10:40:26 ===
** Generic server <0.60.0> terminating
** Last message in was {connect_and_send,
{request,#Ref<0.0.0.50>,<0.31.0>,0,https,
{"playground.cloudant.com",443},
"/",[],get,
{http_request_h,undefined,"keep-alive",
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,
"playground.cloudant.com",undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,[],
undefined,undefined,undefined,undefined,
"0",undefined,undefined,undefined,
undefined,undefined,undefined,[]},
{[],[]},
{http_options,"HTTP/1.1",infinity,true,
{ossl,[{verify,0}]},
undefined,false,infinity,false},
"https://playground.cloudant.com",[],none,[],
1305020425911,undefined,undefined}}
** When Server state == {state,undefined,undefined,undefined,undefined,
undefined,undefined,
{[],[]},
开发者_如何学Go {[],[]},
undefined,[],nolimit,nolimit,
{options,
{undefined,[]},
0,2,5,120000,2,disabled,false,inet,default,
default,[]},
{timers,[],undefined},
httpc_manager,undefined}
** Reason for termination ==
** {{badmatch,{error,no_ssl_server}},
[{ssl,old_connect,4},
{httpc_handler,connect_and_send_first_request,3},
{httpc_handler,handle_call,3},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}
and the Erlang shell hangs ...
Here's the code I am entering in the Erlang shell:
Running Erlang
Eshell V5.8.3 (abort with ^G)
1> inets:start().
ok
2> ssl:start().
ok
3> httpc:request(head, {"https://playground.cloudant.com", []}, [{ssl,[{verify,0}]}], []).
For line 3, I have also tried the following:
3> httpc:request(head, {"https://playground.cloudant.com", []}, [], []).
3> httpc:request(get, {"https://playground.cloudant.com", []}, [{ssl,[{verify,0}]}], []).
3> httpc:request(get, {"https://playground.cloudant.com", []}, [], []).
I can connect to https://playground.cloudant.com no problem from a browser.
I am obviously missing something here but can't for the life of me figure out what. Anything I need to do with SSL? Any config files I should have sitting in a specific place? Any help will be much appreciated!
Try this:
1> ssl:start().
ok
2> whereis(ssl_sup).
<0.42.0>
3> supervisor:start_child(ssl_sup, {ssl_server, {ssl_server, start_link, []}, permanent, 2000, worker, [ssl_server]}).
{ok,<0.48.0>}
4> whereis(ssl_server).
<0.48.0>
It may provide you with additional info. Your sequence works for me out of the box.
Been meaning to update this for a while. It seems that my CA certs may have been incorrect as after updating the CA cert bundle with curl and updating to Erlang R15B1, the example above started working for me. So this seems to have been a setup issue.
And as a matter of note, here's an httpc request to get all databases from an instance of Cloudant over HTTPS:
httpc:request
(get,
{"https://" ++ username() ++ ":" ++ password() ++ "@" ++ username() ++ ".cloudant.com/_all_dbs", []},
[{ssl,[{verify,0}]}],
[]).
where the functions username() and password() respectively return your Cloudant username and password.
精彩评论