split api handling
[src/app-framework-binder.git] / src / afb-hswitch.c
1 /* 
2  * Copyright (C) 2015 "IoT.bzh"
3  * Author "Fulup Ar Foll"
4  * Author José Bollo <jose.bollo@iot.bzh>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #define _GNU_SOURCE
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "afb-req-itf.h"
25 #include "afb-hreq.h"
26 #include "afb-apis.h"
27 #include "session.h"
28 #include "afb-websock.h"
29
30 int afb_hswitch_apis(struct afb_hreq *hreq, void *data)
31 {
32         const char *api, *verb;
33         size_t lenapi, lenverb;
34         struct AFB_clientCtx *context;
35
36         api = &hreq->tail[strspn(hreq->tail, "/")];
37         lenapi = strcspn(api, "/");
38         verb = &api[lenapi];
39         verb = &verb[strspn(verb, "/")];
40         lenverb = strcspn(verb, "/");
41
42         if (!(*api && *verb && lenapi && lenverb))
43                 return 0;
44
45         context = afb_hreq_context(hreq);
46         afb_apis_call(afb_hreq_to_req(hreq), context, api, lenapi, verb, lenverb);
47         return 1;
48 }
49
50 int afb_hswitch_one_page_api_redirect(struct afb_hreq *hreq, void *data)
51 {
52         size_t plen;
53         char *url;
54
55         if (hreq->lentail >= 2 && hreq->tail[1] == '#')
56                 return 0;
57         /*
58          * Here we have for example:
59          *    url  = "/pre/dir/page"   lenurl = 13
60          *    tail =     "/dir/page"   lentail = 9
61          *
62          * We will produce "/pre/#!dir/page"
63          *
64          * Let compute plen that include the / at end (for "/pre/")
65          */
66         plen = hreq->lenurl - hreq->lentail + 1;
67         url = alloca(hreq->lenurl + 3);
68         memcpy(url, hreq->url, plen);
69         url[plen++] = '#';
70         url[plen++] = '!';
71         memcpy(&url[plen], &hreq->tail[1], hreq->lentail);
72         return afb_hreq_redirect_to(hreq, url);
73 }
74
75 int afb_hswitch_websocket_switch(struct afb_hreq *hreq, void *data)
76 {
77         int later;
78
79         afb_hreq_context(hreq);
80         if (hreq->lentail != 0 || !afb_websock_check(hreq, &later))
81                 return 0;
82
83         if (!later) {
84                 struct afb_websock *ws = afb_websock_create(hreq);
85                 if (ws != NULL)
86                         hreq->upgrade = 1;
87         }
88         return 1;
89 }
90
91
92