mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Add restful API's for follow and ignore
This commit is contained in:
parent
a8c29bbb15
commit
e7ca268dbc
6
httpd.h
6
httpd.h
@ -217,6 +217,12 @@ typedef struct httpd_request
|
|||||||
bool_t eof;
|
bool_t eof;
|
||||||
} plylist;
|
} plylist;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
rhizome_bid_t bundle_id;
|
||||||
|
enum list_phase phase;
|
||||||
|
size_t rowcount;
|
||||||
|
} meshmb_feeds;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int fd;
|
int fd;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
@ -204,6 +204,14 @@ public class ServalDClient implements ServalDHttpConnectionFactory {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int meshmbFollow(SigningKey id, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||||
|
return MeshMBCommon.follow(this, id, peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int meshmbIgnore(SigningKey id, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||||
|
return MeshMBCommon.ignore(this, id, peer);
|
||||||
|
}
|
||||||
|
|
||||||
// interface ServalDHttpConnectionFactory
|
// interface ServalDHttpConnectionFactory
|
||||||
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException
|
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.servalproject.servaldna.meshmb;
|
package org.servalproject.servaldna.meshmb;
|
||||||
|
|
||||||
import org.servalproject.servaldna.PostHelper;
|
import org.servalproject.servaldna.PostHelper;
|
||||||
|
import org.servalproject.servaldna.ServalDClient;
|
||||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||||
import org.servalproject.servaldna.SigningKey;
|
import org.servalproject.servaldna.SigningKey;
|
||||||
@ -26,5 +27,17 @@ public class MeshMBCommon {
|
|||||||
return conn.getResponseCode();
|
return conn.getResponseCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int ignore(ServalDHttpConnectionFactory connector, SigningKey id, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||||
|
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshmb/" + id.toHex() + "/follow/" + peer.toHex());
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.connect();
|
||||||
|
return conn.getResponseCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int follow(ServalDHttpConnectionFactory connector, SigningKey id, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||||
|
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshmb/" + id.toHex() + "/ignore/" + peer.toHex());
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.connect();
|
||||||
|
return conn.getResponseCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
27
mem.c
27
mem.c
@ -60,30 +60,3 @@ char *_str_edup(struct __sourceloc __whence, const char *str)
|
|||||||
{
|
{
|
||||||
return _strn_edup(__whence, str, strlen(str));
|
return _strn_edup(__whence, str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef malloc
|
|
||||||
#undef calloc
|
|
||||||
#undef free
|
|
||||||
#undef realloc
|
|
||||||
|
|
||||||
#define SDM_GUARD_AFTER 16384
|
|
||||||
|
|
||||||
void *_serval_debug_malloc(unsigned int bytes, struct __sourceloc __whence)
|
|
||||||
{
|
|
||||||
void *r=malloc(bytes+SDM_GUARD_AFTER);
|
|
||||||
_DEBUGF("malloc(%d) -> %p", bytes, r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_serval_debug_calloc(unsigned int bytes, unsigned int count, struct __sourceloc __whence)
|
|
||||||
{
|
|
||||||
void *r=calloc((bytes*count)+SDM_GUARD_AFTER,1);
|
|
||||||
_DEBUGF("calloc(%d,%d) -> %p", bytes, count, r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serval_debug_free(void *p, struct __sourceloc __whence)
|
|
||||||
{
|
|
||||||
_DEBUGF("free(%p)", p);
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
11
mem.h
11
mem.h
@ -24,17 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
// #define MALLOC_PARANOIA
|
|
||||||
|
|
||||||
#ifdef MALLOC_PARANOIA
|
|
||||||
#define malloc(X) _serval_debug_malloc(X,__WHENCE__)
|
|
||||||
#define calloc(X,Y) _serval_debug_calloc(X,Y,__WHENCE__)
|
|
||||||
#define free(X) _serval_debug_free(X,__WHENCE__)
|
|
||||||
void *_serval_debug_malloc(unsigned int bytes, struct __sourceloc whence) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(1)));
|
|
||||||
void *_serval_debug_calloc(unsigned int bytes, unsigned int count, struct __sourceloc whence) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(1)));
|
|
||||||
void _serval_debug_free(void *p, struct __sourceloc whence);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Equivalent to malloc(3), but logs an error before returning NULL.
|
/* Equivalent to malloc(3), but logs an error before returning NULL.
|
||||||
*
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
118
meshmb_restful.c
118
meshmb_restful.c
@ -386,6 +386,114 @@ static int restful_meshmb_newsince_find(httpd_request *r, const char *remainder)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// allow multiple requests to re-use the same struct meshmb_feeds *, keeping it up to date as bundles arrive
|
||||||
|
struct meshmb_session{
|
||||||
|
struct meshmb_session *next;
|
||||||
|
struct meshmb_session *prev;
|
||||||
|
unsigned ref_count;
|
||||||
|
keyring_identity *id;
|
||||||
|
struct meshmb_feeds *feeds;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct meshmb_session *sessions = NULL;
|
||||||
|
|
||||||
|
static struct meshmb_session *open_session(const identity_t *identity){
|
||||||
|
keyring_identity *id = keyring_find_identity(keyring, identity);
|
||||||
|
if (!id)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct meshmb_session *session = sessions;
|
||||||
|
while(session){
|
||||||
|
if (session->id == id){
|
||||||
|
session->ref_count++;
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
session = session->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct meshmb_feeds *feeds = NULL;
|
||||||
|
if (meshmb_open(id, &feeds)==-1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
session = emalloc(sizeof (struct meshmb_session));
|
||||||
|
if (!session){
|
||||||
|
meshmb_close(feeds);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
session->next = sessions;
|
||||||
|
session->prev = NULL;
|
||||||
|
if (sessions)
|
||||||
|
sessions->prev = session;
|
||||||
|
sessions = session;
|
||||||
|
|
||||||
|
session->ref_count = 1;
|
||||||
|
session->id = id;
|
||||||
|
session->feeds = feeds;
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_session(struct meshmb_session *session){
|
||||||
|
if (--session->ref_count == 0){
|
||||||
|
if (session->next)
|
||||||
|
session->next->prev = session->prev;
|
||||||
|
if (session->prev)
|
||||||
|
session->prev->next = session->next;
|
||||||
|
else
|
||||||
|
sessions = session->next;
|
||||||
|
|
||||||
|
meshmb_close(session->feeds);
|
||||||
|
free(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int restful_meshmb_follow(httpd_request *r, const char *remainder)
|
||||||
|
{
|
||||||
|
if (*remainder)
|
||||||
|
return 404;
|
||||||
|
assert(r->finalise_union == NULL);
|
||||||
|
|
||||||
|
struct meshmb_session *session = open_session(&r->bid);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (session
|
||||||
|
&& meshmb_follow(session->feeds, &r->u.meshmb_feeds.bundle_id)!=-1
|
||||||
|
&& meshmb_flush(session->feeds)!=-1){
|
||||||
|
http_request_simple_response(&r->http, 201, "TODO, detailed response");
|
||||||
|
ret = 201;
|
||||||
|
}else{
|
||||||
|
http_request_simple_response(&r->http, 500, "TODO, detailed response");
|
||||||
|
ret = 500;
|
||||||
|
}
|
||||||
|
if (session)
|
||||||
|
close_session(session);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int restful_meshmb_ignore(httpd_request *r, const char *remainder)
|
||||||
|
{
|
||||||
|
if (*remainder)
|
||||||
|
return 404;
|
||||||
|
assert(r->finalise_union == NULL);
|
||||||
|
|
||||||
|
struct meshmb_session *session = open_session(&r->bid);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (session
|
||||||
|
&& meshmb_ignore(session->feeds, &r->u.meshmb_feeds.bundle_id)!=-1
|
||||||
|
&& meshmb_flush(session->feeds)!=-1){
|
||||||
|
http_request_simple_response(&r->http, 201, "TODO, detailed response");
|
||||||
|
ret = 201;
|
||||||
|
}else{
|
||||||
|
http_request_simple_response(&r->http, 500, "TODO, detailed response");
|
||||||
|
ret = 500;
|
||||||
|
}
|
||||||
|
if (session)
|
||||||
|
close_session(session);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
DECLARE_HANDLER("/restful/meshmb/", restful_meshmb_);
|
DECLARE_HANDLER("/restful/meshmb/", restful_meshmb_);
|
||||||
static int restful_meshmb_(httpd_request *r, const char *remainder)
|
static int restful_meshmb_(httpd_request *r, const char *remainder)
|
||||||
{
|
{
|
||||||
@ -415,6 +523,16 @@ static int restful_meshmb_(httpd_request *r, const char *remainder)
|
|||||||
&& strcmp(end, "messagelist.json") == 0) {
|
&& strcmp(end, "messagelist.json") == 0) {
|
||||||
handler = restful_meshmb_newsince_list;
|
handler = restful_meshmb_newsince_list;
|
||||||
remainder = "";
|
remainder = "";
|
||||||
|
} else if(str_startswith(remainder, "/follow/", &end)
|
||||||
|
&& strn_to_identity_t(&r->u.meshmb_feeds.bundle_id, end, &end) != -1) {
|
||||||
|
handler = restful_meshmb_follow;
|
||||||
|
verb = HTTP_VERB_POST;
|
||||||
|
remainder = "";
|
||||||
|
} else if(str_startswith(remainder, "/ignore/", &end)
|
||||||
|
&& strn_to_identity_t(&r->u.meshmb_feeds.bundle_id, end, &end) != -1) {
|
||||||
|
handler = restful_meshmb_ignore;
|
||||||
|
verb = HTTP_VERB_POST;
|
||||||
|
remainder = "";
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
} else if(strcmp(remainder, "/find.json") == 0) {
|
} else if(strcmp(remainder, "/find.json") == 0) {
|
||||||
|
13
tests/meshmb
13
tests/meshmb
@ -84,18 +84,17 @@ setup_meshmbFollow() {
|
|||||||
}
|
}
|
||||||
test_meshmbFollow() {
|
test_meshmbFollow() {
|
||||||
executeOk_servald meshmb follow $IDA1 $IDA2
|
executeOk_servald meshmb follow $IDA1 $IDA2
|
||||||
tfw_cat --stderr
|
|
||||||
executeOk_servald meshmb list following $IDA1
|
executeOk_servald meshmb list following $IDA1
|
||||||
tfw_cat --stdout --stderr
|
assertStdoutGrep --matches=1 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||||
|
assertStdoutGrep --matches=0 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||||
executeOk_servald meshmb follow $IDA1 $IDA3
|
executeOk_servald meshmb follow $IDA1 $IDA3
|
||||||
tfw_cat --stderr
|
|
||||||
executeOk_servald meshmb list following $IDA1
|
executeOk_servald meshmb list following $IDA1
|
||||||
tfw_cat --stdout --stderr
|
assertStdoutGrep --matches=1 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||||
|
assertStdoutGrep --matches=1 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||||
executeOk_servald meshmb ignore $IDA1 $IDA2
|
executeOk_servald meshmb ignore $IDA1 $IDA2
|
||||||
tfw_cat --stderr
|
|
||||||
executeOk_servald meshmb list following $IDA1
|
executeOk_servald meshmb list following $IDA1
|
||||||
tfw_cat --stdout --stderr
|
assertStdoutGrep --matches=0 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||||
#TODO list....
|
assertStdoutGrep --matches=1 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||||
}
|
}
|
||||||
|
|
||||||
runTests "$@"
|
runTests "$@"
|
||||||
|
@ -95,5 +95,47 @@ test_MeshMBRestList() {
|
|||||||
}
|
}
|
||||||
])"
|
])"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doc_MeshMBRestFollow="Restful follow another feed"
|
||||||
|
setup_MeshMBRestFollow() {
|
||||||
|
IDENTITY_COUNT=3
|
||||||
|
setup
|
||||||
|
executeOk_servald meshmb send $IDA1 "Message 1"
|
||||||
|
executeOk_servald meshmb send $IDA2 "Message 2"
|
||||||
|
executeOk_servald meshmb send $IDA3 "Message 3"
|
||||||
|
}
|
||||||
|
test_MeshMBRestFollow() {
|
||||||
|
executeOk curl \
|
||||||
|
-H "Expect:" \
|
||||||
|
--silent --fail --show-error \
|
||||||
|
--output follow.json \
|
||||||
|
--basic --user harry:potter \
|
||||||
|
--request POST \
|
||||||
|
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/follow/$IDA2"
|
||||||
|
executeOk_servald meshmb list following $IDA1
|
||||||
|
assertStdoutGrep --matches=1 ":$IDA2::[0-9]\+:Message 2\$"
|
||||||
|
assertStdoutGrep --matches=0 ":$IDA3::[0-9]\+:Message 3\$"
|
||||||
|
executeOk curl \
|
||||||
|
-H "Expect:" \
|
||||||
|
--silent --fail --show-error \
|
||||||
|
--output follow.json \
|
||||||
|
--basic --user harry:potter \
|
||||||
|
--request POST \
|
||||||
|
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/follow/$IDA3"
|
||||||
|
executeOk_servald meshmb list following $IDA1
|
||||||
|
assertStdoutGrep --matches=1 ":$IDA2::[0-9]\+:Message 2\$"
|
||||||
|
assertStdoutGrep --matches=1 ":$IDA3::[0-9]\+:Message 3\$"
|
||||||
|
executeOk curl \
|
||||||
|
-H "Expect:" \
|
||||||
|
--silent --fail --show-error \
|
||||||
|
--output follow.json \
|
||||||
|
--basic --user harry:potter \
|
||||||
|
--request POST \
|
||||||
|
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/ignore/$IDA2"
|
||||||
|
executeOk_servald meshmb list following $IDA1
|
||||||
|
assertStdoutGrep --matches=0 ":$IDA2::[0-9]\+:Message 2\$"
|
||||||
|
assertStdoutGrep --matches=1 ":$IDA3::[0-9]\+:Message 3\$"
|
||||||
|
}
|
||||||
|
|
||||||
runTests "$@"
|
runTests "$@"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user