mirror of
				https://github.com/lxsang/ant-http
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	support websocket frame fragments (binary data)
This commit is contained in:
		
							
								
								
									
										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.."); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user