mirror of
https://github.com/lxsang/ant-http
synced 2024-12-26 00:38:21 +01:00
add websocket client to the library
This commit is contained in:
parent
4c9808da78
commit
4fb4674045
@ -56,6 +56,5 @@ make distcheck
|
|||||||
|
|
||||||
|
|
||||||
### To do
|
### To do
|
||||||
- variable size dictionary
|
- max upload file size should be configurable
|
||||||
- refactoring libantd API, remove unused functions
|
|
||||||
- remove static strings, replace it by configurations
|
- remove static strings, replace it by configurations
|
||||||
|
@ -17,6 +17,8 @@ maxcon=200
|
|||||||
backlog=5000
|
backlog=5000
|
||||||
; number of workers
|
; number of workers
|
||||||
workers = 4
|
workers = 4
|
||||||
|
; max upload file size in bytes
|
||||||
|
max_upload_size = 10000000
|
||||||
; if SSL is enable on one port, one should specify
|
; if SSL is enable on one port, one should specify
|
||||||
; the SSL cert and key files
|
; the SSL cert and key files
|
||||||
;Example: self signed key
|
;Example: self signed key
|
||||||
|
@ -142,6 +142,10 @@ static int config_handler(void *conf, const char *section, const char *name,
|
|||||||
{
|
{
|
||||||
pconfig->tmpdir = strdup(value);
|
pconfig->tmpdir = strdup(value);
|
||||||
}
|
}
|
||||||
|
else if (MATCH("SERVER", "max_upload_size"))
|
||||||
|
{
|
||||||
|
pconfig->max_upload_size = atoi(value);
|
||||||
|
}
|
||||||
else if (MATCH("SERVER", "maxcon"))
|
else if (MATCH("SERVER", "maxcon"))
|
||||||
{
|
{
|
||||||
pconfig->maxcon = atoi(value);
|
pconfig->maxcon = atoi(value);
|
||||||
@ -267,6 +271,7 @@ void load_config(const char *file)
|
|||||||
server_config.backlog = 1000;
|
server_config.backlog = 1000;
|
||||||
server_config.handlers = dict();
|
server_config.handlers = dict();
|
||||||
server_config.maxcon = 100;
|
server_config.maxcon = 100;
|
||||||
|
server_config.max_upload_size = 10000000; //10Mb
|
||||||
server_config.connection = 0;
|
server_config.connection = 0;
|
||||||
server_config.errorfp = NULL;
|
server_config.errorfp = NULL;
|
||||||
server_config.logfp = NULL;
|
server_config.logfp = NULL;
|
||||||
|
@ -78,6 +78,7 @@ typedef struct {
|
|||||||
int maxcon;
|
int maxcon;
|
||||||
int connection;
|
int connection;
|
||||||
int n_workers;
|
int n_workers;
|
||||||
|
int max_upload_size;
|
||||||
FILE* errorfp;
|
FILE* errorfp;
|
||||||
// #ifdef DEBUG
|
// #ifdef DEBUG
|
||||||
FILE* logfp;
|
FILE* logfp;
|
||||||
|
249
lib/ws.c
249
lib/ws.c
@ -1,3 +1,7 @@
|
|||||||
|
#ifdef USE_OPENSSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#endif
|
||||||
#include "ws.h"
|
#include "ws.h"
|
||||||
static void ws_gen_mask_key(ws_msg_header_t * header)
|
static void ws_gen_mask_key(ws_msg_header_t * header)
|
||||||
{
|
{
|
||||||
@ -69,13 +73,13 @@ ws_msg_header_t * ws_read_header(void* client)
|
|||||||
switch(header->opcode){
|
switch(header->opcode){
|
||||||
case WS_CLOSE: // client requests to close the connection
|
case WS_CLOSE: // client requests to close the connection
|
||||||
// send back a close message
|
// send back a close message
|
||||||
ws_close(client,1000);
|
ws_send_close(client,1000,header->mask?0:1);
|
||||||
//goto fail;
|
//goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_PING: // client send a ping
|
case WS_PING: // client send a ping
|
||||||
// send back a pong message
|
// send back a pong message
|
||||||
pong(client,header->plen);
|
ws_pong(client,header, header->mask?0:1 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
@ -208,7 +212,7 @@ void ws_send_file(void* client, const char* file, int mask)
|
|||||||
ptr = fopen(file,"rb");
|
ptr = fopen(file,"rb");
|
||||||
if(!ptr)
|
if(!ptr)
|
||||||
{
|
{
|
||||||
ws_close(client,1011);
|
ws_send_close(client,1011,mask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,18 +246,19 @@ void ws_send_file(void* client, const char* file, int mask)
|
|||||||
* Not tested yet
|
* Not tested yet
|
||||||
* but should work
|
* but should work
|
||||||
*/
|
*/
|
||||||
void pong(void* client, int len)
|
void ws_pong(void* client, ws_msg_header_t* oheader, int mask)
|
||||||
{
|
{
|
||||||
//printf("PONG\n");
|
|
||||||
ws_msg_header_t pheader;
|
ws_msg_header_t pheader;
|
||||||
pheader.fin = 1;
|
pheader.fin = 1;
|
||||||
pheader.opcode = WS_PONG;
|
pheader.opcode = WS_PONG;
|
||||||
pheader.plen = len;
|
pheader.plen = oheader->plen;
|
||||||
pheader.mask = 0;
|
pheader.mask = mask;
|
||||||
uint8_t *data = (uint8_t*)malloc(len);
|
uint8_t *data = (uint8_t*)malloc(oheader->plen);
|
||||||
if(!data) return;
|
if(!data) return;
|
||||||
if(antd_recv(client,data, len) < 0)
|
|
||||||
|
if(ws_read_data(client, oheader, pheader.plen,data) == -1)
|
||||||
{
|
{
|
||||||
|
ERROR("Cannot read ping data %d", pheader.plen);
|
||||||
free(data);
|
free(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -262,6 +267,15 @@ void pong(void* client, int len)
|
|||||||
//_send_header(client, pheader);
|
//_send_header(client, pheader);
|
||||||
//send(client, data, len, 0);
|
//send(client, data, len, 0);
|
||||||
}
|
}
|
||||||
|
void ws_ping(void* client, const char* echo, int mask)
|
||||||
|
{
|
||||||
|
ws_msg_header_t pheader;
|
||||||
|
pheader.fin = 1;
|
||||||
|
pheader.opcode = WS_PING;
|
||||||
|
pheader.plen = strlen(echo);
|
||||||
|
pheader.mask = mask;
|
||||||
|
ws_send_frame(client,(uint8_t*)echo,pheader);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Not tested yet, but should work
|
* Not tested yet, but should work
|
||||||
*/
|
*/
|
||||||
@ -295,7 +309,7 @@ int ip_from_hostname(const char * hostname , char* ip)
|
|||||||
if ( (he = gethostbyname( hostname ) ) == NULL)
|
if ( (he = gethostbyname( hostname ) ) == NULL)
|
||||||
{
|
{
|
||||||
// get the host info
|
// get the host info
|
||||||
herror("gethostbyname");
|
ERROR("gethostbyname:%s",strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addr_list = (struct in_addr **) he->h_addr_list;
|
addr_list = (struct in_addr **) he->h_addr_list;
|
||||||
@ -323,14 +337,14 @@ int request_socket(const char* ip, int port)
|
|||||||
timeout.tv_usec = 0;//3 s
|
timeout.tv_usec = 0;//3 s
|
||||||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
||||||
{
|
{
|
||||||
perror("Socket");
|
ERROR("Socket: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
||||||
perror("setsockopt failed\n");
|
ERROR("setsockopt failed:%s", strerror(errno));
|
||||||
|
|
||||||
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
||||||
perror("setsockopt failed\n");
|
ERROR("setsockopt failed:%s",strerror(errno));
|
||||||
/*struct linger lingerStruct;
|
/*struct linger lingerStruct;
|
||||||
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
||||||
@ -347,43 +361,192 @@ int request_socket(const char* ip, int port)
|
|||||||
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
|
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
|
||||||
{
|
{
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
perror("Connect");
|
ERROR("Connect:%s",strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: The ping request
|
void ws_client_close(ws_client_t* wsclient)
|
||||||
/*
|
{
|
||||||
this is for the client side, not use for now
|
int usessl = wsclient->antdsock->port_config->usessl;
|
||||||
int ws_open_hand_shake(const char* host, int port, const char* resource)
|
port_config_t *ptr = wsclient->antdsock->port_config;
|
||||||
|
antd_close(wsclient->antdsock);
|
||||||
|
if(ptr)
|
||||||
|
free(ptr);
|
||||||
|
|
||||||
|
#ifdef USE_OPENSSL
|
||||||
|
if(usessl)
|
||||||
|
{
|
||||||
|
if(wsclient->ssl_ctx)
|
||||||
|
SSL_CTX_free(wsclient->ssl_ctx);
|
||||||
|
FIPS_mode_set(0);
|
||||||
|
// DEPRECATED: CONF_modules_unload(1);
|
||||||
|
EVP_cleanup();
|
||||||
|
EVP_PBE_cleanup();
|
||||||
|
// DEPRECATED:ENGINE_cleanup();
|
||||||
|
CRYPTO_cleanup_all_ex_data();
|
||||||
|
// DEPRECATED: ERR_remove_state(0);
|
||||||
|
ERR_free_strings();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNUSED(usessl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is for the client side, not use for now
|
||||||
|
int ws_client_connect(ws_client_t* wsclient)
|
||||||
{
|
{
|
||||||
char ip[100];
|
char ip[100];
|
||||||
char buff[MAX_BUFF];
|
int stat = ip_from_hostname(wsclient->host,ip);
|
||||||
char* rq = NULL;
|
if(stat == -1)
|
||||||
int size;
|
return -1;
|
||||||
// request socket
|
int sock = request_socket(ip, wsclient->antdsock->port_config->port);
|
||||||
ip_from_hostname(host ,ip);
|
if(sock <= 0)
|
||||||
int sock = request_socket(ip, port);
|
|
||||||
if(sock <= 0) return -1;
|
|
||||||
// now send ws request handshake
|
|
||||||
rq = __s(CLIENT_RQ,resource,host);
|
|
||||||
// printf("%s\n",rq);
|
|
||||||
size = send(sock, rq, strlen(rq),0);
|
|
||||||
if(size != strlen(rq))
|
|
||||||
{
|
{
|
||||||
printf("Cannot send request \n");
|
ERROR("Cannot request socket");
|
||||||
close(sock);
|
return -1;
|
||||||
|
}
|
||||||
|
// will be free
|
||||||
|
wsclient->antdsock->ip = strdup(ip);
|
||||||
|
wsclient->antdsock->sock = sock;
|
||||||
|
wsclient->antdsock->status = 0;
|
||||||
|
wsclient->antdsock->last_io = time(NULL);
|
||||||
|
wsclient->antdsock->port_config->sock = -1;
|
||||||
|
wsclient->antdsock->port_config->rules = NULL;
|
||||||
|
wsclient->antdsock->port_config->htdocs = NULL;
|
||||||
|
#ifdef USE_OPENSSL
|
||||||
|
if(wsclient->antdsock->port_config->usessl)
|
||||||
|
{
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
ERR_load_crypto_strings();
|
||||||
|
OpenSSL_add_ssl_algorithms();
|
||||||
|
const SSL_METHOD *method;
|
||||||
|
unsigned long ssl_err = 0;
|
||||||
|
method = SSLv23_client_method();
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
if(!method)
|
||||||
|
{
|
||||||
|
ERROR("SSLv23_method: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
wsclient->ssl_ctx = SSL_CTX_new(method);
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
if (!wsclient->ssl_ctx) {
|
||||||
|
ERROR("SSL_CTX_new: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// configure the context
|
||||||
|
#if defined(SSL_CTX_set_ecdh_auto)
|
||||||
|
SSL_CTX_set_ecdh_auto(wsclient->ssl_ctx, 1);
|
||||||
|
#else
|
||||||
|
SSL_CTX_set_tmp_ecdh(wsclient->ssl_ctx, EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
|
||||||
|
#endif
|
||||||
|
SSL_CTX_set_options(wsclient->ssl_ctx, SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET);
|
||||||
|
// set the cipher suit
|
||||||
|
const char* suit = wsclient->ciphersuit?wsclient->ciphersuit:PREFERRED_WS_CIPHERS;
|
||||||
|
//const char* suit = "AES128-SHA";
|
||||||
|
if (SSL_CTX_set_cipher_list(wsclient->ssl_ctx, suit) != 1)
|
||||||
|
{
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
// TODO Close the context
|
||||||
|
ERROR("SSL_CTX_set_cipher_list: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wsclient->sslcert && wsclient->sslkey)
|
||||||
|
{
|
||||||
|
if (SSL_CTX_use_certificate_file(wsclient->ssl_ctx,wsclient->sslcert, SSL_FILETYPE_PEM) <= 0) {
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(wsclient->sslpasswd)
|
||||||
|
SSL_CTX_set_default_passwd_cb_userdata(wsclient->ssl_ctx,(void*)wsclient->sslpasswd);
|
||||||
|
if (SSL_CTX_use_PrivateKey_file(wsclient->ssl_ctx,wsclient->sslkey, SSL_FILETYPE_PEM) <= 0) {
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (SSL_CTX_check_private_key(wsclient->ssl_ctx) == 0) {
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
ERROR("SSL_CTX_check_private_key: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if(wsclient->verify_location)
|
||||||
|
{
|
||||||
|
SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
SSL_CTX_set_verify_depth(wsclient->ssl_ctx, 5);
|
||||||
|
if(!SSL_CTX_load_verify_locations(wsclient->ssl_ctx, wsclient->verify_location, NULL))
|
||||||
|
{
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
// TODO Close the context
|
||||||
|
ERROR("SSL_CTX_load_verify_locations: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
wsclient->antdsock->ssl = (void*)SSL_new(wsclient->ssl_ctx);
|
||||||
|
if(!wsclient->antdsock->ssl)
|
||||||
|
{
|
||||||
|
ssl_err = ERR_get_error();
|
||||||
|
ERROR("SSL_new: %s", ERR_error_string(ssl_err, NULL));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SSL_set_fd((SSL*)wsclient->antdsock->ssl, wsclient->antdsock->sock);
|
||||||
|
int stat, ret;
|
||||||
|
ERR_clear_error();
|
||||||
|
while( (ret = SSL_connect(wsclient->antdsock->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
stat = SSL_get_error(wsclient->antdsock->ssl, ret);
|
||||||
|
switch (stat)
|
||||||
|
{
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
case SSL_ERROR_NONE:
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
ERROR("Error performing SSL handshake %d", stat);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ws_open_handshake(ws_client_t* client)
|
||||||
|
{
|
||||||
|
char buf[MAX_BUFF];
|
||||||
|
// now send ws request handshake
|
||||||
|
sprintf(buf, CLIENT_RQ,client->resource,client->host);
|
||||||
|
//printf("Send %s\n", buf);
|
||||||
|
int size = antd_send(client->antdsock, buf, strlen(buf));
|
||||||
|
if(size != (int)strlen(buf))
|
||||||
|
{
|
||||||
|
ERROR("Cannot send request \n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// now verify if server accept the socket
|
// now verify if server accept the socket
|
||||||
size = read_buf(sock,buff,MAX_BUFF);
|
size = read_buf(client->antdsock,buf,MAX_BUFF);
|
||||||
char* token;
|
char* token;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
while (size > 0 && strcmp("\r\n",buff))
|
while (size > 0 && strcmp("\r\n",buf))
|
||||||
{
|
{
|
||||||
char* line = strdup(buff);
|
char* line = buf;
|
||||||
//printf("LINE %s\n", line);
|
|
||||||
token = strsep(&line,":");
|
token = strsep(&line,":");
|
||||||
trim(token,' ');
|
trim(token,' ');
|
||||||
if(token != NULL &&strcasecmp(token,"Sec-WebSocket-Accept") == 0)
|
if(token != NULL &&strcasecmp(token,"Sec-WebSocket-Accept") == 0)
|
||||||
@ -392,25 +555,23 @@ int ws_open_hand_shake(const char* host, int port, const char* resource)
|
|||||||
trim(token,' ');
|
trim(token,' ');
|
||||||
trim(token,'\n');
|
trim(token,'\n');
|
||||||
trim(token,'\r');
|
trim(token,'\r');
|
||||||
//printf("Key found %s \n", token);
|
|
||||||
if(strcasecmp(token, SERVER_WS_KEY) == 0)
|
if(strcasecmp(token, SERVER_WS_KEY) == 0)
|
||||||
{
|
{
|
||||||
// printf("Handshake sucessfull\n");
|
//LOG("Handshake sucessfull\n");
|
||||||
done = 1;
|
done = 1;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
printf("Wrong key %s vs %s\n",token,SERVER_WS_KEY);
|
ERROR("WS handshake, Wrong key %s vs %s",token,SERVER_WS_KEY);
|
||||||
close(sock);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if(line) free(line);
|
//if(line) free(line);
|
||||||
size = read_buf(sock,buff,MAX_BUFF);
|
size = read_buf(client->antdsock,buf,MAX_BUFF);
|
||||||
}
|
}
|
||||||
if(done) return sock;
|
if(done)
|
||||||
//printf("No server key found \n");
|
return 0;
|
||||||
return -1;
|
return -1;
|
||||||
}*/
|
}
|
||||||
char* get_ip_address()
|
char* get_ip_address()
|
||||||
{
|
{
|
||||||
struct ifaddrs* addrs;
|
struct ifaddrs* addrs;
|
||||||
|
31
lib/ws.h
31
lib/ws.h
@ -26,8 +26,10 @@
|
|||||||
#define ws_f(c,f) (ws_send_file(c,f,0))
|
#define ws_f(c,f) (ws_send_file(c,f,0))
|
||||||
#define ws_close(c,r) (ws_send_close(c,r,0))
|
#define ws_close(c,r) (ws_send_close(c,r,0))
|
||||||
#define MAX_BUFF 1024
|
#define MAX_BUFF 1024
|
||||||
//#define CLIENT_RQ "GET /%s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n"
|
|
||||||
//#define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
#define PREFERRED_WS_CIPHERS "HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS"
|
||||||
|
#define CLIENT_RQ "GET /%s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n"
|
||||||
|
#define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint8_t fin;
|
uint8_t fin;
|
||||||
@ -37,9 +39,25 @@ typedef struct{
|
|||||||
uint8_t mask_key[4];
|
uint8_t mask_key[4];
|
||||||
} ws_msg_header_t;
|
} ws_msg_header_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
const char* host;
|
||||||
|
const char* resource;
|
||||||
|
antd_client_t* antdsock;
|
||||||
|
// ssl
|
||||||
|
const char* sslcert;
|
||||||
|
const char* sslkey;
|
||||||
|
const char* sslpasswd;
|
||||||
|
const char* ciphersuit;
|
||||||
|
const char* verify_location;
|
||||||
|
void * ssl_ctx;
|
||||||
|
} ws_client_t;
|
||||||
|
|
||||||
|
|
||||||
ws_msg_header_t * ws_read_header(void*);
|
ws_msg_header_t * ws_read_header(void*);
|
||||||
void ws_send_frame(void* , uint8_t* , ws_msg_header_t );
|
void ws_send_frame(void* , uint8_t* , ws_msg_header_t );
|
||||||
void pong(void* client, int len);
|
void ws_pong(void* client, ws_msg_header_t*, int mask);
|
||||||
|
|
||||||
|
void ws_ping(void* client, const char* echo, int mask);
|
||||||
|
|
||||||
void ws_send_text(void* client, const char* data,int mask);
|
void ws_send_text(void* client, const char* data,int mask);
|
||||||
void ws_send_close(void* client, unsigned int status, int mask);
|
void ws_send_close(void* client, unsigned int status, int mask);
|
||||||
@ -49,7 +67,12 @@ void ws_send_binary(void* client, uint8_t* data, int l, int mask);
|
|||||||
int ws_read_data(void* , ws_msg_header_t*, int, uint8_t*);
|
int ws_read_data(void* , ws_msg_header_t*, int, uint8_t*);
|
||||||
int request_socket(const char* ip, int port);
|
int request_socket(const char* ip, int port);
|
||||||
int ip_from_hostname(const char * hostname , char* ip);
|
int ip_from_hostname(const char * hostname , char* ip);
|
||||||
int sock_read_buf(void* sock, char*buf,int size);
|
|
||||||
//int ws_open_hand_shake(const char* host, int port, const char* resource);
|
//int ws_open_hand_shake(const char* host, int port, const char* resource);
|
||||||
char* get_ip_address();
|
char* get_ip_address();
|
||||||
|
|
||||||
|
// client
|
||||||
|
|
||||||
|
void ws_client_close(ws_client_t* wsclient);
|
||||||
|
int ws_client_connect(ws_client_t* wsclient);
|
||||||
|
int ws_open_handshake(ws_client_t* client);
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user