mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Making progress on the Atom interface.
- GET items - POST items - GET nodes HTTP error codes now are the ones XMPP returns.
This commit is contained in:
parent
a22ebd3c49
commit
cd923838c3
45
doc/http_post.md
Normal file
45
doc/http_post.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Managing pubsub nodes through HTTP Atompub #
|
||||
|
||||
|
||||
## Configuration ##
|
||||
|
||||
These options will be used by the service to know how to build URLs. Using the previous configuration items the service should be accessed through `http://notify.push.bbc.co.uk:5280/pshb/<host>/<node>/`.
|
||||
|
||||
Also, in the ejabberd_http handler configuration, add the identified line.
|
||||
|
||||
{5280, ejabberd_http, [
|
||||
http_poll,
|
||||
web_admin,
|
||||
{request_handlers, [{["pshb"], pshb_http}]} % this should be added
|
||||
]}
|
||||
|
||||
## Usage example with cURL ##
|
||||
|
||||
### Getting the service document ###
|
||||
|
||||
No authentication necessary. All nodes are listed.
|
||||
|
||||
curl -i http://<host>:<port>/pshb/<domain>/
|
||||
|
||||
### Getting items from a node ###
|
||||
|
||||
No authentication done, and all nodes are accessible.
|
||||
|
||||
curl -i http://<host>:<port>/pshb/<domain>/<node>/
|
||||
|
||||
|
||||
### Posting a new item ###
|
||||
|
||||
curl -u <jid>:<password> -i -X POST -d @entry.atom http://<host>:<port>/pshb/<domain>/<node>
|
||||
|
||||
User ability to post is based on node configuration.
|
||||
|
||||
|
||||
### Creating a new node ###
|
||||
|
||||
An instant node can be created :
|
||||
|
||||
curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost
|
||||
|
||||
|
||||
|
@ -46,17 +46,15 @@
|
||||
|
||||
-export([process/2]).
|
||||
|
||||
process([_Domain, _Node|_Rest]=LocalPath, #request{auth = Auth} = Request)->
|
||||
process(LocalPath, #request{auth = Auth} = Request)->
|
||||
?DEBUG("LocalPath = ~p", [LocalPath]),
|
||||
case get_auth(Auth) of
|
||||
%%make sure user belongs to pubsub domain
|
||||
{User, Domain} ->
|
||||
out(Request, Request#request.method, LocalPath,{User, Domain});
|
||||
_ ->
|
||||
out(Request, Request#request.method, LocalPath,undefined)
|
||||
end;
|
||||
|
||||
process(_LocalPath, _Request)->
|
||||
error(404).
|
||||
out(Request, Request#request.method, LocalPath, undefined)
|
||||
end.
|
||||
|
||||
get_auth(Auth) ->
|
||||
case Auth of
|
||||
@ -128,13 +126,42 @@ out(Args, 'POST', [Domain, Node]=Uri, {User, _Domain}) ->
|
||||
?DEBUG("Publishing to ~p~n",[entry_uri(Args, Domain, Node,Slug)]),
|
||||
{201, [{"location", entry_uri(Args, Domain,Node,Slug)}], Payload};
|
||||
{error, Error} ->
|
||||
error(400, Error)
|
||||
error(Error)
|
||||
end;
|
||||
|
||||
out(Args, 'GET', [Domain]=Uri, From)->
|
||||
Host = get_host(Uri),
|
||||
?DEBUG("Host = ~p", [Host]),
|
||||
case mod_pubsub:tree_action(Host, get_subnodes, [Host, <<>>, From ]) of
|
||||
[] ->
|
||||
?DEBUG("Error getting URI ~p : ~p",[Uri, From]),
|
||||
error(404);
|
||||
Collections ->
|
||||
{200, [{"Content-Type", "application/atomsvc+xml"}], "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
++ xml:element_to_string(service(Args,Domain, Collections))}
|
||||
end;
|
||||
|
||||
out(Args, 'POST', [Domain]=Uri, {User, UDomain})->
|
||||
Host = get_host(Uri),
|
||||
case mod_pubsub:create_node(Host, Domain, <<>>, {User, UDomain}, "default") of
|
||||
{error, Error} ->
|
||||
?ERROR_MSG("Error create node via HTTP : ~p",[Error]),
|
||||
|
||||
error(Error); % will probably detail more
|
||||
{result, [Node]} ->
|
||||
{200, [{"Content-Type", "application/xml"}], "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
++ xml:element_to_string(Node)}
|
||||
end;
|
||||
|
||||
out(Args, 'POST', [Domain]=Uri, undefined) ->
|
||||
error(403);
|
||||
|
||||
|
||||
|
||||
out(Args, 'GET', [Domain, Node, _Item]=URI, _) ->
|
||||
Failure = fun(Error)->
|
||||
?DEBUG("Error getting URI ~p : ~p",[URI, Error]),
|
||||
error(404)
|
||||
error(Error)
|
||||
end,
|
||||
Success = fun(Item)->
|
||||
Etag =generate_etag(Item),
|
||||
@ -169,10 +196,10 @@ get_member([_Domain, _Node, Member])->
|
||||
Member.
|
||||
|
||||
collection_uri(R, Domain, Node) ->
|
||||
base_uri(R, Domain)++ "/" ++Node.
|
||||
base_uri(R, Domain)++ "/" ++ b2l(Node).
|
||||
|
||||
entry_uri(R,Domain, Node, Id)->
|
||||
collection_uri(R,Domain, Node)++"/"++Id.
|
||||
collection_uri(R,Domain, Node)++"/"++b2l(Id).
|
||||
|
||||
base_uri(#request{host=Host, port=Port}, Domain)->
|
||||
"http://"++Host++":"++i2l(Port)++"/pshb/" ++ Domain.
|
||||
@ -209,7 +236,24 @@ collection(Title, Link, Updated, _Id, Entries)->
|
||||
Entries
|
||||
]}.
|
||||
|
||||
service(Args, Domain,Collections)->
|
||||
{xmlelement, "service", [{"xmlns", "http://www.w3.org/2007/app"},
|
||||
{"xmlns:atom", "http://www.w3.org/2005/Atom"},
|
||||
{"xmlns:app", "http://www.w3.org/2007/app"}],[
|
||||
{xmlelement, "workspace", [],[
|
||||
{xmlelement, "atom:title", [],[{xmlcdata,"Pubsub node Feed for " ++Domain}]} |
|
||||
lists:map(fun(#pubsub_node{nodeid={_Server, Id}, type=_Type})->
|
||||
{xmlelement, "collection", [{"href", collection_uri(Args,Domain, Id)}], [
|
||||
{xmlelement, "atom:title", [], [{xmlcdata, Id}]}
|
||||
]}
|
||||
end, Collections)
|
||||
]}
|
||||
]}.
|
||||
|
||||
%% simple output functions
|
||||
error({xmlelement, "error", Attrs, _}=Error) ->
|
||||
Value = list_to_integer(xml:get_attr_s("code", Attrs)),
|
||||
{Value, [{"Content-type", "application/xml"}], xml:element_to_string(Error)};
|
||||
error(404)->
|
||||
{404, [], "Not Found"};
|
||||
error(403)->
|
||||
@ -221,7 +265,6 @@ error(401)->
|
||||
error(Code)->
|
||||
{Code, [], ""}.
|
||||
error(Code, Error) when is_list(Error) -> {Code, [], Error};
|
||||
error(Code, {xmlelement, "error",_,_}=Error) -> {Code, [], xml:element_to_string(Error)};
|
||||
error(Code, _Error) -> {Code, [], "Bad request"}.
|
||||
success(200)->
|
||||
{200, [], ""};
|
||||
@ -296,3 +339,6 @@ add_zero(L) when is_list(L) -> L.
|
||||
|
||||
i2l(I) when is_integer(I) -> integer_to_list(I);
|
||||
i2l(L) when is_list(L) -> L.
|
||||
|
||||
b2l(B) when is_binary(B) -> binary_to_list(B);
|
||||
b2l(L) when is_list(L) -> L.
|
Loading…
Reference in New Issue
Block a user