mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 12:56:29 +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
@ -216,6 +216,12 @@ typedef struct httpd_request
|
||||
time_s_t timestamp;
|
||||
bool_t eof;
|
||||
} plylist;
|
||||
|
||||
struct {
|
||||
rhizome_bid_t bundle_id;
|
||||
enum list_phase phase;
|
||||
size_t rowcount;
|
||||
} meshmb_feeds;
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
|
@ -204,6 +204,14 @@ public class ServalDClient implements ServalDHttpConnectionFactory {
|
||||
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
|
||||
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.servalproject.servaldna.meshmb;
|
||||
|
||||
import org.servalproject.servaldna.PostHelper;
|
||||
import org.servalproject.servaldna.ServalDClient;
|
||||
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.SigningKey;
|
||||
@ -26,5 +27,17 @@ public class MeshMBCommon {
|
||||
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));
|
||||
}
|
||||
|
||||
#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 "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.
|
||||
*
|
||||
* @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_);
|
||||
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) {
|
||||
handler = restful_meshmb_newsince_list;
|
||||
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) {
|
||||
|
13
tests/meshmb
13
tests/meshmb
@ -84,18 +84,17 @@ setup_meshmbFollow() {
|
||||
}
|
||||
test_meshmbFollow() {
|
||||
executeOk_servald meshmb follow $IDA1 $IDA2
|
||||
tfw_cat --stderr
|
||||
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
|
||||
tfw_cat --stderr
|
||||
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
|
||||
tfw_cat --stderr
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
tfw_cat --stdout --stderr
|
||||
#TODO list....
|
||||
assertStdoutGrep --matches=0 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
}
|
||||
|
||||
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 "$@"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user