mirror of
https://github.com/lxsang/ant-http
synced 2024-12-26 16:58:22 +01:00
support websocket frame fragments (binary data)
This commit is contained in:
parent
a720d8ff9c
commit
6d32fdfc3d
2
Makefile
2
Makefile
@ -20,7 +20,7 @@ ifeq ($(UNAME_S),Darwin)
|
|||||||
endif
|
endif
|
||||||
CFLAGS=-W -Wall -g -std=c99 -D DEBUG -D USE_DB $(PF_FLAG)
|
CFLAGS=-W -Wall -g -std=c99 -D DEBUG -D USE_DB $(PF_FLAG)
|
||||||
#-lsocket
|
#-lsocket
|
||||||
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT) nodedaemon.$(EXT) cookiex.$(EXT)
|
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT) nodedaemon.$(EXT) cookiex.$(EXT) wsimg.$(EXT)
|
||||||
|
|
||||||
PLUGINSDEP = plugins/ini.o \
|
PLUGINSDEP = plugins/ini.o \
|
||||||
plugins/plugin.o \
|
plugins/plugin.o \
|
||||||
|
@ -35,6 +35,7 @@ int request_socket(const char* ip, int port)
|
|||||||
perror("Socket");
|
perror("Socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,sizeof(timeout)) < 0)
|
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,sizeof(timeout)) < 0)
|
||||||
perror("setsockopt failed\n");
|
perror("setsockopt failed\n");
|
||||||
|
|
||||||
|
67
plugins/ws.c
67
plugins/ws.c
@ -102,6 +102,7 @@ void _send_header(int client, ws_msg_header_t header)
|
|||||||
for(int i=0; i< 8; i++) bytes[i] = 0;
|
for(int i=0; i< 8; i++) bytes[i] = 0;
|
||||||
//first byte |FIN|000|opcode|
|
//first byte |FIN|000|opcode|
|
||||||
byte = (header.fin << 7) + header.opcode;
|
byte = (header.fin << 7) + header.opcode;
|
||||||
|
//printf("BYTE: %d\n", byte);
|
||||||
send(client, &byte, 1, 0);
|
send(client, &byte, 1, 0);
|
||||||
// second byte, payload length
|
// second byte, payload length
|
||||||
// mask = 0
|
// mask = 0
|
||||||
@ -130,6 +131,17 @@ void _send_header(int client, ws_msg_header_t header)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
* Send a frame to client
|
||||||
|
*/
|
||||||
|
void ws_send_frame(int client, uint8_t* data, ws_msg_header_t header)
|
||||||
|
{
|
||||||
|
_send_header(client, header);
|
||||||
|
if(header.opcode == WS_TEXT)
|
||||||
|
send(client,(char*)data,header.plen,0);
|
||||||
|
else
|
||||||
|
send(client,(uint8_t*)data,header.plen,0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
* send a text data frame to client
|
* send a text data frame to client
|
||||||
*/
|
*/
|
||||||
void ws_t(int client, const char* data)
|
void ws_t(int client, const char* data)
|
||||||
@ -138,11 +150,12 @@ void ws_t(int client, const char* data)
|
|||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
header.opcode = WS_TEXT;
|
header.opcode = WS_TEXT;
|
||||||
header.plen = strlen(data);
|
header.plen = strlen(data);
|
||||||
_send_header(client,header);
|
//_send_header(client,header);
|
||||||
send(client, data, header.plen,0);
|
//send(client, data, header.plen,0);
|
||||||
|
ws_send_frame(client,data,header);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* send a binary data fram to client
|
* send a single binary data fram to client
|
||||||
* not tested yet, but should work
|
* not tested yet, but should work
|
||||||
*/
|
*/
|
||||||
void ws_b(int client, uint8_t* data, int l)
|
void ws_b(int client, uint8_t* data, int l)
|
||||||
@ -151,8 +164,50 @@ void ws_b(int client, uint8_t* data, int l)
|
|||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
header.opcode = WS_BIN;
|
header.opcode = WS_BIN;
|
||||||
header.plen = l;
|
header.plen = l;
|
||||||
_send_header(client,header);
|
ws_send_frame(client,data, header);
|
||||||
send(client, data, header.plen,0);
|
//_send_header(client,header);
|
||||||
|
//send(client, data, header.plen,0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* send a file as binary data
|
||||||
|
*/
|
||||||
|
void ws_f(int client, const char* file)
|
||||||
|
{
|
||||||
|
uint8_t buff[1024];
|
||||||
|
FILE *ptr;
|
||||||
|
ptr = fopen(file,"rb");
|
||||||
|
if(!ptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_msg_header_t header;
|
||||||
|
size_t size;
|
||||||
|
int first_frame = 1;
|
||||||
|
//ws_send_frame(client,buff,header);
|
||||||
|
while(!feof(ptr))
|
||||||
|
{
|
||||||
|
size = fread(buff,1,1024,ptr);
|
||||||
|
if(size >= 0)
|
||||||
|
{
|
||||||
|
if(feof(ptr))
|
||||||
|
header.fin = 1;
|
||||||
|
else
|
||||||
|
header.fin = 0;
|
||||||
|
// clear opcode
|
||||||
|
if(first_frame)
|
||||||
|
{
|
||||||
|
header.opcode = WS_BIN;
|
||||||
|
first_frame = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
header.opcode = 0;
|
||||||
|
header.plen = size;
|
||||||
|
//printf("FIN: %d OC:%d\n", header.fin, header.opcode);
|
||||||
|
ws_send_frame(client,buff,header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(ptr);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Not tested yet
|
* Not tested yet
|
||||||
@ -160,6 +215,7 @@ void ws_b(int client, uint8_t* data, int l)
|
|||||||
*/
|
*/
|
||||||
void pong(int client, int len)
|
void pong(int client, int len)
|
||||||
{
|
{
|
||||||
|
//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;
|
||||||
@ -174,6 +230,7 @@ void pong(int client, int len)
|
|||||||
*/
|
*/
|
||||||
void ws_close(int client, unsigned int status)
|
void ws_close(int client, unsigned int status)
|
||||||
{
|
{
|
||||||
|
//printf("CLOSED\n");
|
||||||
ws_msg_header_t header;
|
ws_msg_header_t header;
|
||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
header.opcode = WS_CLOSE;
|
header.opcode = WS_CLOSE;
|
||||||
|
@ -19,8 +19,10 @@ typedef struct{
|
|||||||
} ws_msg_header_t;
|
} ws_msg_header_t;
|
||||||
|
|
||||||
ws_msg_header_t * ws_read_header(int);
|
ws_msg_header_t * ws_read_header(int);
|
||||||
|
void ws_send_frame(int , uint8_t* , ws_msg_header_t );
|
||||||
void ws_t(int , const char* );
|
void ws_t(int , const char* );
|
||||||
void ws_b(int , uint8_t* data, int);
|
void ws_b(int , uint8_t* data, int);
|
||||||
|
void ws_f(int, const char*);
|
||||||
void ws_close(int, unsigned int);
|
void ws_close(int, unsigned int);
|
||||||
void pong(int client, int len);
|
void pong(int client, int len);
|
||||||
int ws_read_data(int , ws_msg_header_t*, int, uint8_t*);
|
int ws_read_data(int , ws_msg_header_t*, int, uint8_t*);
|
||||||
|
52
plugins/wsimg/wsimg.c
Normal file
52
plugins/wsimg/wsimg.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../plugin.h"
|
||||||
|
|
||||||
|
void pexit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void handler(int cl, const char* m, const char* rqp, dictionary rq)
|
||||||
|
{
|
||||||
|
char* path = NULL;
|
||||||
|
int nimg = 19;
|
||||||
|
ws_msg_header_t* h = NULL;
|
||||||
|
uint8_t buff[8];
|
||||||
|
if(ws_enable(rq))
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
h = ws_read_header(cl);
|
||||||
|
if(h)
|
||||||
|
{
|
||||||
|
if(h->opcode == WS_CLOSE)
|
||||||
|
{
|
||||||
|
LOG("%s\n","Websocket: connection closed");
|
||||||
|
ws_close(cl, 1011);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(h->opcode == WS_BIN)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
if((l = ws_read_data(cl,h,sizeof(buff),buff)) > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
path = __s("%s/ws/img%d.jpg",__plugin__.htdocs,buff[0]);
|
||||||
|
LOG("%s : %s\n", "send back data of", path);
|
||||||
|
ws_f(cl,path);
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG("%s\n","Invalid request");
|
||||||
|
ws_close(cl, 1011);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("%s\n", "EXIT Streaming..");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user