7 #ifndef _CEPTR_TEST_HTTP_EXAMPLE_H
8 #define _CEPTR_TEST_HTTP_EXAMPLE_H
10 #include "../src/ceptr.h"
11 #include "../src/receptor.h"
12 #include "../src/protocol.h"
13 #include "../src/def.h"
14 #include "../src/semtrex.h"
16 #include "../src/vmhost.h"
17 #include "../src/accumulator.h"
34 if (!
_t_match(stx,t)) {raise_error(
"BAD HTTP_REQUEST semtrex");}
57 _t_news(resp,CARRIER,HTTP_RESPONSE);
58 int pt1[] = {2,1,TREE_PATH_TERMINATOR};
59 _t_new(resp,PARAM_REF,pt1,
sizeof(
int)*3);
67 HTTP_RESPONSE_STATUS,STATUS_VALUE,200,STATUS_TEXT,
"OK",NULL_SYMBOL,
69 CONTENT_TYPE,MEDIA_TYPE_IDENT,TEXT_MEDIA_TYPE,MEDIA_SUBTYPE_IDENT,CEPTR_TEXT_MEDIA_SUBTYPE,NULL_SYMBOL,NULL_SYMBOL,
71 SLOT,USAGE,HTTP_REQUEST_PATH_SEGMENT,NULL_SYMBOL,
72 NULL_SYMBOL,NULL_SYMBOL,NULL_SYMBOL
85 char *
G_stxs =
"/ASCII_CHARS/<HTTP_REQUEST:<HTTP_REQUEST_METHOD:ASCII_CHAR!=' '+>,ASCII_CHAR=' ',<HTTP_REQUEST_PATH:<HTTP_REQUEST_PATH_SEGMENTS:(ASCII_CHAR='/',<HTTP_REQUEST_PATH_SEGMENT:ASCII_CHAR!={'/','?',' '}*>)+>>,(ASCII_CHAR='?',<HTTP_REQUEST_PATH_QUERY:<HTTP_REQUEST_PATH_QUERY_PARAMS:(<HTTP_REQUEST_PATH_QUERY_PARAM:<PARAM_KEY:ASCII_CHAR!={'&',' ','='}+>,ASCII_CHAR='=',<PARAM_VALUE:ASCII_CHAR!={'&',' '}*>>,ASCII_CHAR='&'?)+>+>)?,ASCII_CHAR=' ',ASCII_CHAR='H',ASCII_CHAR='T',ASCII_CHAR='T',ASCII_CHAR='P',ASCII_CHAR='/',<HTTP_REQUEST_VERSION:<VERSION_MAJOR:ASCII_CHAR='0'>,ASCII_CHAR='.',<VERSION_MINOR:ASCII_CHAR='9'>>>";
95 T *stx=
_sl(0,ASCII_CHARS);
96 t = _t_news(stx,SEMTREX_GROUP,HTTP_REQUEST);
97 T *sq = _t_newr(t,SEMTREX_SEQUENCE);
98 t = _t_news(sq,SEMTREX_GROUP,HTTP_REQUEST_METHOD);
99 t = _t_newr(t,SEMTREX_ONE_OR_MORE);
103 t = _t_news(sq,SEMTREX_GROUP,HTTP_REQUEST_PATH);
104 T *sqq = _t_newr(t,SEMTREX_SEQUENCE);
106 t = _t_news(sqq,SEMTREX_GROUP,HTTP_REQUEST_PATH_SEGMENTS);
107 t = _t_newr(t,SEMTREX_ONE_OR_MORE);
108 t = _t_newr(t,SEMTREX_SEQUENCE);
110 t = _t_news(t,SEMTREX_GROUP,HTTP_REQUEST_PATH_SEGMENT);
111 t = _t_newr(t,SEMTREX_ZERO_OR_MORE);
112 __stxcvm(t,1,3,
'/',
'?',
' ');
127 t = _t_newr(sq,SEMTREX_ZERO_OR_ONE);
128 t = _t_newr(t,SEMTREX_SEQUENCE);
132 t = _t_news(t,SEMTREX_GROUP,HTTP_REQUEST_PATH_QUERY);
133 t = _t_newr(t,SEMTREX_ONE_OR_MORE);
134 t = _t_news(t,SEMTREX_GROUP,HTTP_REQUEST_PATH_QUERY_PARAMS);
135 t = _t_newr(t,SEMTREX_ONE_OR_MORE);
136 T *qps = _t_newr(t,SEMTREX_SEQUENCE);
137 t = _t_news(qps,SEMTREX_GROUP,HTTP_REQUEST_PATH_QUERY_PARAM);
138 f = _t_newr(t,SEMTREX_SEQUENCE);
139 t = _t_news(f,SEMTREX_GROUP,PARAM_KEY);
140 t = _t_newr(t,SEMTREX_ONE_OR_MORE);
141 __stxcvm(t,1,3,
'&',
' ',
'=');
143 t = _t_news(f,SEMTREX_GROUP,PARAM_VALUE);
144 t = _t_newr(t,SEMTREX_ZERO_OR_MORE);
145 __stxcvm(t,1,2,
'&',
' ');
147 t = _t_newr(qps,SEMTREX_ZERO_OR_ONE);
157 t = _t_news(sq,SEMTREX_GROUP,HTTP_REQUEST_VERSION);
158 t = _t_newr(t,SEMTREX_SEQUENCE);
159 f = _t_news(t,SEMTREX_GROUP,VERSION_MAJOR);
162 f = _t_news(t,SEMTREX_GROUP,VERSION_MINOR);
167 T *makeDeltaAdd(
T *src,
T *t) {
169 T *d = makeDelta(TREE_DELTA_ADD,path,t,0);
174 Symbol getTag(
char *otag,
Symbol tag_sym[],
char *tag_str[]) {
178 if (!strcicmp(otag,tag_str[i])) {ts = tag_sym[i];
break;}
180 if (semeq(ts,NULL_SYMBOL)) {raise_error(
"invalid tag: %s",otag);}
184 T *parseHTML(
char *html) {
186 Symbol G_tag_sym[] = {HTML_HTML,HTML_HEAD,HTML_TITLE,HTML_BODY,HTML_DIV,HTML_P,HTML_A,HTML_B,HTML_UL,HTML_OL,HTML_LI,HTML_SPAN,HTML_H1,HTML_H2,HTML_H3,HTML_H4,HTML_FORM};
187 char *G_tag_str[] ={
"html",
"head",
"title",
"body",
"div",
"p",
"a",
"b",
"ul",
"ol",
"li",
"span",
"h1",
"h2",
"h3",
"h4",
"form"};
189 Symbol G_stag_sym[] = {HTML_IMG,HTML_INPUT,HTML_BUTTON};
190 char *G_stag_str[] ={
"img",
"input",
"button"};
198 char *stx =
"/ASCII_CHARS/<HTML_TOKENS:(ASCII_CHAR='<',<HTML_TOK_TAG_SELFCLOSE:ASCII_CHAR!={'>',' '}+>,<HTML_ATTRIBUTES:(ASCII_CHAR=' ',<HTML_ATTRIBUTE:<PARAM_KEY:ASCII_CHAR!={'>',' ','='}+>,ASCII_CHAR='=',ASCII_CHAR='\"',<PARAM_VALUE:ASCII_CHAR!='\"'+>,ASCII_CHAR='\"'>)*>,ASCII_CHAR='/',ASCII_CHAR='>'|ASCII_CHAR='<',ASCII_CHAR='/',<HTML_TOK_TAG_CLOSE:ASCII_CHAR!='>'+>,ASCII_CHAR='>'|ASCII_CHAR='<',<HTML_TOK_TAG_OPEN:ASCII_CHAR!={'>',' '}+>,<HTML_ATTRIBUTES:(ASCII_CHAR=' ',<HTML_ATTRIBUTE:<PARAM_KEY:ASCII_CHAR!={'>',' ','='}+>,ASCII_CHAR='=',ASCII_CHAR='\"',<PARAM_VALUE:ASCII_CHAR!='\"'+>,ASCII_CHAR='\"'>)*>,ASCII_CHAR='>'|<HTML_TEXT:ASCII_CHAR!='<'+>)+>";
203 wjson(G_sem,s,
"htmlparse",-1);
204 wjson(G_sem,h,
"htmlascii",-1);
210 wjson(G_sem,tokens,
"html",fnc++);
216 if (semeq(ts,HTML_ATTRIBUTES)) {
220 T *attr = _t_newr(a,HTML_ATTRIBUTE);
236 delta = makeDeltaAdd(src,delta);
237 wjson(G_sem,delta,
"html",fnc++);
246 T *g = _t_news(s,SEMTREX_GROUP,HTML_TAG);
247 T *sq = _t_newr(g,SEMTREX_SEQUENCE);
248 _sl(sq,HTML_TOK_TAG_OPEN);
249 g = _t_news(sq,SEMTREX_GROUP,HTML_CONTENT);
250 T* st = _t_newr(g,SEMTREX_ZERO_OR_MORE);
251 __sl(st,1,2,HTML_TOK_TAG_OPEN,HTML_TOK_TAG_CLOSE);
252 _sl(sq,HTML_TOK_TAG_CLOSE);
266 if (strcmp(otag,ctag)) {raise_error(
"Mismatched tags %s,%s",otag,ctag)};
268 Symbol ts = getTag(otag,G_tag_sym,G_tag_str);
270 T *content = wrap(tokens,results,HTML_CONTENT,HTML_TAG);
279 delta = makeDelta(TREE_DELTA_REPLACE,path,tag,count);
280 wjson(G_sem,delta,
"html",fnc++);
287 g = _t_news(s,SEMTREX_GROUP,HTML_TAG);
288 _sl(g,HTML_TOK_TAG_SELFCLOSE);
294 Symbol ts = getTag(otag,G_stag_sym,G_stag_str);
296 _t_newr(t,HTML_CONTENT);
297 delta = makeDelta(TREE_DELTA_REPLACE,path,t,1);
298 wjson(G_sem,delta,
"html",fnc++);
309 raise_error(
"HTML doesn't match");
312 void testHTTPparseHTML() {
313 T *t = parseHTML(
"<html><body><div>Hello <b>world!</b></div></body></html>");
315 spec_is_str_equal(t2s(t),
"(HTML_HTML (HTML_ATTRIBUTES) (HTML_CONTENT (HTML_BODY (HTML_ATTRIBUTES) (HTML_CONTENT (HTML_DIV (HTML_ATTRIBUTES) (HTML_CONTENT (HTML_TEXT:Hello ) (HTML_B (HTML_ATTRIBUTES) (HTML_CONTENT (HTML_TEXT:world!)))))))))");
322 void *_httptester(
void *arg) {
323 char *result = doSys(
"echo 'GET /path/to/file.ext HTTP/0.9' | nc localhost 8888");
324 spec_is_str_equal(result,
"HTTP/1.1 200 OK\nContent-Type: text/ceptr\n\nsuper cept\n314159\n");
330 void testHTTPedgeReceptor() {
339 _sem_get_by_label(G_sem,
"HTTP",&HTTP);
341 T *http_def = _sem_get_def(G_sem,HTTP);
344 spec_is_str_equal(t2s(http_def),
"(PROTOCOL_DEFINITION (PROTOCOL_LABEL (ENGLISH_LABEL:HTTP)) (PROTOCOL_SEMANTICS (GOAL:HTTP_REQUEST_HANDLER)) (INCLUSION (PNAME:REQUESTING) (LINKAGE (WHICH_ROLE (ROLE:REQUESTER) (ROLE:HTTP_CLIENT))) (LINKAGE (WHICH_ROLE (ROLE:RESPONDER) (ROLE:HTTP_SERVER))) (RESOLUTION (WHICH_SYMBOL (USAGE:REQUEST_TYPE) (ACTUAL_SYMBOL:HTTP_REQUEST))) (RESOLUTION (WHICH_SYMBOL (USAGE:RESPONSE_TYPE) (ACTUAL_SYMBOL:HTTP_RESPONSE))) (RESOLUTION (WHICH_SYMBOL (USAGE:CHANNEL) (ACTUAL_SYMBOL:HTTP_ASPECT))) (RESOLUTION (WHICH_PROCESS (GOAL:REQUEST_HANDLER) (ACTUAL_PROCESS:httpresp)))))");
350 spec_is_str_equal(t2s(t),
"(PROTOCOL_DEFINITION (PROTOCOL_LABEL (ENGLISH_LABEL:HTTP)) (PROTOCOL_SEMANTICS (GOAL:HTTP_REQUEST_HANDLER) (ROLE:HTTP_CLIENT) (USAGE:RESPONSE_HANDLER_PARAMETERS)) (PROTOCOL_DEFAULTS (SEMANTIC_LINK (USAGE:RESPONSE_HANDLER_PARAMETERS) (REPLACEMENT_VALUE (NULL_SYMBOL)))) (backnforth (INITIATE (ROLE:HTTP_CLIENT) (DESTINATION (ROLE:HTTP_SERVER)) (ACTION:send_request)) (EXPECT (ROLE:HTTP_SERVER) (SOURCE (ROLE:HTTP_CLIENT)) (PATTERN (SEMTREX_SYMBOL_LITERAL (SEMTREX_SYMBOL:HTTP_REQUEST))) (ACTION:send_response))))");
353 spec_is_str_equal(t2s(sem_map),
"(SEMANTIC_MAP (SEMANTIC_LINK (ROLE:REQUESTER) (REPLACEMENT_VALUE (ROLE:HTTP_CLIENT))) (SEMANTIC_LINK (ROLE:RESPONDER) (REPLACEMENT_VALUE (ROLE:HTTP_SERVER))) (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (ACTUAL_SYMBOL:HTTP_REQUEST))) (SEMANTIC_LINK (USAGE:RESPONSE_TYPE) (REPLACEMENT_VALUE (ACTUAL_SYMBOL:HTTP_RESPONSE))) (SEMANTIC_LINK (USAGE:CHANNEL) (REPLACEMENT_VALUE (ACTUAL_SYMBOL:HTTP_ASPECT))) (SEMANTIC_LINK (GOAL:REQUEST_HANDLER) (REPLACEMENT_VALUE (ACTUAL_PROCESS:httpresp))))");
359 Xaddr edge = _v_new_receptor(v,v->
r,STREAM_EDGE,r);
361 T *code =
_t_parse(r->
sem,0,
"(CONVERSE (SCOPE (ITERATE (PARAMS) (STREAM_ALIVE (PARAM_REF:/2/1)) (INITIATE_PROTOCOL (PNAME:HTTP) (WHICH_INTERACTION:backnforth) (PROTOCOL_BINDINGS (RESOLUTION (WHICH_RECEPTOR (ROLE:HTTP_CLIENT) %)) (RESOLUTION (WHICH_RECEPTOR (ROLE:HTTP_SERVER) %)) (RESOLUTION (WHICH_PROCESS (GOAL:RESPONSE_HANDLER) (ACTUAL_PROCESS:echo2stream))) (RESOLUTION (WHICH_USAGE (USAGE:RESPONSE_HANDLER_PARAMETERS) (ACTUAL_VALUE (PARAM_REF:/2/1)))) (RESOLUTION (WHICH_VALUE (ACTUAL_SYMBOL:HTTP_REQUEST) (ACTUAL_VALUE (STREAM_READ (PARAM_REF:/2/1) (RESULT_SYMBOL:HTTP_REQUEST)))))) ) ) (STREAM_CLOSE (PARAM_REF:/2/1))) (BOOLEAN:1))",__r_make_addr(0,ACTUAL_RECEPTOR,r->
addr),__r_make_addr(0,ACTUAL_RECEPTOR,r->
addr));
363 T *err_handler =
_t_parse(r->
sem,0,
"(CONTINUE (POP_PATH (PARAM_REF:/4/1/1) (RESULT_SYMBOL:CONTINUE_LOCATION) (POP_COUNT:5)) (CONTINUE_VALUE (BOOLEAN:0)))");
365 SocketListener *l = _r_addListener(r,8888,code,0,err_handler,DELIM_LF);
369 T *res = _t_newr(bindings,RESOLUTION);
370 T *w = _t_newr(res,WHICH_RECEPTOR);
371 _t_news(w,ROLE,HTTP_SERVER);
372 __r_make_addr(w,ACTUAL_RECEPTOR,r->
addr);
373 res = _t_newr(bindings,RESOLUTION);
374 w = _t_newr(res,WHICH_PROCESS);
375 _t_news(w,GOAL,HTTP_REQUEST_HANDLER);
376 _t_news(w,ACTUAL_PROCESS,fill_i_am);
383 _v_start_vmhost(G_vm);
388 rc = pthread_create(&thread,0,_httptester,NULL);
390 raise_error(
"ERROR; return code from pthread_create() is %d\n", rc);
392 pthread_detach(thread);
394 raise_error(
"Error detaching tester thread; return code from pthread_detach() is %d\n", rc);
396 while(!G_done) sleepms(1);
398 debug_disable(D_STREAM+D_SIGNALS+D_TREE+D_PROTOCOL);
399 debug_disable(D_TRANSCODE+D_REDUCE+D_REDUCEV+D_STEP);
406 _v_join_thread(&G_vm->vm_thread);
417 testHTTPedgeReceptor();
T * _t_new_root(Symbol symbol)
T * asciiT_tos(T *asciiT, T *match, T *t, Symbol s)
T * _makeHTTPRequestSemtrex()
T * _t_detach_by_idx(T *t, int i)
int _t_path_depth(int *p)
T * __sl(T *p, bool not, int count,...)
T * _t_child(T *t, int i)
T * makeASCIITree(char *c)
T * _d_build_def_semtrex(SemTable *sem, Symbol s, T *parent)
void _t_insert_at(T *t, int *path, T *i)
ReceptorAddress addr
the address by which to get messages to this receptor instance
VMHost * _v_new()
Creates a new virtual machine host.
int _t_match(T *semtrex, T *t)
T * _o_unwrap(SemTable *sem, T *def, T *sem_map)
T * _t_get_match(T *match, Symbol group)
void _v_activate(VMHost *v, Xaddr x)
SemTable * sem
Semantic Table for definitions on this host.
void _makeTestHTTPResponseProcess(Receptor *r, T **paramsP, Process *pP)
[makeTestHTTPRequestTree]
int _t_matchr(T *semtrex, T *t, T **rP)
SemTable * sem
pointer back to the genotype table for this receptor's vmhost instance
void _o_express_role(Receptor *r, Protocol protocol, Symbol role, Aspect aspect, T *bindings)
T * _makeTestHTTPRequestTree()
[makeTestHTTPRequestTree]
Receptor * r
Receptor data for this vm host.
#define _sl(t, s)
macro to add a single symbol literal to semtrex tree
T * parseSemtrex(SemTable *sem, char *stx)
T * _t_parse(SemTable *sem, T *parent, char *s,...)
void __t_morph(T *t, Symbol s, void *surface, size_t size, int allocate)
char * G_stxs
[makeTestHTTPResponseProcess]
Process _r_define_process(Receptor *r, T *code, char *name, char *intention, T *signature, T *link)
void _t_detach_by_ptr(T *t, T *c)
T * _t_build(SemTable *sem, T *parent,...)