1
0
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:
mom040267 2015-01-04 09:09:52 +00:00
parent 8d5ccfa445
commit 0aee63f61e
6 changed files with 242 additions and 10 deletions

View File

@ -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);
}
}
///////////////////////////////////////////////

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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");

View File

@ -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;