mirror of
https://github.com/payden/libwsclient
synced 2024-10-27 17:54:01 +00:00
Pthreads for opening connection
This commit is contained in:
parent
b670d894f3
commit
c24b62d0db
@ -2,4 +2,5 @@ lib_LTLIBRARIES=libwsclient.la
|
|||||||
libwsclient_la_SOURCES = wsclient.c base64.c sha1.c
|
libwsclient_la_SOURCES = wsclient.c base64.c sha1.c
|
||||||
library_includedir=$(includedir)/wsclient
|
library_includedir=$(includedir)/wsclient
|
||||||
library_include_HEADERS = wsclient.h
|
library_include_HEADERS = wsclient.h
|
||||||
|
AM_LDFLAGS = -lpthread
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
|
#undef HAVE_LIBPTHREAD
|
||||||
|
|
||||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||||
to 0 otherwise. */
|
to 0 otherwise. */
|
||||||
#undef HAVE_MALLOC
|
#undef HAVE_MALLOC
|
||||||
|
@ -23,6 +23,9 @@ AC_TYPE_SIZE_T
|
|||||||
AC_FUNC_MALLOC
|
AC_FUNC_MALLOC
|
||||||
AC_FUNC_REALLOC
|
AC_FUNC_REALLOC
|
||||||
AC_CHECK_FUNCS([memset socket strstr strchr])
|
AC_CHECK_FUNCS([memset socket strstr strchr])
|
||||||
|
AC_CHECK_LIB(pthread, pthread_create, [], [
|
||||||
|
echo "This library requires pthread"
|
||||||
|
exit -1
|
||||||
|
])
|
||||||
AC_CONFIG_FILES([Makefile])
|
AC_CONFIG_FILES([Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
5
test.c
5
test.c
@ -20,9 +20,8 @@ int main(int argc, char **argv) {
|
|||||||
fprintf(stderr, "Unable to initialize new WS client.\n");
|
fprintf(stderr, "Unable to initialize new WS client.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
client->onopen = &onopen;
|
libwsclient_onopen(client, &onopen);
|
||||||
client->onmessage = &onmessage;
|
libwsclient_onmessage(client, &onmessage);
|
||||||
libwsclient_send(client, "Testing");
|
|
||||||
libwsclient_run(client);
|
libwsclient_run(client);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
87
wsclient.c
87
wsclient.c
@ -17,6 +17,16 @@
|
|||||||
void libwsclient_run(wsclient *c) {
|
void libwsclient_run(wsclient *c) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int n, i;
|
int n, i;
|
||||||
|
pthread_mutex_lock(&c->lock);
|
||||||
|
if(c->flags & CLIENT_CONNECTING) {
|
||||||
|
pthread_mutex_unlock(&c->lock);
|
||||||
|
pthread_join(c->handshake_thread, NULL);
|
||||||
|
pthread_mutex_lock(&c->lock);
|
||||||
|
c->flags &= ~CLIENT_CONNECTING;
|
||||||
|
free(c->URI);
|
||||||
|
c->URI = NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&c->lock);
|
||||||
do {
|
do {
|
||||||
memset(buf, 0, 1024);
|
memset(buf, 0, 1024);
|
||||||
n = recv(c->sockfd, buf, 1023, 0);
|
n = recv(c->sockfd, buf, 1023, 0);
|
||||||
@ -31,6 +41,18 @@ void libwsclient_run(wsclient *c) {
|
|||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void libwsclient_onopen(wsclient *client, int (*cb)(void)) {
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
|
client->onopen = cb;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libwsclient_onmessage(wsclient *client, int (*cb)(libwsclient_message *msg)) {
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
|
client->onmessage = cb;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
}
|
||||||
|
|
||||||
void libwsclient_in_data(wsclient *c, char in) {
|
void libwsclient_in_data(wsclient *c, char in) {
|
||||||
libwsclient_frame *current = NULL, *new = NULL;
|
libwsclient_frame *current = NULL, *new = NULL;
|
||||||
unsigned char payload_len_short;
|
unsigned char payload_len_short;
|
||||||
@ -201,6 +223,38 @@ int libwsclient_open_connection(const char *host, const char *port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wsclient *libwsclient_new(const char *URI) {
|
wsclient *libwsclient_new(const char *URI) {
|
||||||
|
wsclient *client = NULL;
|
||||||
|
|
||||||
|
client = (wsclient *)malloc(sizeof(wsclient));
|
||||||
|
if(!client) {
|
||||||
|
fprintf(stderr, "Unable to allocate memory in libwsclient_new.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(client, 0, sizeof(wsclient));
|
||||||
|
if(pthread_mutex_init(&client->lock, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Unable to init mutex in libwsclient_new.\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
|
client->URI = (char *)malloc(strlen(URI)+1);
|
||||||
|
if(!client->URI) {
|
||||||
|
fprintf(stderr, "Unable to allocate memory in libwsclient_new.\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
memset(client->URI, 0, strlen(URI)+1);
|
||||||
|
strncpy(client->URI, URI, strlen(URI));
|
||||||
|
client->flags |= CLIENT_CONNECTING;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
|
||||||
|
if(pthread_create(&(client->handshake_thread), NULL, libwsclient_handshake_thread, (void *)client)) {
|
||||||
|
perror("pthread");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
void *libwsclient_handshake_thread(void *ptr) {
|
||||||
|
wsclient *client = (wsclient *)ptr;
|
||||||
|
const char *URI = client->URI;
|
||||||
SHA1Context shactx;
|
SHA1Context shactx;
|
||||||
const char *UUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
const char *UUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
char pre_encode[256];
|
char pre_encode[256];
|
||||||
@ -217,12 +271,6 @@ wsclient *libwsclient_new(const char *URI) {
|
|||||||
char recv_buf[1024];
|
char recv_buf[1024];
|
||||||
char *URI_copy = NULL, *p = NULL, *rcv = NULL, *tok = NULL;
|
char *URI_copy = NULL, *p = NULL, *rcv = NULL, *tok = NULL;
|
||||||
int i, z, sockfd, n, flags = 0, headers_space = 1024;
|
int i, z, sockfd, n, flags = 0, headers_space = 1024;
|
||||||
wsclient *client = (wsclient *)malloc(sizeof(wsclient));
|
|
||||||
if(!client) {
|
|
||||||
fprintf(stderr, "Unable to allocate memory in libwsclient_new.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset(client, 0, sizeof(wsclient));
|
|
||||||
URI_copy = (char *)malloc(strlen(URI)+1);
|
URI_copy = (char *)malloc(strlen(URI)+1);
|
||||||
if(!URI_copy) {
|
if(!URI_copy) {
|
||||||
fprintf(stderr, "Unable to allocate memory in libwsclient_new.\n");
|
fprintf(stderr, "Unable to allocate memory in libwsclient_new.\n");
|
||||||
@ -254,11 +302,15 @@ wsclient *libwsclient_new(const char *URI) {
|
|||||||
strncpy(port, "80", 9);
|
strncpy(port, "80", 9);
|
||||||
} else {
|
} else {
|
||||||
strncpy(port, "443", 9);
|
strncpy(port, "443", 9);
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
client->flags |= CLIENT_IS_SSL;
|
client->flags |= CLIENT_IS_SSL;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
i++;
|
i++;
|
||||||
p = strchr(URI_copy+i, '/');
|
p = strchr(URI_copy+i, '/');
|
||||||
|
if(!p)
|
||||||
|
p = strchr(URI_copy+i, '\0');
|
||||||
strncpy(port, URI_copy+i, (p - (URI_copy+i)));
|
strncpy(port, URI_copy+i, (p - (URI_copy+i)));
|
||||||
port[p-(URI_copy+i)] = '\0';
|
port[p-(URI_copy+i)] = '\0';
|
||||||
i += p-(URI_copy+i);
|
i += p-(URI_copy+i);
|
||||||
@ -271,7 +323,9 @@ wsclient *libwsclient_new(const char *URI) {
|
|||||||
fprintf(stderr, "Error opening socket.\n");
|
fprintf(stderr, "Error opening socket.\n");
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
client->sockfd = sockfd;
|
client->sockfd = sockfd;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
|
||||||
//perform handshake
|
//perform handshake
|
||||||
//generate nonce
|
//generate nonce
|
||||||
@ -358,7 +412,13 @@ wsclient *libwsclient_new(const char *URI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return client;
|
pthread_mutex_lock(&client->lock);
|
||||||
|
client->flags &= ~CLIENT_CONNECTING;
|
||||||
|
if(client->onopen != NULL) {
|
||||||
|
client->onopen();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//somewhat hackish stricmp
|
//somewhat hackish stricmp
|
||||||
@ -375,11 +435,22 @@ int stricmp(const char *s1, const char *s2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int libwsclient_send(wsclient *client, char *strdata) {
|
int libwsclient_send(wsclient *client, char *strdata) {
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
|
if(client->flags & CLIENT_CONNECTING) {
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
|
pthread_join(client->handshake_thread, NULL);
|
||||||
|
pthread_mutex_lock(&client->lock);
|
||||||
|
client->flags &= ~CLIENT_CONNECTING;
|
||||||
|
free(client->URI);
|
||||||
|
client->URI = NULL;
|
||||||
|
}
|
||||||
|
int sockfd = client->sockfd;
|
||||||
|
pthread_mutex_unlock(&client->lock);
|
||||||
if(strdata == NULL) {
|
if(strdata == NULL) {
|
||||||
fprintf(stderr, "NULL pointer psased to libwsclient_send\n");
|
fprintf(stderr, "NULL pointer psased to libwsclient_send\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int sockfd = client->sockfd;
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
unsigned char mask[4];
|
unsigned char mask[4];
|
||||||
unsigned int mask_int;
|
unsigned int mask_int;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifndef WSCLIENT_H_
|
#ifndef WSCLIENT_H_
|
||||||
#define WSCLIENT_H_
|
#define WSCLIENT_H_
|
||||||
@ -6,6 +7,8 @@
|
|||||||
#define FRAME_CHUNK_LENGTH 1024
|
#define FRAME_CHUNK_LENGTH 1024
|
||||||
|
|
||||||
#define CLIENT_IS_SSL (1 << 0)
|
#define CLIENT_IS_SSL (1 << 0)
|
||||||
|
#define CLIENT_CONNECTING (1 << 1)
|
||||||
|
|
||||||
|
|
||||||
#define REQUEST_HAS_CONNECTION (1 << 0)
|
#define REQUEST_HAS_CONNECTION (1 << 0)
|
||||||
#define REQUEST_HAS_UPGRADE (1 << 1)
|
#define REQUEST_HAS_UPGRADE (1 << 1)
|
||||||
@ -33,6 +36,9 @@ typedef struct _libwsclient_message {
|
|||||||
} libwsclient_message;
|
} libwsclient_message;
|
||||||
|
|
||||||
typedef struct _wsclient {
|
typedef struct _wsclient {
|
||||||
|
pthread_t handshake_thread;
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
char *URI;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
int flags;
|
int flags;
|
||||||
int (*onopen)(void);
|
int (*onopen)(void);
|
||||||
@ -43,13 +49,14 @@ typedef struct _wsclient {
|
|||||||
|
|
||||||
} wsclient;
|
} wsclient;
|
||||||
|
|
||||||
|
|
||||||
//Function defs
|
//Function defs
|
||||||
|
|
||||||
wsclient *libwsclient_new(const char *URI);
|
wsclient *libwsclient_new(const char *URI);
|
||||||
int libwsclient_open_connection(const char *host, const char *port);
|
int libwsclient_open_connection(const char *host, const char *port);
|
||||||
int stricmp(const char *s1, const char *s2);
|
int stricmp(const char *s1, const char *s2);
|
||||||
void libwsclient_run(wsclient *c);
|
void libwsclient_run(wsclient *c);
|
||||||
void *libwsclient_run_thread(void *ptr);
|
void *libwsclient_handshake_thread(void *ptr);
|
||||||
void libwsclient_cleanup_frames(libwsclient_frame *first);
|
void libwsclient_cleanup_frames(libwsclient_frame *first);
|
||||||
void libwsclient_in_data(wsclient *c, char in);
|
void libwsclient_in_data(wsclient *c, char in);
|
||||||
int libwsclient_complete_frame(libwsclient_frame *frame);
|
int libwsclient_complete_frame(libwsclient_frame *frame);
|
||||||
|
Loading…
Reference in New Issue
Block a user