Review Board 1.7.16


WebSocket HTTP Module

Review Request #1952 - Created May 29, 2012 and submitted

Joshua Colp
websocket
Reviewers
asterisk-dev
Asterisk
This adds support for WebSocket protocols 7, 8, and 13. These are the most recent protocols. Sending and receiving text/binary frames is supported along with the various operation codes. An API is provided which makes it easy to implement different sub-protocols. Frame reconstruction is supported for situations where desirable (if multiple frames are received they will be reconstructed into a single one) but this can be disabled in situations where streaming is wanted.
Tested using Google Chrome Canary to confirm connection is established and data can be sent and received.

Tested using websocket.py to confirm connection is established and data can be sent and received.

Diff revision 2

This is not the most recent revision of the diff. The latest diff is revision 3. See what's changed.

1 2 3
1 2 3

  1. /include/asterisk/http_websocket.h: Loading...
  2. /include/asterisk/utils.h: Loading...
  3. /main/utils.c: Loading...
  4. /res/res_http_websocket.c: Loading...
  5. /res/res_http_websocket.exports.in: Loading...
/trunk/include/asterisk/http_websocket.h /include/asterisk/http_websocket.h
New File

    
   
1
/*

    
   
2
 * Asterisk -- An open source telephony toolkit.

    
   
3
 *

    
   
4
 * Copyright (C) 2012, Digium, Inc.

    
   
5
 *

    
   
6
 * Joshua Colp <jcolp@digium.com>

    
   
7
 *

    
   
8
 * See http://www.asterisk.org for more information about

    
   
9
 * the Asterisk project. Please do not directly contact

    
   
10
 * any of the maintainers of this project for assistance;

    
   
11
 * the project provides a web site, mailing lists and IRC

    
   
12
 * channels for your use.

    
   
13
 *

    
   
14
 * This program is free software, distributed under the terms of

    
   
15
 * the GNU General Public License Version 2. See the LICENSE file

    
   
16
 * at the top of the source tree.

    
   
17
 */

    
   
18

   

    
   
19
#ifndef _ASTERISK_HTTP_WEBSOCKET_H

    
   
20
#define _ASTERISK_HTTP_WEBSOCKET_H

    
   
21

   

    
   
22
#include "asterisk/module.h"

    
   
23

   

    
   
24
/*!

    
   
25
 * \file http_websocket.h

    
   
26
 * \brief Support for WebSocket connections within the Asterisk HTTP server.

    
   
27
 *

    
   
28
 * \author Joshua Colp <jcolp@digium.com>

    
   
29
 *

    
   
30
 */

    
   
31

   

    
   
32
/*! \brief WebSocket operation codes */

    
   
33
enum ast_websocket_opcode {

    
   
34
	AST_WEBSOCKET_OPCODE_TEXT = 0x1,         /*!< Text frame */

    
   
35
	AST_WEBSOCKET_OPCODE_BINARY = 0x2,       /*!< Binary frame */

    
   
36
	AST_WEBSOCKET_OPCODE_PING = 0x9,         /*!< Request that the other side respond with a pong */

    
   
37
	AST_WEBSOCKET_OPCODE_PONG = 0xA,         /*!< Response to a ping */

    
   
38
	AST_WEBSOCKET_OPCODE_CLOSE = 0x8,        /*!< Connection is being closed */

    
   
39
	AST_WEBSOCKET_OPCODE_CONTINUATION = 0x0, /*!< Continuation of a previous frame */

    
   
40
};

    
   
41

   

    
   
42
/*!

    
   
43
 * \brief Opaque structure for WebSocket sessions

    
   
44
 */

    
   
45
struct ast_websocket;

    
   
46

   

    
   
47
/*!

    
   
48
 * \brief Callback for when a new connection for a sub-protocol is established

    
   
49
 *

    
   
50
 * \param session A WebSocket session structure

    
   
51
 * \param parameters Parameters extracted from the request URI

    
   
52
 * \param headers Headers included in the request

    
   
53
 *

    
   
54
 * \note Once called the ownership of the session is transferred to the sub-protocol handler. It

    
   
55
 *       is responsible for closing and cleaning up.

    
   
56
 *

    
   
57
 */

    
   
58
typedef void (*ast_websocket_callback)(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers);

    
   
59

   

    
   
60
/*!

    
   
61
 * \brief Add a sub-protocol handler to the server

    
   
62
 *

    
   
63
 * \param name Name of the sub-protocol to register

    
   
64
 * \param callback Callback called when a new connection requesting the sub-protocol is established

    
   
65
 *

    
   
66
 * \retval 0 success

    
   
67
 * \retval -1 if sub-protocol handler could not be registered

    
   
68
 */

    
   
69
int ast_websocket_add_protocol(const char *name, ast_websocket_callback callback);

    
   
70

   

    
   
71
/*!

    
   
72
 * \brief Remove a sub-protocol handler from the server

    
   
73
 *

    
   
74
 * \param name Name of the sub-protocol to unregister

    
   
75
 * \param callback Callback that was previously registered with the sub-protocol

    
   
76
 *

    
   
77
 * \retval 0 success

    
   
78
 * \retval -1 if sub-protocol was not found or if callback did not match

    
   
79
 */

    
   
80
int ast_websocket_remove_protocol(const char *name, ast_websocket_callback callback);

    
   
81

   

    
   
82
/*!

    
   
83
 * \brief Read a WebSocket frame and handle it

    
   
84
 *

    
   
85
 * \param session Pointer to the WebSocket session

    
   
86
 * \param payload Pointer to a char* which will be populated with a pointer to the payload if present

    
   
87
 * \param payload_len Pointer to a uint64_t which will be populated with the length of the payload if present

    
   
88
 * \param opcode Pointer to an enum which will be populated with the opcode of the frame

    
   
89
 * \param fragmented Pointer to an int which is set to 1 if payload is fragmented and 0 if not

    
   
90
 *

    
   
91
 * \retval -1 on error

    
   
92
 * \retval 0 on success

    
   
93
 *

    
   
94
 * \note Once an AST_WEBSOCKET_OPCODE_CLOSE opcode is received the socket will be closed

    
   
95
 */

    
   
96
int ast_websocket_read(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented);

    
   
97

   

    
   
98
/*!

    
   
99
 * \brief Construct and transmit a WebSocket frame

    
   
100
 *

    
   
101
 * \param session Pointer to the WebSocket session

    
   
102
 * \param opcode WebSocket operation code to place in the frame

    
   
103
 * \param payload Optional pointer to a payload to add to the frame

    
   
104
 * \param actual_length Length of the payload (0 if no payload)

    
   
105
 *

    
   
106
 * \retval 0 if successfully written

    
   
107
 * \retval -1 if error occurred

    
   
108
 */

    
   
109
int ast_websocket_write(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length);

    
   
110

   

    
   
111
/*!

    
   
112
 * \brief Close a WebSocket session by sending a message with the CLOSE opcode and an optional code

    
   
113
 *

    
   
114
 * \param session Pointer to the WebSocket session

    
   
115
 * \param reason Reason code for closing the session as defined in the RFC

    
   
116
 *

    
   
117
 * \retval 0 if successfully written

    
   
118
 * \retval -1 if error occurred

    
   
119
 */

    
   
120
int ast_websocket_close(struct ast_websocket *session, uint16_t reason);

    
   
121

   

    
   
122
/*!

    
   
123
 * \brief Enable multi-frame reconstruction up to a certain number of bytes

    
   
124
 *

    
   
125
 * \param session Pointer to the WebSocket session

    
   
126
 * \param bytes If a reconstructed payload exceeds the specified number of bytes the payload will be returned

    
   
127
 *              and upon reception of the next multi-frame a new reconstructed payload will begin.

    
   
128
 */

    
   
129
void ast_websocket_reconstruct_enable(struct ast_websocket *session, size_t bytes);

    
   
130

   

    
   
131
/*!

    
   
132
 * \brief Disable multi-frame reconstruction

    
   
133
 *

    
   
134
 * \param session Pointer to the WebSocket session

    
   
135
 *

    
   
136
 * \note If reconstruction is disabled each message that is part of a multi-frame message will be sent up to

    
   
137
 *       the user when ast_websocket_read is called.

    
   
138
 */

    
   
139
void ast_websocket_reconstruct_disable(struct ast_websocket *session);

    
   
140

   

    
   
141
/*!

    
   
142
 * \brief Increase the reference count for a WebSocket session

    
   
143
 *

    
   
144
 * \param session Pointer to the WebSocket session

    
   
145
 */

    
   
146
void ast_websocket_ref(struct ast_websocket *session);

    
   
147

   

    
   
148
/*!

    
   
149
 * \brief Decrease the reference count for a WebSocket session

    
   
150
 *

    
   
151
 * \param session Pointer to the WebSocket session

    
   
152
 */

    
   
153
void ast_websocket_unref(struct ast_websocket *session);

    
   
154

   

    
   
155
/*!

    
   
156
 * \brief Get the file descriptor for a WebSocket session.

    
   
157
 *

    
   
158
 * \retval file descriptor

    
   
159
 *

    
   
160
 * \note You must *not* directly read from or write to this file descriptor. It should only be used for polling.

    
   
161
 */

    
   
162
int ast_websocket_fd(struct ast_websocket *session);

    
   
163

   

    
   
164
/*!

    
   
165
 * \brief Get the remote address for a WebSocket connected session.

    
   
166
 *

    
   
167
 * \retval ast_sockaddr Remote address

    
   
168
 */

    
   
169
struct ast_sockaddr *ast_websocket_remote_address(struct ast_websocket *session);

    
   
170

   

    
   
171
/*!

    
   
172
 * \brief Get whether the WebSocket session is using a secure transport or not.

    
   
173
 *

    
   
174
 * \retval 0 if unsecure

    
   
175
 * \retval 1 if secure

    
   
176
 */

    
   
177
int ast_websocket_is_secure(struct ast_websocket *session);

    
   
178

   

    
   
179
#endif /* _ASTERISK_HTTP_WEBSOCKET_H */
/trunk/include/asterisk/utils.h
Revision 360141 New Change
 
/trunk/main/utils.c
Revision 360141 New Change
 
/trunk/res/res_http_websocket.c
New File
 
/trunk/res/res_http_websocket.exports.in
New File
 
  1. /include/asterisk/http_websocket.h: Loading...
  2. /include/asterisk/utils.h: Loading...
  3. /main/utils.c: Loading...
  4. /res/res_http_websocket.c: Loading...
  5. /res/res_http_websocket.exports.in: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.