mirror of
https://github.com/coturn/coturn.git
synced 2025-10-28 21:41:29 +01:00
working on https
This commit is contained in:
parent
8d5ccfa445
commit
0aee63f61e
@ -30,6 +30,26 @@
|
|||||||
|
|
||||||
#include "ns_ioalib_impl.h"
|
#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)
|
static void write_http_echo(ioa_socket_handle s)
|
||||||
{
|
{
|
||||||
if(s && !ioa_socket_tobeclosed(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) {
|
void handle_http_echo(ioa_socket_handle s) {
|
||||||
write_http_echo(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__
|
#ifndef __TURN_HTTP_SERVER__
|
||||||
#define __TURN_HTTP_SERVER__
|
#define __TURN_HTTP_SERVER__
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "ns_turn_utils.h"
|
#include "ns_turn_utils.h"
|
||||||
#include "ns_turn_server.h"
|
#include "ns_turn_server.h"
|
||||||
#include "apputils.h"
|
#include "apputils.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
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 && ioa_socket_tobeclosed(s)) {
|
||||||
|
|
||||||
if(!(s->session) && !(s->sub_session)) {
|
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);
|
IOA_CLOSE_SOCKET(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2782,7 +2782,7 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg)
|
|||||||
if(!(s->session) && !(s->sub_session)) {
|
if(!(s->session) && !(s->sub_session)) {
|
||||||
char sraddr[129]="\0";
|
char sraddr[129]="\0";
|
||||||
addr_to_string(&(s->remote_addr),(u08bits*)sraddr);
|
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);
|
IOA_CLOSE_SOCKET(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1390,7 +1390,13 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) {
|
|||||||
handle_http_echo(s);
|
handle_http_echo(s);
|
||||||
} else {
|
} else {
|
||||||
if(nbh) {
|
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
|
//TODO
|
||||||
|
free_http_request(hr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write_https_default_page(s);
|
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) {
|
static inline int is_http_get_inline(const char *s, size_t blen) {
|
||||||
if(s && blen>=12) {
|
if(s && blen>=12) {
|
||||||
if((s[0]=='G')&&(s[1]=='E')&&(s[2]=='T')&&(s[3]==' ')) {
|
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) {
|
if(sp) {
|
||||||
sp += 4;
|
sp += 6;
|
||||||
size_t diff_blen = sp-s;
|
size_t diff_blen = sp-s;
|
||||||
if(diff_blen+4 <= blen) {
|
if(diff_blen+4 <= blen) {
|
||||||
sp=findstr(sp,blen-diff_blen,"\r\n\r\n");
|
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);
|
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));
|
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) {
|
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);
|
ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket);
|
||||||
if(new_s) {
|
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);
|
server->send_https_socket(new_s);
|
||||||
}
|
}
|
||||||
ss->to_be_closed = 1;
|
ss->to_be_closed = 1;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user