Skip to content
This repository
Browse code

add basic authentification and proxy support :

1> couchbeam:start().
2> Server = couchbeam:server_connection("localhost", 5984, "",
[{basic_auth, {"guest", "test"}}]).
{server,"localhost",5984,false,[],
        [{basic_auth,{"guest","test"}}]}
3> {ok, Db} = couchbeam:create_db(Server, "mydb").
  • Loading branch information...
commit bc200e3cf6f0969e497101534b081ab6bf41c370 1 parent 953dfcc
Benoit Chesneau authored October 09, 2010
14  include/couchbeam.hrl
@@ -21,23 +21,15 @@
21 21
 -type headers() :: [header()].
22 22
 %% In R13B bool() is now called boolean()
23 23
 %% Uncomment if it's not compiling.
24  
-%% -type boolean() :: bool().
  24
+%% -type boolean() :: bool()
25 25
 
26  
--record(options, {
27  
-    username = nil :: string(),
28  
-    password = nil :: string(),
29  
-    headers = [] :: iolist(),
30  
-    auth :: iolist()
31  
-}).
32  
-
33  
--type options() :: #options{}.
34 26
 
35 27
 -record(server, {
36 28
     host :: string(),
37 29
     port :: integer(),
38 30
     ssl :: boolean(),
39 31
     prefix :: string(),
40  
-    options :: options()
  32
+    options = [] :: list()
41 33
 }).
42 34
 
43 35
 -type server() :: #server{}.
@@ -46,7 +38,7 @@
46 38
 -record(db, {
47 39
     server :: server(),
48 40
     name :: string(),
49  
-    options :: options()
  41
+    options = [] :: list()
50 42
 }).
51 43
 
52 44
 -type db() :: #db{}.
141  src/couchbeam.erl
@@ -28,9 +28,9 @@
28 28
 
29 29
 %% utilities urls 
30 30
 -export([server_url/1, uuids_url/1, db_url/1, doc_url/2, make_url/3]).
31  
--export([request/3, request/4, request/5,
32  
-         request_stream/3, request_stream/4, request_stream/5,
33  
-         db_request/3, db_request/4, db_request/5]).
  31
+-export([request/4, request/5, request/6,
  32
+         request_stream/4, request_stream/5, request_stream/6,
  33
+         db_request/4, db_request/5, db_request/6]).
34 34
 
35 35
 %% API urls
36 36
 -export([server_connection/0, server_connection/2, server_connection/4,
@@ -141,7 +141,25 @@ server_connection(Host, Port, Prefix, Options) ->
141 141
 %%
142 142
 %%      If ssl is set https is used.
143 143
 %%
144  
-%% @spec server_connection(string(), integer(), string(), options(), boolean()) -> server() 
  144
+%%      For a description of SSL Options, look in the <a href="http://www.erlang.org/doc/apps/ssl/index.html">ssl</a> manpage. 
  145
+%%
  146
+%% @spec server_connection(Host::string(), Port::integer(),
  147
+%%                        Prefix::string(), Options::optionList(),
  148
+%%                        Ssl:boolean()) -> Server::server()
  149
+%% optionList() = [option()]
  150
+%% option() = 
  151
+%%          {ssl_options, [SSLOpt]}            |
  152
+%%          {pool_name, atom()}                |
  153
+%%          {proxy_host, string()}             |
  154
+%%          {proxy_port, integer()}            |
  155
+%%          {proxy_user, string()}             |
  156
+%%          {proxy_password, string()}         |
  157
+%%          {basic_auth, {username(), password()}} |
  158
+%%          {cookie, string()}}
  159
+%%
  160
+%% username() = string()
  161
+%% password() = string()
  162
+%% SSLOpt = term()
145 163
 server_connection(Host, Port, Prefix, Options, Ssl) when is_binary(Port) ->
146 164
     server_connection(Host, binary_to_list(Port), Prefix, Options, Ssl);
147 165
 server_connection(Host, Port, Prefix, Options, Ssl) when is_list(Port) ->
@@ -152,9 +170,9 @@ server_connection(Host, Port, Prefix, Options, Ssl) ->
152 170
 
153 171
 %% @doc Get Information from the server
154 172
 %% @spec server_info(server()) -> iolist()
155  
-server_info(Server) ->
  173
+server_info(#server{options=IbrowseOpts}=Server) ->
156 174
     Url = binary_to_list(iolist_to_binary(server_url(Server))),
157  
-    case request(get, Url, ["200"]) of
  175
+    case request(get, Url, ["200"], IbrowseOpts) of
158 176
         {ok, _Status, _Headers, Body} ->
159 177
             Version = couchbeam_util:json_decode(Body),
160 178
             {ok, Version};
@@ -173,9 +191,9 @@ get_uuids(Server, Count) ->
173 191
  
174 192
 %% @doc get list of databases on a CouchDB node 
175 193
 %% @spec all_dbs(server()) -> iolist()
176  
-all_dbs(Server) ->
  194
+all_dbs(#server{options=IbrowseOpts}=Server) ->
177 195
     Url = make_url(Server, "_all_dbs", []),
178  
-    case request(get, Url, ["200"]) of
  196
+    case request(get, Url, ["200"], IbrowseOpts) of
179 197
         {ok, _, _, Body} ->
180 198
             AllDbs = couchbeam_util:json_decode(Body),
181 199
             {ok, AllDbs};
@@ -185,9 +203,9 @@ all_dbs(Server) ->
185 203
 
186 204
 %% @doc test if db with dbname exists on the CouchDB node
187 205
 %% @spec db_exists(server(), string()) -> boolean()
188  
-db_exists(Server, DbName) ->
  206
+db_exists(#server{options=IbrowseOpts}=Server, DbName) ->
189 207
     Url = make_url(Server, DbName, []),
190  
-    case request(head, Url, ["200"]) of
  208
+    case request(head, Url, ["200"], IbrowseOpts) of
191 209
         {ok, _, _, _} -> true;
192 210
         _Error -> false
193 211
     end.
@@ -209,10 +227,11 @@ create_db(Server, DbName, Options) ->
209 227
 %%
210 228
 %%      If ssl is set https is used.
211 229
 %%
212  
-%% @spec create_db(sserver(), string(), options(), list()) -> db() 
213  
-create_db(Server, DbName, Options, Params) ->
  230
+%% @spec create_db(Server::server(), DbName::string(),
  231
+%%                 Options::optionList(), Params::list()) -> db() 
  232
+create_db(#server{options=IbrowseOpts}=Server, DbName, Options, Params) ->
214 233
     Url = make_url(Server, DbName, Params),
215  
-    case request(put, Url, ["201"]) of
  234
+    case request(put, Url, ["201"], IbrowseOpts) of
216 235
         {ok, _Status, _Headers, _Body} ->
217 236
             {ok, #db{server=Server, name=DbName, options=Options}};
218 237
         {error, {ok, "412", _, _}} ->
@@ -247,9 +266,9 @@ open_or_create_db(Server, DbName, Options) ->
247 266
 %% @doc Create a client for connecting to a database and create the
248 267
 %%      database if needed.
249 268
 %% @spec open_or_create_db(server(), string(), list(), list()) -> db()
250  
-open_or_create_db(Server, DbName, Options, Params) ->
  269
+open_or_create_db(#server{options=IbrowseOpts}=Server, DbName, Options, Params) ->
251 270
     Url = make_url(Server, DbName, []),
252  
-    case request(get, Url, ["200"]) of
  271
+    case request(get, Url, ["200"], IbrowseOpts) of
253 272
         {ok, _, _, _} ->
254 273
             open_db(Server, DbName, Options);
255 274
         {error, {ok, "404", _, _}} ->
@@ -265,9 +284,9 @@ delete_db(#db{server=Server, name=DbName}) ->
265 284
 
266 285
 %% @doc delete database 
267 286
 %% @spec delete_db(server(), DbName) -> iolist()
268  
-delete_db(Server, DbName) ->
  287
+delete_db(#server{options=IbrowseOpts}=Server, DbName) ->
269 288
     Url = make_url(Server, DbName, []),
270  
-    case request(delete, Url, ["200"]) of
  289
+    case request(delete, Url, ["200"], IbrowseOpts) of
271 290
         {ok, _, _, Body} ->
272 291
             {ok, couchbeam_util:json_decode(Body)};
273 292
         Error ->
@@ -276,9 +295,9 @@ delete_db(Server, DbName) ->
276 295
 
277 296
 %% @doc get database info
278 297
 %% @spec db_info(db()) -> iolist()
279  
-db_info(#db{server=Server, name=DbName}) ->
  298
+db_info(#db{server=Server, name=DbName, options=IbrowseOpts}) ->
280 299
     Url = make_url(Server, DbName, []),
281  
-    case request(get, Url, ["200"]) of
  300
+    case request(get, Url, ["200"], IbrowseOpts) of
282 301
         {ok, _Status, _Headers, Body} ->
283 302
             Infos = couchbeam_util:json_decode(Body),
284 303
             {ok, Infos}; 
@@ -290,10 +309,10 @@ db_info(#db{server=Server, name=DbName}) ->
290 309
 
291 310
 open_doc(Db, DocId) ->
292 311
     open_doc(Db, DocId, []).
293  
-open_doc(#db{server=Server}=Db, DocId, Params) ->
  312
+open_doc(#db{server=Server, options=IbrowseOpts}=Db, DocId, Params) ->
294 313
     DocId1 = couchbeam_util:encode_docid(DocId), 
295 314
     Url = make_url(Server, doc_url(Db, DocId1), Params),
296  
-    case db_request(get, Url, ["200", "201"]) of
  315
+    case db_request(get, Url, ["200", "201"], IbrowseOpts) of
297 316
         {ok, _, _, Body} ->
298 317
             {ok, couchbeam_util:json_decode(Body)};
299 318
         Error ->
@@ -302,7 +321,7 @@ open_doc(#db{server=Server}=Db, DocId, Params) ->
302 321
 
303 322
 save_doc(Db, Doc) ->
304 323
     save_doc(Db, Doc, []).
305  
-save_doc(#db{server=Server}=Db, {Props}=Doc, Options) ->
  324
+save_doc(#db{server=Server, options=IbrowseOpts}=Db, {Props}=Doc, Options) ->
306 325
     DocId = case proplists:get_value(<<"_id">>, Props) of
307 326
         undefined ->
308 327
             [Id] = get_uuid(Server),
@@ -313,7 +332,7 @@ save_doc(#db{server=Server}=Db, {Props}=Doc, Options) ->
313 332
     Url = make_url(Server, doc_url(Db, DocId), Options),
314 333
     Body = couchbeam_util:json_encode(Doc),
315 334
     Headers = [{"Content-Type", "application/json"}],
316  
-    case db_request(put, Url, ["201", "202"], Headers, Body) of
  335
+    case db_request(put, Url, ["201", "202"], IbrowseOpts, Headers, Body) of
317 336
         {ok, _, _, RespBody} ->
318 337
             {JsonProp} = couchbeam_util:json_decode(RespBody),
319 338
             NewRev = proplists:get_value(<<"rev">>, JsonProp),
@@ -342,7 +361,7 @@ delete_docs(Db, Docs, Options) ->
342 361
 save_docs(Db, Docs) ->
343 362
     save_docs(Db, Docs, []).
344 363
 
345  
-save_docs(#db{server=Server}=Db, Docs, Options) ->
  364
+save_docs(#db{server=Server, options=IbrowseOpts}=Db, Docs, Options) ->
346 365
     Docs1 = [maybe_docid(Server, Doc) || Doc <- Docs],
347 366
     Options1 = couchbeam_util:parse_options(Options),
348 367
     {Options2, Body} = case proplists:get_value("all_or_nothing", 
@@ -360,7 +379,7 @@ save_docs(#db{server=Server}=Db, Docs, Options) ->
360 379
         end,
361 380
     Url = make_url(Server, [db_url(Db), "/", "_bulk_docs"], Options2),
362 381
     Headers = [{"Content-Type", "application/json"}], 
363  
-    case db_request(post, Url, ["201"], Headers, Body) of
  382
+    case db_request(post, Url, ["201"], IbrowseOpts, Headers, Body) of
364 383
         {ok, _, _, RespBody} ->
365 384
             {ok, couchbeam_util:json_decode(RespBody)};
366 385
         Error -> 
@@ -410,7 +429,7 @@ stream_fetch_attachment(Db, DocId, Name, ClientPid, Options) ->
410 429
 %% @spec stream_fetch_attachment(Db::db(), DocId::string(), Name::string(), 
411 430
 %%                               ClientPid::pid(), Options::list(), Timeout::integer())
412 431
 %%          -> {ok, reference()}|{error, term()}
413  
-stream_fetch_attachment(#db{server=Server}=Db, DocId, Name, ClientPid, 
  432
+stream_fetch_attachment(#db{server=Server, options=IbrowseOpts}=Db, DocId, Name, ClientPid, 
414 433
         Options, Timeout) ->
415 434
     Options1 = couchbeam_util:parse_options(Options),
416 435
     %% custom headers. Allows us to manage Range.
@@ -425,7 +444,7 @@ stream_fetch_attachment(#db{server=Server}=Db, DocId, Name, ClientPid,
425 444
     StartRef = make_ref(),
426 445
     Pid = spawn(couchbeam_attachments, attachment_acceptor, [ClientPid,
427 446
             StartRef, Timeout]),
428  
-    case request_stream(Pid, get, Url, Headers) of
  447
+    case request_stream(Pid, get, Url, IbrowseOpts, Headers) of
429 448
         {ok, ReqId}    ->
430 449
             Pid ! {ibrowse_req_id, StartRef, ReqId},
431 450
             {ok, StartRef};
@@ -446,7 +465,7 @@ put_attachment(Db, DocId, Name, Body)->
446 465
 %%                  {content_length, string()}
447 466
 %%       body() = [] | string() | binary() | fun_arity_0() | {fun_arity_1(), initial_state()}
448 467
 %%       initial_state() = term()
449  
-put_attachment(#db{server=Server}=Db, DocId, Name, Body, Options) ->
  468
+put_attachment(#db{server=Server, options=IbrowseOpts}=Db, DocId, Name, Body, Options) ->
450 469
     QueryArgs = case proplists:get_value(rev, Options) of
451 470
         undefined -> [];
452 471
         Rev -> [{"rev", couchbeam_util:to_list(Rev)}]
@@ -466,7 +485,7 @@ put_attachment(#db{server=Server}=Db, DocId, Name, Body, Options) ->
466 485
     Url = make_url(Server, [db_url(Db), "/",
467 486
             couchbeam_util:encode_docid(DocId), "/", Name], QueryArgs),
468 487
 
469  
-    case db_request(put, Url, ["201"], FinalHeaders, Body) of
  488
+    case db_request(put, Url, ["201"], IbrowseOpts, FinalHeaders, Body) of
470 489
         {ok, _, _, RespBody} ->
471 490
             {[{<<"ok">>, true}|R]} = couchbeam_util:json_decode(RespBody),
472 491
             {ok, {R}};
@@ -483,7 +502,7 @@ delete_attachment(Db, Doc, Name) ->
483 502
 
484 503
 %% @doc delete a document attachment
485 504
 %% @spec(db(), string()|list(), string(), list() -> term()
486  
-delete_attachment(#db{server=Server}=Db, DocOrDocId, Name, Options) ->
  505
+delete_attachment(#db{server=Server, options=IbrowseOpts}=Db, DocOrDocId, Name, Options) ->
487 506
     Options1 = couchbeam_util:parse_options(Options),
488 507
     {Rev, DocId} = case DocOrDocId of
489 508
         {Props} ->
@@ -505,7 +524,7 @@ delete_attachment(#db{server=Server}=Db, DocOrDocId, Name, Options) ->
505 524
                     Options1
506 525
             end,
507 526
             Url = make_url(Server, [db_url(Db), "/", DocId, "/", Name], Options2),
508  
-            case db_request(delete, Url, ["200"]) of
  527
+            case db_request(delete, Url, ["200"], IbrowseOpts) of
509 528
             {ok, _, _, _Body} ->
510 529
                 ok; 
511 530
             Error ->
@@ -570,10 +589,10 @@ view(#db{server=Server}=Db, ViewName, Options) ->
570 589
 ensure_full_commit(Db) ->
571 590
     ensure_full_commit(Db, []).
572 591
 
573  
-ensure_full_commit(#db{server=Server}=Db, Options) ->
  592
+ensure_full_commit(#db{server=Server, options=IbrowseOpts}=Db, Options) ->
574 593
     Url = make_url(Server, [db_url(Db), "/_ensure_full_commit"], Options),
575 594
     Headers = [{"Content-Type", "application/json"}],
576  
-    case db_request(post, Url, ["201"], Headers) of
  595
+    case db_request(post, Url, ["201"], IbrowseOpts, Headers) of
577 596
         {ok, _, _, Body} ->
578 597
             {[{<<"ok">>, true}|R]} = couchbeam_util:json_decode(Body),
579 598
             {ok, R};
@@ -581,20 +600,20 @@ ensure_full_commit(#db{server=Server}=Db, Options) ->
581 600
             Error
582 601
     end.
583 602
 
584  
-compact(#db{server=Server}=Db) ->
  603
+compact(#db{server=Server, options=IbrowseOpts}=Db) ->
585 604
     Url = make_url(Server, [db_url(Db), "/_compact"], []),
586 605
     Headers = [{"Content-Type", "application/json"}],
587  
-    case db_request(post, Url, ["202"], Headers) of
  606
+    case db_request(post, Url, ["202"], IbrowseOpts, Headers) of
588 607
         {ok, _, _, _} ->
589 608
             ok;
590 609
         Error -> 
591 610
             Error
592 611
     end.
593 612
 
594  
-compact(#db{server=Server}=Db, DesignName) ->
  613
+compact(#db{server=Server, options=IbrowseOpts}=Db, DesignName) ->
595 614
     Url = make_url(Server, [db_url(Db), "/_compact/", DesignName], []),
596 615
     Headers = [{"Content-Type", "application/json"}],
597  
-    case db_request(post, Url, ["202"], Headers) of
  616
+    case db_request(post, Url, ["202"], IbrowseOpts, Headers) of
598 617
         {ok, _, _, _} ->
599 618
             ok;
600 619
         Error -> 
@@ -618,9 +637,9 @@ changes(Db) ->
618 637
 %%                  {filter, string()} |
619 638
 %%                  {since, integer()|string()} |
620 639
 %%                  {heartbeat, string()|boolean()}
621  
-changes(#db{server=Server}=Db, Options) ->
  640
+changes(#db{server=Server, options=IbrowseOpts}=Db, Options) ->
622 641
     Url = make_url(Server, [db_url(Db), "/_changes"], Options),
623  
-    case db_request(get, Url, ["200"]) of
  642
+    case db_request(get, Url, ["200"], IbrowseOpts) of
624 643
         {ok, _, _, Body} ->
625 644
             {ok, couchbeam_util:json_decode(Body)};
626 645
         Error ->
@@ -656,12 +675,12 @@ changes_wait(Db, ClientPid) ->
656 675
 %%              <dd>n error occurred</dd>
657 676
 %%      </dl> 
658 677
 %% @spec changes_wait(Db::db(), Pid::pid(), Options::changeoptions()) -> term() 
659  
-changes_wait(#db{server=Server}=Db, ClientPid, Options) ->
  678
+changes_wait(#db{server=Server, options=IbrowseOpts}=Db, ClientPid, Options) ->
660 679
     Options1 = [{"feed", "continuous"}|Options],
661 680
     Url = make_url(Server, [db_url(Db), "/_changes"], Options1),
662 681
     StartRef = make_ref(),
663 682
     Pid = spawn(couchbeam_changes, continuous_acceptor, [ClientPid, StartRef]),
664  
-    case request_stream({Pid, once}, get, Url) of
  683
+    case request_stream({Pid, once}, get, Url, IbrowseOpts) of
665 684
         {ok, ReqId}    ->
666 685
             Pid ! {ibrowse_req_id, StartRef, ReqId},
667 686
             {ok, StartRef};
@@ -738,12 +757,12 @@ encode_query_value(K, V) ->
738 757
     end.
739 758
 
740 759
 
741  
-db_request(Method, Url, Expect) ->
742  
-    db_request(Method, Url, Expect, [], []).
743  
-db_request(Method, Url, Expect, Headers) ->
744  
-    db_request(Method, Url, Expect, Headers, []).
745  
-db_request(Method, Url, Expect, Headers, Body) ->
746  
-    case request(Method, Url, Expect, Headers, Body) of
  760
+db_request(Method, Url, Expect, Options) ->
  761
+    db_request(Method, Url, Expect, Options, [], []).
  762
+db_request(Method, Url, Expect, Options, Headers) ->
  763
+    db_request(Method, Url, Expect, Options, Headers, []).
  764
+db_request(Method, Url, Expect, Options, Headers, Body) ->
  765
+    case request(Method, Url, Expect, Options, Headers, Body) of
747 766
         Resp = {ok, _, _, _} ->
748 767
             Resp;
749 768
         {error, {ok, "404", _, _}} ->
@@ -757,14 +776,14 @@ db_request(Method, Url, Expect, Headers, Body) ->
757 776
     end.
758 777
 
759 778
 %% @doc send an ibrowse request
760  
-request(Method, Url, Expect) ->
761  
-    request(Method, Url, Expect, [], []).
762  
-request(Method, Url, Expect, Headers) ->
763  
-    request(Method, Url, Expect, Headers, []).
764  
-request(Method, Url, Expect, Headers, Body) ->
  779
+request(Method, Url, Expect, Options) ->
  780
+    request(Method, Url, Expect, Options, [], []).
  781
+request(Method, Url, Expect, Options, Headers) ->
  782
+    request(Method, Url, Expect, Options, Headers, []).
  783
+request(Method, Url, Expect, Options, Headers, Body) ->
765 784
     Accept = {"Accept", "application/json, */*;q=0.9"},
766 785
     case ibrowse:send_req(Url, [Accept|Headers], Method, Body, 
767  
-            [{response_format, binary}]) of
  786
+            [{response_format, binary}|Options]) of
768 787
         Resp={ok, Status, _, _} ->
769 788
             case lists:member(Status, Expect) of
770 789
                 true -> Resp;
@@ -774,14 +793,14 @@ request(Method, Url, Expect, Headers, Body) ->
774 793
     end.
775 794
 
776 795
 %% @doc stream an ibrowse request
777  
-request_stream(Pid, Method, Url) ->
778  
-    request_stream(Pid, Method, Url, []).
779  
-request_stream(Pid, Method, Url, Headers) ->
780  
-    request_stream(Pid, Method, Url, Headers, []).
781  
-request_stream(Pid, Method, Url, Headers, Body) ->
  796
+request_stream(Pid, Method, Url, Options) ->
  797
+    request_stream(Pid, Method, Url, Options, []).
  798
+request_stream(Pid, Method, Url, Options, Headers) ->
  799
+    request_stream(Pid, Method, Url, Options, Headers, []).
  800
+request_stream(Pid, Method, Url, Options, Headers, Body) ->
782 801
     case ibrowse:send_req(Url, Headers, Method, Body,
783 802
                           [{stream_to, Pid},
784  
-                           {response_format, binary}]) of
  803
+                           {response_format, binary}|Options]) of
785 804
         {ibrowse_req_id, ReqId} ->
786 805
             {ok, ReqId};
787 806
         Error ->
@@ -848,9 +867,9 @@ do_get_uuids1(Acc, [Uuid|Rest], Count) ->
848 867
     do_get_uuids1([Uuid|Acc], Rest, Count-1).
849 868
 
850 869
 
851  
-get_new_uuids(Server=#server{host=Host, port=Port}) ->
  870
+get_new_uuids(Server=#server{host=Host, port=Port, options=IbrowseOptions}) ->
852 871
     Url = make_url(Server, "_uuids", [{"count", "1000"}]),  
853  
-    case request(get, Url, ["200"]) of
  872
+    case request(get, Url, ["200"], IbrowseOptions) of
854 873
         {ok, _Status, _Headers, Body} ->
855 874
             {[{<<"uuids">>, Uuids}]} = couchbeam_util:json_decode(Body),
856 875
             ServerUuids = #server_uuids{host_port={Host,

0 notes on commit bc200e3

Please sign in to comment.
Something went wrong with that request. Please try again.