Statistics
| Branch: | Revision:

peerstreamer-src / src / path_handlers.c @ c81c126e

History | View | Annotate | Download (5.19 KB)

1
/*******************************************************************
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
#include<streamer_creation_callback.h>
30

    
31
void mg_connection_remote_ip(char * ip, const struct mg_connection *nc)
32
{
33
        const struct sockaddr_in *sender;
34
        sender = (struct sockaddr_in *)&(nc->sa);
35
        inet_ntop(AF_INET, &(sender->sin_addr), ip, MAX_IPADDR_LENGTH);
36
}
37

    
38
char * mg_uri_field(struct http_message *hm, uint8_t pos)
39
{
40
        char * uri;
41
        char ** tokens;
42
        uint32_t ntok;
43

    
44
        uri = malloc((hm->uri.len + 1) * sizeof(char));
45
        strncpy(uri, hm->uri.p, hm->uri.len);
46
        uri[hm->uri.len] = '\0';
47

    
48
        tokens = tokens_create(uri, '/', &ntok);
49
        
50
        strcpy(uri, tokens[pos]);
51
        tokens_destroy(&tokens, ntok);
52

    
53
        return uri;
54
}
55

    
56
void channel_index(struct mg_connection *nc, struct http_message *hm)
57
{
58
        char * channels;
59
        const struct context * c;
60

    
61
        c = (const struct context *) nc->user_data;
62

    
63
        info("GET request for channels\n");
64
        channels = pschannel_bucket_to_json(c->pb);
65
        debug("\t%s\n", channels);
66

    
67
        mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
68
        mg_printf_http_chunk(nc, "%s", channels);
69
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
70

    
71
        free(channels);
72
}
73

    
74
int8_t streamer_creation_handler(struct mg_connection *nc, const struct pstreamer * ps, int8_t ret)
75
{
76
        char * json = NULL;
77
        int8_t res = -1;
78

    
79
        info("Inside creation handler\n");
80
        if (ps)
81
                json = pstreamer_to_json(ps);
82

    
83
        if (ret == 0 && json)
84
        {
85
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
86
                mg_printf_http_chunk(nc, json);
87
                res = 0;
88
                info("Stream created and served\n");
89
        } else {
90
                mg_printf(nc, "%s", "HTTP/1.1 500 Internal server error\r\nTransfer-Encoding: chunked\r\n\r\n");
91
                // destroy ps?
92
                info("Stream cannot be correctly served\n");
93
                if (ret)
94
                        debug(json);
95
                else
96
                        debug("PS does not exist");
97
        }
98
        if (json)
99
                free(json);
100
        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
101

    
102
        return res;
103
}
104

    
105
void streamer_create(struct mg_connection *nc, struct http_message *hm)
106
{
107
        const struct context * c;
108
        char ipaddr[MAX_IPADDR_LENGTH];
109
        char rtp_dst_ip[MAX_IPADDR_LENGTH];
110
        char port[MAX_PORT_LENGTH];
111
        char * id;
112
        const struct pstreamer * ps = NULL;
113
        const struct pschannel * ch = NULL;
114

    
115
        c = (const struct context *) nc->user_data;
116
        mg_get_http_var(&hm->body, "ipaddr", ipaddr, MAX_IPADDR_LENGTH);
117
        mg_get_http_var(&hm->body, "port", port, MAX_PORT_LENGTH);
118

    
119
        id = mg_uri_field(hm, 1);
120
        mg_connection_remote_ip(rtp_dst_ip, nc);
121

    
122
        info("POST request for resource %s from %s\n", id, rtp_dst_ip);
123
        ch = pschannel_bucket_find(c->pb, ipaddr, port);
124

    
125
        if (ch)
126
        {
127
                debug("Channel: %s\n", ch->name);
128
                ps = pstreamer_manager_create_streamer(c->psm, ipaddr, port, id, rtp_dst_ip, streamer_creation_callback_new(nc, streamer_creation_handler)); 
129
                if(ps)
130
                {
131
                        pstreamer_schedule_tasks((struct pstreamer*)ps, c->tm);
132
                        info("Streamer instance created\n");
133
                } else {
134
                        info("Streamer could not be launched\n");
135
                        mg_printf(nc, "%s", "HTTP/1.1 409 Conflict\r\nTransfer-Encoding: chunked\r\n\r\n");
136
                        mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
137
                }
138
        } else {
139
                info("No channel found for socket <%s:%s>\n", ipaddr, port);
140
                mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
141
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
142
        }
143

    
144
        free(id);
145
}
146

    
147
void streamer_update(struct mg_connection *nc, struct http_message *hm)
148
{
149
        char * id, * json;
150
        const struct pstreamer * ps;
151
        const struct context * c;
152

    
153
        c = (const struct context *) nc->user_data;
154
        id = mg_uri_field(hm, 1);
155

    
156
        ps = pstreamer_manager_get_streamer(c->psm, id);
157
        info("UPDATE request for resource %s\n", id);
158
        if (ps)
159
        {
160
                pstreamer_touch((struct pstreamer*) ps);
161
                info("\tInstance %s found and touched\n", id);
162
                json = pstreamer_to_json(ps);
163
                mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
164
                mg_printf_http_chunk(nc, "%s", json);
165
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
166
                free(json);
167
        } else {
168
                info("\tInstance %s not found\n", id);
169
                mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
170
                mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
171
        }
172

    
173
        free(id);
174
}