Statistics
| Branch: | Revision:

peerstreamer-src / src / path_handlers.c @ 58fb2cdc

History | View | Annotate | Download (9.02 KB)

1 c039490c Luca Baldesi
/*******************************************************************
2
* PeerStreamer-ng is a P2P video streaming application exposing a ReST
3
* interface.
4
* Copyright (C) 2015 Luca Baldesi <luca.baldesi@unitn.it>
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Affero General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU Affero General Public License for more details.
15
*
16
* You should have received a copy of the GNU Affero General Public License
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*******************************************************************/
19
20
#include<stdint.h>
21
#include<pschannel.h>
22
#include<router.h>
23
#include<tokens.h>
24
#include<name_lengths.h>
25
#include<debug.h>
26
#include<pschannel.h>
27
#include<context.h>
28
#include<mongoose.h>
29 c81c126e Luca Baldesi
#include<streamer_creation_callback.h>
30 c039490c Luca Baldesi
31
char * mg_uri_field(struct http_message *hm, uint8_t pos)
32
{
33
        char * uri;
34
        char ** tokens;
35
        uint32_t ntok;
36
37
        uri = malloc((hm->uri.len + 1) * sizeof(char));
38
        strncpy(uri, hm->uri.p, hm->uri.len);
39
        uri[hm->uri.len] = '\0';
40
41
        tokens = tokens_create(uri, '/', &ntok);
42
        
43
        strcpy(uri, tokens[pos]);
44
        tokens_destroy(&tokens, ntok);
45
46
        return uri;
47
}
48
49
void channel_index(struct mg_connection *nc, struct http_message *hm)
50
{
51
        char * channels;
52
        const struct context * c;
53
54
        c = (const struct context *) nc->user_data;
55
56 91e9f1a7 Luca Baldesi
        info("GET request for channels\n");
57 c039490c Luca Baldesi
        channels = pschannel_bucket_to_json(c->pb);
58
        debug("\t%s\n", channels);
59
60 a95383e2 Luca Baldesi
        mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
61 c039490c Luca Baldesi
        mg_printf_http_chunk(nc, "%s", channels);
62
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
63
64
        free(channels);
65
}
66
67 3af4c8d7 Luca Baldesi
int8_t source_streamer_creation_handler(struct mg_connection *nc, const struct pschannel_bucket *psb, const struct pstreamer * ps, int8_t ret)
68
{
69
        char * json = NULL;
70
        int8_t res = -1;
71
72
        info("Inside source creation handler\n");
73
        if (ps)
74
                json = pstreamer_to_json(ps);
75
76
        if (ret == 0 && json)
77
        {
78
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
79
                mg_printf_http_chunk(nc, json);
80
                res = 0;
81
                info("Source room created and served\n");
82
        } else {
83
                mg_printf(nc, "%s", "HTTP/1.1 500 Internal server error\r\nTransfer-Encoding: chunked\r\n\r\n");
84
                // destroy ps?
85
                info("Stream room cannot be correctly created\n");
86
                if (ret)
87
                        debug(json);
88
                else
89
                        debug("PS does not exist");
90
        }
91
        if (json)
92
                free(json);
93
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
94
95
        return res;
96
}
97
98 92a361ca Luca Baldesi
int8_t streamer_creation_handler(struct mg_connection *nc, const struct pschannel_bucket *psb, const struct pstreamer * ps, int8_t ret)
99 c81c126e Luca Baldesi
{
100
        char * json = NULL;
101
        int8_t res = -1;
102 92a361ca Luca Baldesi
        const struct pschannel * ch = NULL;
103 c81c126e Luca Baldesi
104
        info("Inside creation handler\n");
105
        if (ps)
106 92a361ca Luca Baldesi
        {
107
                ch = pschannel_bucket_find(psb, pstreamer_source_ipaddr(ps), pstreamer_source_port(ps));
108 c81c126e Luca Baldesi
                json = pstreamer_to_json(ps);
109 92a361ca Luca Baldesi
                if (ch)
110
                        json[strlen(json)-1] = '\0';
111
        }
112 c81c126e Luca Baldesi
113
        if (ret == 0 && json)
114
        {
115 a95383e2 Luca Baldesi
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
116 c81c126e Luca Baldesi
                mg_printf_http_chunk(nc, json);
117 92a361ca Luca Baldesi
                if (ch)
118
                        mg_printf_http_chunk(nc, ",\"name\":\"%s\"}", ch->name);
119 c81c126e Luca Baldesi
                res = 0;
120
                info("Stream created and served\n");
121
        } else {
122
                mg_printf(nc, "%s", "HTTP/1.1 500 Internal server error\r\nTransfer-Encoding: chunked\r\n\r\n");
123
                // destroy ps?
124
                info("Stream cannot be correctly served\n");
125
                if (ret)
126
                        debug(json);
127
                else
128
                        debug("PS does not exist");
129
        }
130
        if (json)
131
                free(json);
132
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
133
134
        return res;
135
}
136
137 c039490c Luca Baldesi
void streamer_create(struct mg_connection *nc, struct http_message *hm)
138
{
139
        const struct context * c;
140
        char ipaddr[MAX_IPADDR_LENGTH];
141 91e9f1a7 Luca Baldesi
        char rtp_dst_ip[MAX_IPADDR_LENGTH];
142 c039490c Luca Baldesi
        char port[MAX_PORT_LENGTH];
143 c81c126e Luca Baldesi
        char * id;
144
        const struct pstreamer * ps = NULL;
145
        const struct pschannel * ch = NULL;
146 c039490c Luca Baldesi
147
        c = (const struct context *) nc->user_data;
148
        mg_get_http_var(&hm->body, "ipaddr", ipaddr, MAX_IPADDR_LENGTH);
149
        mg_get_http_var(&hm->body, "port", port, MAX_PORT_LENGTH);
150
151
        id = mg_uri_field(hm, 1);
152 3af4c8d7 Luca Baldesi
        mg_conn_addr_to_str(nc, rtp_dst_ip, MAX_IPADDR_LENGTH, MG_SOCK_STRINGIFY_IP|MG_SOCK_STRINGIFY_REMOTE);
153 c039490c Luca Baldesi
154 91e9f1a7 Luca Baldesi
        info("POST request for resource %s from %s\n", id, rtp_dst_ip);
155 c039490c Luca Baldesi
        ch = pschannel_bucket_find(c->pb, ipaddr, port);
156
157
        if (ch)
158
        {
159
                debug("Channel: %s\n", ch->name);
160 92a361ca Luca Baldesi
                ps = pstreamer_manager_create_streamer(c->psm, ipaddr, port, id, rtp_dst_ip, streamer_creation_callback_new(nc, c->pb, streamer_creation_handler)); 
161 c039490c Luca Baldesi
                if(ps)
162
                {
163 b87dc7a2 Luca Baldesi
                        pstreamer_schedule_tasks((struct pstreamer*)ps, c->tm);
164 91e9f1a7 Luca Baldesi
                        info("Streamer instance created\n");
165 c039490c Luca Baldesi
                } else {
166 91e9f1a7 Luca Baldesi
                        info("Streamer could not be launched\n");
167 c039490c Luca Baldesi
                        mg_printf(nc, "%s", "HTTP/1.1 409 Conflict\r\nTransfer-Encoding: chunked\r\n\r\n");
168
                        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
169
                }
170
        } else {
171 91e9f1a7 Luca Baldesi
                info("No channel found for socket <%s:%s>\n", ipaddr, port);
172 c039490c Luca Baldesi
                mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
173
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
174
        }
175
176
        free(id);
177
}
178 4d6f8fd5 Luca Baldesi
179
void streamer_update(struct mg_connection *nc, struct http_message *hm)
180
{
181 eab111d2 Luca Baldesi
        char * id, * json;
182 4d6f8fd5 Luca Baldesi
        const struct pstreamer * ps;
183
        const struct context * c;
184
185
        c = (const struct context *) nc->user_data;
186
        id = mg_uri_field(hm, 1);
187
188
        ps = pstreamer_manager_get_streamer(c->psm, id);
189 91e9f1a7 Luca Baldesi
        info("UPDATE request for resource %s\n", id);
190 4d6f8fd5 Luca Baldesi
        if (ps)
191
        {
192
                pstreamer_touch((struct pstreamer*) ps);
193 91e9f1a7 Luca Baldesi
                info("\tInstance %s found and touched\n", id);
194 eab111d2 Luca Baldesi
                json = pstreamer_to_json(ps);
195 a95383e2 Luca Baldesi
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
196 eab111d2 Luca Baldesi
                mg_printf_http_chunk(nc, "%s", json);
197
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
198
                free(json);
199
        } else {
200 91e9f1a7 Luca Baldesi
                info("\tInstance %s not found\n", id);
201 eab111d2 Luca Baldesi
                mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
202
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
203
        }
204 4d6f8fd5 Luca Baldesi
205
        free(id);
206
}
207 3af4c8d7 Luca Baldesi
208
void source_index(struct mg_connection *nc, struct http_message *hm)
209
{
210
        char * channels;
211
        const struct context * c;
212
213
        c = (const struct context *) nc->user_data;
214
215
        info("GET request for source\n");
216
        channels = pstreamer_manager_sources_to_json(c->psm);
217
        debug("\t%s\n", channels);
218
219
        mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
220
        mg_printf_http_chunk(nc, "%s", channels);
221
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
222
223
        free(channels);
224
}
225
226
void source_streamer_create(struct mg_connection *nc, struct http_message *hm)
227
{
228
        const struct context * c;
229
        char rtp_source_ip[MAX_IPADDR_LENGTH];
230
        char * id;
231
        const struct pstreamer * ps = NULL;
232
        const struct pschannel * ch = NULL;
233
234
        c = (const struct context *) nc->user_data;
235
236
        id = mg_uri_field(hm, 1);
237
        mg_conn_addr_to_str(nc, rtp_source_ip, MAX_IPADDR_LENGTH, MG_SOCK_STRINGIFY_IP);
238
239
        info("POST request for source resource %s from %s\n", id, rtp_source_ip);
240
241
        ps = pstreamer_manager_create_source_streamer(c->psm, id, rtp_source_ip, streamer_creation_callback_new(nc, c->pb, source_streamer_creation_handler)); 
242
        if(ps)
243
        {
244
                pstreamer_schedule_tasks((struct pstreamer*)ps, c->tm);
245
                info("Source streamer instance created\n");
246
        } else {
247
                info("Source streamer could not be launched\n");
248
                mg_printf(nc, "%s", "HTTP/1.1 409 Conflict\r\nTransfer-Encoding: chunked\r\n\r\n");
249
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
250
        }
251
252
        free(id);
253
}
254
255
void source_streamer_update(struct mg_connection *nc, struct http_message *hm)
256
{
257
        char * id, * json;
258
        char janus_user_id[MAX_JANUS_USERID_LENGTH+1];
259
        const struct pstreamer * ps;
260
        const struct context * c;
261
262
        c = (const struct context *) nc->user_data;
263
        id = mg_uri_field(hm, 1);
264
265
        ps = pstreamer_manager_get_streamer(c->psm, id);
266 58fb2cdc Luca Baldesi
        janus_user_id[0] = '\0';
267 3af4c8d7 Luca Baldesi
        info("UPDATE request for source resource %s\n", id);
268
        if (ps)
269
        {
270
                mg_get_http_var(&hm->body, "participant_id", janus_user_id, MAX_JANUS_USERID_LENGTH);
271
272 58fb2cdc Luca Baldesi
                if (strlen(janus_user_id) > 0)
273
                {
274
                        info("\tFound Participant ID: %s\n", janus_user_id);
275
                        pstreamer_source_touch(c->psm, (struct pstreamer*) ps, atoll(janus_user_id));
276
                } else
277
                        pstreamer_touch((struct pstreamer*) ps);
278
279 3af4c8d7 Luca Baldesi
                info("\tSource instance %s found and touched\n", id);
280
                json = pstreamer_to_json(ps);
281
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-type: application/json\r\n\r\n");
282
                mg_printf_http_chunk(nc, "%s", json);
283
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
284
                free(json);
285
        } else {
286
                info("\tInstance %s not found\n", id);
287
                mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
288
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
289
        }
290
        free(id);
291
}