Re: [PATCH] Support DELETE verb in http_open/3
Wouter Beek <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <CAE1un7NvqM85iR7ft8Q0PttZoCd_zNbV5NzSV6TX_NwV6ZwW7w@mail.gmail.com> |
Hi Michael,
That's great! My impression is that the HTTP package is in principle able
to support all HTTP methods, but that many higher-level predicates contain
unnecessary restrictions on the HTTP method allowed (mostly POST and GET).
Here's a workaround module that I'm using now, providing (1) variants of
http_parameters/[2,3] that work for non-POST methods and JSON data, and (2)
a variant of http_read_json/2 that works for non-POST methods. (Maybe it
comes in handy.)
~~~{.pl}
:- module(
json_ext,
[
http_parameters2/2, % +Request:list
% ?Params:list
http_parameters2/3, % +Request:list
% ?Params:list
% :Options:list
http_read_json2/2 % +Request:list
% -JSON:compound
]
).
:- reexport(
library(http/http_json),
[
http_read_json/2,
http_read_json/3,
reply_json/1,
reply_json/2
]
).
:- use_module(library(error)).
:- use_module(library(http/http_client)).
:- use_module(library(http/http_parameters)).
:- use_module(library(option)).
:- meta_predicate(http_parameters2(+,?,:)).
%! http_parameters2(+Request, ?Params)
% @see Like http_parameters/2, but works for JSON as well and
% is not restricted to the POST method.
http_parameters2(Request, Params) :-
http_parameters2(Request, Params, []).
%! http_parameters2(+Request, ?Params, :Options)
% @see Like http_parameters/2, but works for JSON as well and
% is not restricted to the POST method.
http_parameters2(Request, Params, Options) :-
must_be(list, Params),
meta_options(http_parameters:is_meta, Options, QOptions),
option(attribute_declarations(DeclGoal), QOptions, -),
http_parms2(Request, Params, DeclGoal, Form),
( memberchk(form_data(RForm), QOptions)
-> RForm = Form
; true
).
http_parms2(Request, Params, DeclGoal, Data2) :-
memberchk(content_type(Type), Request),
http_json:is_json_type(Type), !,
http_read_data(Request, Data1, []),
Data1 = json(Data2),
http_parameters:fill_parameters(Params, Data2, DeclGoal).
%! http_read_json2(+Request:list(nvpair), -JSON:compound) is det.
% @see Like http_read_json/2, but is not restricted to the HTTP POST method.
http_read_json2(Request, JSON):-
memberchk(content_type(Type), Request),
(
http_json:is_json_type(Type)
->
http_read_data(Request, JSON, [])
;
domain_error(mimetype, Type)
).
~~~
---
Cheers!,
Wouter.
E-mail: [email protected]
WWW: www.wouterbeek.com
Tel.: 0647674624
On Sun, Jul 21, 2013 at 5:10 AM, Michael Hendricks <[email protected]>wrote:
> As requested by Wouter Beek, this patch adds support for HTTP 1.1 verb
> DELETE. Its implementation is very similar to GET and HEAD.
>
> I actually needed this for a project I'm working. Without this patch,
> I got this:
>
> ?- http_open('http://127.0.0.1:3000/foo', Stream, [method(delete)]),
> | close(Stream).
> ERROR: Domain error: `method' expected, found `delete'
>
> With this patch, I get:
>
> Stream = <stream>(0x7fb71212e070).
>
> and the correct request is made to the server.
> ---
> http_open.pl | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git http_open.pl http_open.pl
> index 4014ecd..1d0a96c 100644
> --- http_open.pl
> +++ http_open.pl
> @@ -54,7 +54,7 @@ two additional modules that acts as plugins:
>
> * library(http/http_header)
> Loading this library causes http_open/3 to support the =POST= method
> - in addition to =GET= and =HEAD=.
> + in addition to =GET=, =HEAD= and =DELETE=.
>
> * library(http/http_ssl_plugin)
> Loading this library causes http_open/3 HTTPS connections. Relevant
> @@ -106,7 +106,7 @@ resource. See also parse_time/2.
> [ authorization(compound),
> final_url(-atom),
> header(+atom, -atom),
> - method(oneof([get,head,post])),
> + method(oneof([delete,get,head,post])),
> size(-integer),
> status_code(-integer),
> timeout(number),
> @@ -155,7 +155,8 @@ user_agent('SWI-Prolog').
> % AtomValue is unified to the empty atom ('').
> %
> % * method(+Method)
> -% One of =get= (default) or =head=. The =head= message can be
> +% One of =get= (default), =head= or =delete=.
> +% The =head= message can be
> % used in combination with the header(Name, Value) option to
> % access information on the resource without actually fetching
> % the resource itself. The returned stream must be closed
> @@ -348,6 +349,7 @@ method(Options, MNAME) :-
> ; domain_error(method, M)
> ).
>
> +map_method(delete, 'DELETE').
> map_method(get, 'GET').
> map_method(head, 'HEAD').
> map_method(post, 'POST') :-
> @@ -472,6 +474,7 @@ redirect_options(Options0, Options) :-
> ; Options = Options1
> ).
>
> +redirect_method(delete).
> redirect_method(get).
> redirect_method(head).
>
> --
> 1.8.2.3
>
>
>
-------------- next part --------------
HTML attachment scrubbed and removed