Как сделать GET-запрос к Cloudant из Erlang по HTTPS

Я уже некоторое время ломаю голову над этим ... Я могу получать и публиковать в CouchDB на своем локальном компьютере, но теперь я хочу переключиться на использование Cloudant, для которого требуется подключение через https.

Я хочу понять, что происходит, поэтому на данный момент предпочел бы использовать httpc или аналогичный, а не, скажем, диванный луч, но я просто не могу проникнуть в документацию Erlang по подключению через SSL, и любые примеры относятся к простому HTTP.. Cloudant, похоже, также не имеет какой-либо документации по Erlang.

Я просмотрел тему Как выполнить HTTPS-запрос с Erlang, но приведенный пример у меня не работает - я получаю следующий отчет об ошибке:


ฐ=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,
                            {[],[]},
                            {[],[]},
                            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}]}

а оболочка Erlang виснет...

Вот код, который я ввожу в оболочке Erlang:


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}]}], []).

Для строки 3 я также пробовал следующее:

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", []} , [], []).

Я без проблем могу подключиться к https://playground.cloudant.com из браузера.

Я, очевидно, что-то упускаю здесь, но не могу понять, что именно. Что мне нужно сделать с SSL? Какие-нибудь конфигурационные файлы, которые я должен хранить в определенном месте? Любая помощь будет высоко ценится!


person Alfamale    schedule 10.05.2011    source источник
comment
Я рассказал о своих приключениях в этой области более подробно в этом сообщении в блоге для всех, кто заинтересован: andrewlocatelliwoodcock.com/2012/06/12/   -  person Alfamale    schedule 12.06.2012


Ответы (2)


Попробуй это:

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>

Это может предоставить вам дополнительную информацию. Ваша последовательность работает для меня из коробки.

person Victor Moroz    schedule 10.05.2011
comment
хммм... очевидно, что-то не так с моей настройкой, потому что вот что происходит в оболочке Erlang, когда я запускаю вышеописанное: 1> ssl:start(). ок 2› где (ssl_sup). ‹0.42.0› 3› supervisor:start_child(ssl_sup, {ssl_server, {ssl_server, start_link, []}, постоянный, 2000, рабочий, [ssl_server]}). {ошибка,{обычный,{дочерний,неопределенный,ssl_server, {ssl_server,start_link,[]}, постоянный,2000,рабочий, [ssl_server]}}} 4› - person Alfamale; 10.05.2011
comment
Затем вы можете попробовать запустить Erlang как erl -ssl edebug true, он покажет некоторую отладочную информацию. - person Victor Moroz; 11.05.2011

Давно собирался обновить это. Похоже, что мои сертификаты CA могли быть неверными, поскольку после обновления пакета сертификатов CA с помощью curl и обновления до Erlang R15B1 приведенный выше пример начал работать для меня. Так что, похоже, это была проблема с настройкой.

И, на заметку, вот httpc-запрос для получения всех баз данных из экземпляра Cloudant по HTTPS:

httpc:request
    (get, 
    {"https://" ++ username() ++ ":" ++ password() ++ "@" ++ username() ++ ".cloudant.com/_all_dbs", []}, 
    [{ssl,[{verify,0}]}], 
    []).

где функции username() и password() соответственно возвращают ваше имя пользователя и пароль Cloudant.

person Alfamale    schedule 12.06.2012