1 #ifndef WEBSOCKET_H
2 #define WEBSOCKET_H
3 
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <event.h>
7 #include <hiredis/async.h>
8 
9 struct http_client;
10 struct cmd;
11 
12 enum ws_state {
13 	WS_ERROR,
14 	WS_READING,
15 	WS_MSG_COMPLETE};
16 
17 enum ws_frame_type {
18 	WS_TEXT_FRAME = 0,
19 	WS_BINARY_FRAME = 1,
20 	WS_CONNECTION_CLOSE = 8,
21 	WS_PING = 9,
22 	WS_PONG = 0xA,
23 	WS_UNKNOWN_FRAME = -1};
24 
25 struct ws_msg {
26 	enum ws_frame_type type;
27 	char *payload;
28 	size_t payload_sz;
29 	size_t total_sz;
30 };
31 
32 struct ws_client {
33 	struct http_client *http_client; /* parent */
34 	int scheduled_read; /* set if we are scheduled to read WS data */
35 	int scheduled_write; /* set if we are scheduled to send out WS data */
36 	struct evbuffer *rbuf; /* read buffer for incoming data */
37 	struct evbuffer *wbuf; /* write buffer for outgoing data */
38 	redisAsyncContext *ac; /* dedicated connection to redis */
39 	struct cmd *cmd; /* current command */
40 	/* indicates that we'll close once we've flushed all
41 	   buffered data and read what we planned to read */
42 	int close_after_events;
43 	int ran_subscribe; /* set if we've run a (p)subscribe command */
44 };
45 
46 struct ws_client *
47 ws_client_new(struct http_client *http_client);
48 
49 void
50 ws_client_free(struct ws_client *ws);
51 
52 int
53 ws_handshake_reply(struct ws_client *ws);
54 
55 int
56 ws_monitor_input(struct ws_client *ws);
57 
58 enum ws_state
59 ws_process_read_data(struct ws_client *ws, unsigned int *out_processed);
60 
61 int
62 ws_frame_and_send_response(struct ws_client *ws, enum ws_frame_type type, const char *p, size_t sz);
63 
64 #endif
65