working on https

libevent.rpm
mom040267 11 years ago
parent 385bb2fe9b
commit bd8c39c3b7
  1. 77
      src/apps/relay/http_server.c
  2. 16
      src/apps/relay/http_server.h
  3. 45
      src/apps/relay/ns_ioalib_engine_impl.c
  4. 6
      src/apps/relay/ns_ioalib_impl.h
  5. 48
      src/apps/relay/turn_admin_server.c
  6. 2
      src/apps/relay/turn_admin_server.h
  7. 41
      src/client/ns_turn_msg.c
  8. 2
      src/client/ns_turn_msg.h
  9. 2
      src/server/ns_turn_server.c

@ -138,6 +138,11 @@ static struct http_request* parse_http_request_1(struct http_request* ret, char*
ret->headers->uri_headers = kv;
}
}
const char *path = evhttp_uri_get_path(uri);
if(path)
ret->path = strdup(path);
evhttp_uri_free(uri);
if(parse_post) {
@ -174,6 +179,12 @@ struct http_request* parse_http_request(char* request) {
} else if(strstr(request,"POST ") == request) {
ret->rtype = HRT_POST;
ret = parse_http_request_1(ret,request+5,1);
} else if(strstr(request,"PUT ") == request) {
ret->rtype = HRT_PUT;
ret = parse_http_request_1(ret,request+4,1);
} else if(strstr(request,"DELETE ") == request) {
ret->rtype = HRT_DELETE;
ret = parse_http_request_1(ret,request+7,1);
} else {
free(ret);
ret = NULL;
@ -241,6 +252,10 @@ const char *get_http_header_value(const struct http_request *request, const char
void free_http_request(struct http_request *request) {
if(request) {
if(request->path) {
free(request->path);
request->path = NULL;
}
if(request->headers) {
if(request->headers->uri_headers) {
evhttp_clear_headers(request->headers->uri_headers);
@ -258,4 +273,66 @@ void free_http_request(struct http_request *request) {
}
}
////////////////////////////////////////////
struct str_buffer {
size_t capacity;
size_t sz;
char* buffer;
};
struct str_buffer* str_buffer_new(void)
{
struct str_buffer* ret = (struct str_buffer*)malloc(sizeof(struct str_buffer));
ns_bzero(ret,sizeof(struct str_buffer));
ret->buffer = (char*)malloc(1);
ret->buffer[0] = 0;
ret->capacity = 1;
return ret;
}
void str_buffer_append(struct str_buffer* sb, const char* str)
{
if(sb && str && str[0]) {
size_t len = strlen(str);
while(sb->sz + len + 1 > sb->capacity) {
sb->capacity += len + 1024;
sb->buffer = (char*)realloc(sb->buffer,sb->capacity);
}
ns_bcopy(str,sb->buffer+sb->sz,len+1);
sb->sz += len;
}
}
void str_buffer_append_sz(struct str_buffer* sb, size_t sz)
{
char ssz[129];
snprintf(ssz,sizeof(ssz)-1,"%lu",(unsigned long)sz);
str_buffer_append(sb,ssz);
}
const char* str_buffer_get_str(const struct str_buffer *sb)
{
if(sb) {
return sb->buffer;
}
return NULL;
}
size_t str_buffer_get_str_len(const struct str_buffer *sb)
{
if(sb) {
return sb->sz;
}
return 0;
}
void str_buffer_free(struct str_buffer *sb)
{
if(sb) {
free(sb->buffer);
free(sb);
}
}
///////////////////////////////////////////////

@ -47,7 +47,9 @@ extern "C" {
enum _HTTP_REQUEST_TYPE {
HRT_UNKNOWN=0,
HRT_GET,
HRT_POST
HRT_POST,
HRT_PUT,
HRT_DELETE
};
typedef enum _HTTP_REQUEST_TYPE HTTP_REQUEST_TYPE;
@ -56,6 +58,7 @@ struct http_headers;
struct http_request {
HTTP_REQUEST_TYPE rtype;
char *path;
struct http_headers *headers;
};
@ -65,6 +68,17 @@ void free_http_request(struct http_request *request);
////////////////////////////////////////////
struct str_buffer;
struct str_buffer* str_buffer_new(void);
void str_buffer_append(struct str_buffer* sb, const char* str);
void str_buffer_append_sz(struct str_buffer* sb, size_t sz);
const char* str_buffer_get_str(const struct str_buffer *sb);
size_t str_buffer_get_str_len(const struct str_buffer *sb);
void str_buffer_free(struct str_buffer *sb);
////////////////////////////////////////////
void handle_http_echo(ioa_socket_handle s);
////////////////////////////////////////////

@ -3191,6 +3191,51 @@ int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr* dest_addr,
return ret;
}
int send_data_from_ioa_socket_tcp(ioa_socket_handle s, const void *data, size_t sz)
{
int ret = -1;
if(s && data) {
if (s->done || (s->fd == -1) || ioa_socket_tobeclosed(s) || !(s->e)) {
TURN_LOG_FUNC(
TURN_LOG_LEVEL_INFO,
"!!! %s: (1) Trying to send data from bad socket: 0x%lx (1): done=%d, fd=%d, st=%d, sat=%d\n",
__FUNCTION__, (long) s, (int) s->done,
(int) s->fd, s->st, s->sat);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s socket: 0x%lx was closed\n", __FUNCTION__,(long)s);
} else if (s->connected && s->bev) {
if (s->st == TLS_SOCKET) {
#if TLS_SUPPORTED
SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
if (!ctx || SSL_get_shutdown(ctx)) {
s->tobeclosed = 1;
ret = 0;
}
#endif
}
if (!(s->tobeclosed)) {
ret = (int)sz;
s->in_write = 1;
if (bufferevent_write(s->bev, data, sz) < 0) {
ret = -1;
perror("bufev send");
log_socket_event(s, "socket write failed, to be closed", 1);
s->tobeclosed = 1;
s->broken = 1;
}
s->in_write = 0;
}
}
}
return ret;
}
int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, int event_type, ioa_net_event_handler cb, void* ctx, int clean_preexisting)
{
if(s) {

@ -66,6 +66,8 @@ extern "C" {
#define MAX_BUFFER_QUEUE_SIZE_PER_ENGINE (64)
#define MAX_SOCKET_BUFFER_BACKLOG (16)
#define ADMIN_USER_MAX_LENGTH (32)
#define BUFFEREVENT_HIGH_WATERMARK (128<<10)
#define BUFFEREVENT_MAX_UDP_TO_TCP_WRITE (64<<9)
#define BUFFEREVENT_MAX_TCP_TO_TCP_WRITE (192<<10)
@ -225,7 +227,7 @@ struct _ioa_socket
/* <<== RFC 6062 */
//Admin server:
int as_ok;
char as_login[17];
char as_login[ADMIN_USER_MAX_LENGTH + 1];
char as_realm[STUN_MAX_REALM_SIZE + 1];
};
@ -301,6 +303,8 @@ int set_socket_options(ioa_socket_handle s);
int send_session_cancellation_to_relay(turnsession_id sid);
int send_data_from_ioa_socket_tcp(ioa_socket_handle s, const void *data, size_t sz);
///////////////////////// SUPER MEMORY ////////
#define allocate_super_memory_engine(e,size) allocate_super_memory_engine_func(e, size, __FILE__, __FUNCTION__, __LINE__)

@ -1249,7 +1249,7 @@ void setup_cli_thread(void)
cliserver.https_in_buf = pair[0];
cliserver.https_out_buf = pair[1];
bufferevent_setcb(cliserver.https_in_buf, https_cli_server_receive_message, NULL, NULL, &cliserver);
bufferevent_setcb(cliserver.https_in_buf, https_admin_server_receive_message, NULL, NULL, &cliserver);
bufferevent_enable(cliserver.https_in_buf, EV_READ);
}
@ -1360,19 +1360,35 @@ int send_turn_session_info(struct turn_session_info* tsi)
static void write_https_logon_page(ioa_socket_handle s)
{
if(s && !ioa_socket_tobeclosed(s)) {
//TODO
ioa_network_buffer_handle nbh_http = ioa_network_buffer_allocate(s->e);
size_t len_http = ioa_network_buffer_get_size(nbh_http);
u08bits *data = ioa_network_buffer_data(nbh_http);
char data_http[1025];
char content_http[1025];
const char* title = "HTTPS TURN Server";
snprintf(content_http,sizeof(content_http)-1,"<!DOCTYPE html>\r\n<html>\r\n <head>\r\n <title>%s</title>\r\n </head>\r\n <body>\r\n %s\r\n </body>\r\n</html>\r\n",title,title);
snprintf(data_http,sizeof(data_http)-1,"HTTP/1.1 200 OK\r\nServer: %s\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s",TURN_SOFTWARE,(int)strlen(content_http),content_http);
len_http = strlen(data_http);
ns_bcopy(data_http,data,len_http);
ioa_network_buffer_set_size(nbh_http,len_http);
send_data_from_ioa_socket_nbh(s, NULL, nbh_http, TTL_IGNORE, TOS_IGNORE);
struct str_buffer* sb = str_buffer_new();
const char* title = "TURN Server (https admin connection)";
str_buffer_append(sb,"<!DOCTYPE html>\r\n<html>\r\n <head>\r\n <title>");
str_buffer_append(sb,title);
str_buffer_append(sb,"</title>\r\n </head>\r\n <body>\r\n ");
str_buffer_append(sb,title);
str_buffer_append(sb,"<br>\r\n");
str_buffer_append(sb,"<form action=\"logon\" method=\"POST\">\r\n");
str_buffer_append(sb," <fieldset><legend>Admin user information:</legend> user name:<br><input type=\"text\" name=\"uname\" value=\"\"><br>password:<br><input type=\"password\" name=\"pwd\" value=\"\"><br><br><input type=\"submit\" value=\"Login\"></fieldset>\r\n");
str_buffer_append(sb,"</form>\r\n");
str_buffer_append(sb,"\r\n </body>\r\n</html>\r\n");
struct str_buffer* sb_http = str_buffer_new();
str_buffer_append(sb_http,"HTTP/1.1 200 OK\r\nServer: ");
str_buffer_append(sb_http,TURN_SOFTWARE);
str_buffer_append(sb_http,"\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: ");
str_buffer_append_sz(sb_http,str_buffer_get_str_len(sb));
str_buffer_append(sb_http,"\r\n\r\n");
str_buffer_append(sb_http,str_buffer_get_str(sb));
str_buffer_free(sb);
send_data_from_ioa_socket_tcp(s, str_buffer_get_str(sb_http), str_buffer_get_str_len(sb_http));
str_buffer_free(sb_http);
}
}
@ -1393,6 +1409,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: wrong HTTPS request (I cannot parse it)\n", __FUNCTION__);
} else {
//TODO
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: HTTPS request, path %s\n", __FUNCTION__,hr->path);
write_https_logon_page(s);
s->as_ok = 1;
free_http_request(hr);
@ -1400,6 +1417,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) {
}
} else {
write_https_logon_page(s);
s->as_ok = 1;
}
}
@ -1416,7 +1434,7 @@ static void https_input_handler(ioa_socket_handle s, int event_type, ioa_net_dat
data->nbh = NULL;
}
void https_cli_server_receive_message(struct bufferevent *bev, void *ptr)
void https_admin_server_receive_message(struct bufferevent *bev, void *ptr)
{
UNUSED_ARG(ptr);

@ -89,7 +89,7 @@ extern int cli_max_output_sessions;
void setup_cli_thread(void);
void cli_server_receive_message(struct bufferevent *bev, void *ptr);
void https_cli_server_receive_message(struct bufferevent *bev, void *ptr);
void https_admin_server_receive_message(struct bufferevent *bev, void *ptr);
int send_turn_session_info(struct turn_session_info* tsi);
void send_https_socket(ioa_socket_handle s);

@ -611,17 +611,22 @@ int stun_is_channel_message_str(const u08bits *buf, size_t *blen, u16bits* chnum
////////// STUN message ///////////////////////////////
static inline int sheadof(const char *head, const char* full)
static inline int sheadof(const char *head, const char* full, int ignore_case)
{
while(*head) {
if(*head != *full)
return 0;
if(*head != *full) {
if(ignore_case && (tolower(*head)==tolower(*full))) {
//OK
} else {
return 0;
}
}
++head;++full;
}
return 1;
}
static inline const char* findstr(const char *hay, size_t slen, const char *needle)
static inline const char* findstr(const char *hay, size_t slen, const char *needle, int ignore_case)
{
const char *ret = NULL;
@ -632,7 +637,7 @@ static inline const char* findstr(const char *hay, size_t slen, const char *need
size_t i;
const char *sp = hay;
for(i=0;i<smax;++i) {
if(sheadof(needle,sp+i)) {
if(sheadof(needle,sp+i,ignore_case)) {
ret = sp+i;
break;
}
@ -643,28 +648,36 @@ static inline const char* findstr(const char *hay, size_t slen, const char *need
return ret;
}
static inline int is_http_get_inline(const char *s, size_t blen) {
static inline int is_http_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/");
if((strstr(s,"GET ")==s) ||(strstr(s,"POST ")==s) || (strstr(s,"DELETE ")==s) || (strstr(s,"PUT ")==s)) {
const char *sp=findstr(s+4,blen-4," HTTP/",0);
if(sp) {
sp += 6;
size_t diff_blen = sp-s;
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",0);
if(sp) {
return (int)(sp-s+4);
int ret_len = (int)(sp-s+4);
const char* clheader = "content-length: ";
const char* cl = findstr(s,sp-s,clheader,1);
if(cl) {
unsigned long clen = strtoul(cl+strlen(clheader),NULL,10);
if(clen>0 && clen<(0x0FFFFFFF)) {
ret_len += (int)clen;
}
}
return ret_len;
}
}
}
}
}
return 0;
}
int is_http_get(const char *s, size_t blen) {
return is_http_get_inline(s, blen);
int is_http(const char *s, size_t blen) {
return is_http_inline(s, blen);
}
int stun_get_message_len_str(u08bits *buf, size_t blen, int padding, size_t *app_len) {
@ -690,7 +703,7 @@ int stun_get_message_len_str(u08bits *buf, size_t blen, int padding, size_t *app
//HTTP request ?
{
int http_len = is_http_get_inline(((char*)buf), blen);
int http_len = is_http_inline(((char*)buf), blen);
if((http_len>0) && ((size_t)http_len<=blen)) {
*app_len = (size_t)http_len;
return http_len;

@ -207,7 +207,7 @@ int stun_attr_get_padding_len_str(stun_attr_ref attr);
int stun_attr_add_padding_str(u08bits *buf, size_t *len, u16bits padding_len);
/* HTTP */
int is_http_get(const char *s, size_t blen);
int is_http(const char *s, size_t blen);
/* OAUTH */
int convert_oauth_key_data(const oauth_key_data *oakd, oauth_key *key, char *err_msg, size_t err_msg_size);

@ -4538,7 +4538,7 @@ static int read_client_connection(turn_turnserver *server,
} else {
SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket);
if((st == TCP_SOCKET)||(st==TLS_SOCKET)||(st==TENTATIVE_TCP_SOCKET)) {
if(is_http_get((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
const char *proto = "HTTP";
if(st==TLS_SOCKET) {
proto = "HTTPS";

Loading…
Cancel
Save