mirror of
https://github.com/coturn/coturn.git
synced 2025-10-28 05:21:00 +01:00
working on https
This commit is contained in:
parent
8d5ccfa445
commit
0aee63f61e
@ -30,6 +30,26 @@
|
||||
|
||||
#include "ns_ioalib_impl.h"
|
||||
|
||||
#include "http_server.h"
|
||||
|
||||
#include <event2/http.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
struct headers_list {
|
||||
size_t n;
|
||||
char **keys;
|
||||
char **values;
|
||||
};
|
||||
|
||||
struct http_headers {
|
||||
struct evkeyvalq *uri_headers;
|
||||
struct headers_list *post_headers;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
static void write_http_echo(ioa_socket_handle s)
|
||||
{
|
||||
if(s && !ioa_socket_tobeclosed(s)) {
|
||||
@ -54,3 +74,188 @@ static void write_http_echo(ioa_socket_handle s)
|
||||
void handle_http_echo(ioa_socket_handle s) {
|
||||
write_http_echo(s);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
static struct headers_list * post_parse(char *data, size_t data_len)
|
||||
{
|
||||
char *post_data = calloc(data_len + 1, sizeof(char));
|
||||
memcpy(post_data, data, data_len);
|
||||
char *fmarker = NULL;
|
||||
char *fsplit = strtok_r(post_data, "&", &fmarker);
|
||||
struct headers_list *list = (struct headers_list*)malloc(sizeof(struct headers_list));
|
||||
ns_bzero(list,sizeof(struct headers_list));
|
||||
while (fsplit != NULL) {
|
||||
char *vmarker = NULL;
|
||||
char *key = strtok_r(fsplit, "=", &vmarker);
|
||||
char *value = strtok_r(NULL, "=", &vmarker);
|
||||
value = value ? value : "";
|
||||
value = evhttp_decode_uri(value);
|
||||
char *p = value;
|
||||
while (*p != '\0') {
|
||||
if (*p == '+')
|
||||
*p = ' ';
|
||||
p++;
|
||||
}
|
||||
list->keys = (char**)realloc(list->keys,sizeof(char*)*(list->n+1));
|
||||
list->keys[list->n] = strdup(key);
|
||||
list->values = (char**)realloc(list->values,sizeof(char*)*(list->n+1));
|
||||
list->values[list->n] = value;
|
||||
++(list->n);
|
||||
fsplit = strtok_r(NULL, "&", &fmarker);
|
||||
}
|
||||
free(post_data);
|
||||
return list;
|
||||
}
|
||||
|
||||
static struct http_request* parse_http_request_1(struct http_request* ret, char* request, int parse_post)
|
||||
{
|
||||
if(ret && request) {
|
||||
|
||||
char* s = strstr(request," HTTP/");
|
||||
if(!s) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
} else {
|
||||
*s = 0;
|
||||
|
||||
struct evhttp_uri *uri = evhttp_uri_parse(request);
|
||||
if(!uri) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
} else {
|
||||
|
||||
const char *query = evhttp_uri_get_query(uri);
|
||||
if(query) {
|
||||
struct evkeyvalq* kv = (struct evkeyvalq*)malloc(sizeof(struct evkeyvalq));
|
||||
ns_bzero(kv,sizeof(struct evkeyvalq));
|
||||
if(evhttp_parse_query_str(query, kv)<0) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
} else {
|
||||
ret->headers = (struct http_headers*)malloc(sizeof(struct http_headers));
|
||||
ns_bzero(ret->headers,sizeof(struct http_headers));
|
||||
ret->headers->uri_headers = kv;
|
||||
}
|
||||
}
|
||||
evhttp_uri_free(uri);
|
||||
|
||||
if(parse_post) {
|
||||
char *body = strstr(s+1,"\r\n\r\n");
|
||||
if(body && body[0]) {
|
||||
if(!ret->headers) {
|
||||
ret->headers = (struct http_headers*)malloc(sizeof(struct http_headers));
|
||||
ns_bzero(ret->headers,sizeof(struct http_headers));
|
||||
}
|
||||
ret->headers->post_headers = post_parse(body,strlen(body));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*s = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct http_request* parse_http_request(char* request) {
|
||||
|
||||
struct http_request* ret = NULL;
|
||||
|
||||
if(request) {
|
||||
|
||||
ret = (struct http_request*)malloc(sizeof(struct http_request));
|
||||
ns_bzero(ret,sizeof(struct http_request));
|
||||
|
||||
if(strstr(request,"GET ") == request) {
|
||||
ret->rtype = HRT_GET;
|
||||
ret = parse_http_request_1(ret,request+4,0);
|
||||
} else if(strstr(request,"POST ") == request) {
|
||||
ret->rtype = HRT_POST;
|
||||
ret = parse_http_request_1(ret,request+5,1);
|
||||
} else {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * get_headers_list_value(struct headers_list *h, const char* key) {
|
||||
const char* ret = NULL;
|
||||
if(h && h->keys && h->values && key && key[0]) {
|
||||
size_t i = 0;
|
||||
for(i=0;i<h->n;++i) {
|
||||
if(h->keys[i] && !strcmp(key,h->keys[i]) && h->values[i]) {
|
||||
ret = h->values[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_headers_list(struct headers_list *h) {
|
||||
if(h) {
|
||||
if(h->keys) {
|
||||
size_t i = 0;
|
||||
for(i=0;i<h->n;++i) {
|
||||
if(h->keys[i]) {
|
||||
free(h->keys[i]);
|
||||
h->keys[i]=NULL;
|
||||
}
|
||||
}
|
||||
free(h->keys);
|
||||
h->keys = NULL;
|
||||
}
|
||||
if(h->values) {
|
||||
size_t i = 0;
|
||||
for(i=0;i<h->n;++i) {
|
||||
if(h->values[i]) {
|
||||
free(h->values[i]);
|
||||
h->values[i]=NULL;
|
||||
}
|
||||
}
|
||||
free(h->values);
|
||||
h->values = NULL;
|
||||
}
|
||||
h->n = 0;
|
||||
free(h);
|
||||
}
|
||||
}
|
||||
|
||||
const char *get_http_header_value(const struct http_request *request, const char* key) {
|
||||
const char *ret = NULL;
|
||||
if(key && key[0] && request && request->headers) {
|
||||
if(request->headers->uri_headers) {
|
||||
ret = evhttp_find_header(request->headers->uri_headers,key);
|
||||
}
|
||||
if(!ret && request->headers->post_headers) {
|
||||
ret = get_headers_list_value(request->headers->post_headers,key);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void free_http_request(struct http_request *request) {
|
||||
if(request) {
|
||||
if(request->headers) {
|
||||
if(request->headers->uri_headers) {
|
||||
evhttp_clear_headers(request->headers->uri_headers);
|
||||
free(request->headers->uri_headers);
|
||||
request->headers->uri_headers = NULL;
|
||||
}
|
||||
if(request->headers->post_headers) {
|
||||
free_headers_list(request->headers->post_headers);
|
||||
request->headers->post_headers = NULL;
|
||||
}
|
||||
free(request->headers);
|
||||
request->headers = NULL;
|
||||
}
|
||||
free(request);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
@ -31,17 +31,38 @@
|
||||
#ifndef __TURN_HTTP_SERVER__
|
||||
#define __TURN_HTTP_SERVER__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ns_turn_utils.h"
|
||||
#include "ns_turn_server.h"
|
||||
#include "apputils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///////// HTTP REQUEST //////////
|
||||
|
||||
enum _HTTP_REQUEST_TYPE {
|
||||
HRT_UNKNOWN=0,
|
||||
HRT_GET,
|
||||
HRT_POST
|
||||
};
|
||||
|
||||
typedef enum _HTTP_REQUEST_TYPE HTTP_REQUEST_TYPE;
|
||||
|
||||
struct http_headers;
|
||||
|
||||
struct http_request {
|
||||
HTTP_REQUEST_TYPE rtype;
|
||||
struct http_headers *headers;
|
||||
};
|
||||
|
||||
struct http_request* parse_http_request(char* request);
|
||||
const char *get_http_header_value(const struct http_request *request, const char* key);
|
||||
void free_http_request(struct http_request *request);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
void handle_http_echo(ioa_socket_handle s);
|
||||
|
||||
@ -2601,7 +2601,7 @@ void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s)
|
||||
if (s && ioa_socket_tobeclosed(s)) {
|
||||
|
||||
if(!(s->session) && !(s->sub_session)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_type(s));
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s));
|
||||
IOA_CLOSE_SOCKET(s);
|
||||
return;
|
||||
}
|
||||
@ -2782,7 +2782,7 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg)
|
||||
if(!(s->session) && !(s->sub_session)) {
|
||||
char sraddr[129]="\0";
|
||||
addr_to_string(&(s->remote_addr),(u08bits*)sraddr);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d, remote addr=%s\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_type(s),sraddr);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s https server socket closed: 0x%lx, st=%d, sat=%d, remote addr=%s\n", __FUNCTION__,(long)s, get_ioa_socket_type(s), get_ioa_socket_app_type(s),sraddr);
|
||||
IOA_CLOSE_SOCKET(s);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1390,7 +1390,13 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) {
|
||||
handle_http_echo(s);
|
||||
} else {
|
||||
if(nbh) {
|
||||
struct http_request* hr = parse_http_request((char*)ioa_network_buffer_data(nbh));
|
||||
if(!hr) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong HTTPS request (I cannot parse it)\n", __FUNCTION__);
|
||||
} else {
|
||||
//TODO
|
||||
free_http_request(hr);
|
||||
}
|
||||
}
|
||||
write_https_default_page(s);
|
||||
}
|
||||
|
||||
@ -646,9 +646,9 @@ static inline const char* findstr(const char *hay, size_t slen, const char *need
|
||||
static inline int is_http_get_inline(const char *s, size_t blen) {
|
||||
if(s && blen>=12) {
|
||||
if((s[0]=='G')&&(s[1]=='E')&&(s[2]=='T')&&(s[3]==' ')) {
|
||||
const char *sp=findstr(s+4,blen-4,"HTTP");
|
||||
const char *sp=findstr(s+4,blen-4," HTTP/");
|
||||
if(sp) {
|
||||
sp += 4;
|
||||
sp += 6;
|
||||
size_t diff_blen = sp-s;
|
||||
if(diff_blen+4 <= blen) {
|
||||
sp=findstr(sp,blen-diff_blen,"\r\n\r\n");
|
||||
|
||||
@ -4545,10 +4545,10 @@ static int read_client_connection(turn_turnserver *server,
|
||||
set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh));
|
||||
if(server->send_https_socket) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_type(ss->client_socket));
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket));
|
||||
ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket);
|
||||
if(new_s) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_type(new_s));
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s));
|
||||
server->send_https_socket(new_s);
|
||||
}
|
||||
ss->to_be_closed = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user