2010-11-08 20:20:42 +00:00
|
|
|
/*
|
|
|
|
* libwebsockets - small server side websockets and web server implementation
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2013-01-18 11:43:21 +08:00
|
|
|
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
|
2010-11-08 20:20:42 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation:
|
|
|
|
* version 2.1 of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
* MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "private-libwebsockets.h"
|
|
|
|
|
2011-01-18 15:39:02 +00:00
|
|
|
/*
|
|
|
|
* -04 of the protocol (actually the 80th version) has a radically different
|
|
|
|
* handshake. The 04 spec gives the following idea
|
|
|
|
*
|
|
|
|
* The handshake from the client looks as follows:
|
|
|
|
*
|
|
|
|
* GET /chat HTTP/1.1
|
|
|
|
* Host: server.example.com
|
|
|
|
* Upgrade: websocket
|
|
|
|
* Connection: Upgrade
|
|
|
|
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
|
|
|
* Sec-WebSocket-Origin: http://example.com
|
|
|
|
* Sec-WebSocket-Protocol: chat, superchat
|
2011-01-18 17:14:03 +00:00
|
|
|
* Sec-WebSocket-Version: 4
|
2011-01-18 15:39:02 +00:00
|
|
|
*
|
|
|
|
* The handshake from the server looks as follows:
|
|
|
|
*
|
|
|
|
* HTTP/1.1 101 Switching Protocols
|
|
|
|
* Upgrade: websocket
|
|
|
|
* Connection: Upgrade
|
|
|
|
* Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
|
|
|
|
* Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
|
|
|
|
* Sec-WebSocket-Protocol: chat
|
|
|
|
*/
|
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
/*
|
|
|
|
* We have to take care about parsing because the headers may be split
|
|
|
|
* into multiple fragments. They may contain unknown headers with arbitrary
|
|
|
|
* argument lengths. So, we parse using a single-character at a time state
|
|
|
|
* machine that is completely independent of packet size.
|
|
|
|
*/
|
|
|
|
|
2013-02-06 15:26:58 +09:00
|
|
|
#ifndef LWS_NO_SERVER
|
|
|
|
extern int handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi);
|
|
|
|
#endif
|
|
|
|
|
2010-11-13 10:03:47 +00:00
|
|
|
int
|
2012-04-09 15:09:01 +08:00
|
|
|
libwebsocket_read(struct libwebsocket_context *context,
|
|
|
|
struct libwebsocket *wsi, unsigned char * buf, size_t len)
|
2010-11-08 20:20:42 +00:00
|
|
|
{
|
|
|
|
size_t n;
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
switch (wsi->state) {
|
2013-01-15 13:40:23 +08:00
|
|
|
case WSI_STATE_HTTP_ISSUING_FILE:
|
2010-11-08 20:20:42 +00:00
|
|
|
case WSI_STATE_HTTP:
|
|
|
|
wsi->state = WSI_STATE_HTTP_HEADERS;
|
2013-01-21 11:04:23 +08:00
|
|
|
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
|
|
|
|
wsi->u.hdr.lextable_pos = 0;
|
2010-11-08 20:20:42 +00:00
|
|
|
/* fallthru */
|
|
|
|
case WSI_STATE_HTTP_HEADERS:
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_parser("issuing %d bytes to parser\n", (int)len);
|
2013-01-10 12:35:18 +08:00
|
|
|
#ifdef _DEBUG
|
2013-01-10 19:50:35 +08:00
|
|
|
//fwrite(buf, 1, len, stderr);
|
2010-11-08 20:20:42 +00:00
|
|
|
#endif
|
2011-01-22 12:51:57 +00:00
|
|
|
|
2013-01-16 11:47:40 +08:00
|
|
|
#ifndef LWS_NO_CLIENT
|
2013-01-16 14:35:12 +08:00
|
|
|
|
|
|
|
// lwsl_info("mode=%d\n", wsi->mode);
|
|
|
|
|
2011-02-09 07:16:34 +00:00
|
|
|
switch (wsi->mode) {
|
2011-05-23 10:00:03 +01:00
|
|
|
case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
|
|
|
|
case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
|
|
|
|
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
|
|
|
|
case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT:
|
2011-02-09 07:16:34 +00:00
|
|
|
case LWS_CONNMODE_WS_CLIENT:
|
2011-01-22 12:51:57 +00:00
|
|
|
for (n = 0; n < len; n++)
|
2013-02-04 08:55:42 +08:00
|
|
|
if (libwebsocket_client_rx_sm(wsi, *buf++)) {
|
|
|
|
lwsl_info("libwebsocket_client_rx_sm failed\n");
|
|
|
|
goto bail;
|
|
|
|
}
|
2011-01-22 12:51:57 +00:00
|
|
|
return 0;
|
2011-02-09 07:16:34 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-01-22 12:51:57 +00:00
|
|
|
}
|
2013-01-16 11:47:40 +08:00
|
|
|
#endif
|
2013-01-18 11:43:21 +08:00
|
|
|
#ifndef LWS_NO_SERVER
|
2011-02-09 07:16:34 +00:00
|
|
|
/* LWS_CONNMODE_WS_SERVING */
|
2011-01-22 12:51:57 +00:00
|
|
|
|
2010-11-13 10:03:47 +00:00
|
|
|
for (n = 0; n < len; n++)
|
2013-02-04 08:55:42 +08:00
|
|
|
if (libwebsocket_parse(wsi, *buf++)) {
|
|
|
|
lwsl_info("libwebsocket_parse failed\n");
|
|
|
|
goto bail;
|
|
|
|
}
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2013-01-21 11:04:23 +08:00
|
|
|
if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
|
2010-11-08 20:20:42 +00:00
|
|
|
break;
|
|
|
|
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_parser("libwebsocket_parse sees parsing complete\n");
|
2011-01-22 12:51:57 +00:00
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
/* is this websocket protocol or normal http 1.0? */
|
2010-11-13 10:03:47 +00:00
|
|
|
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) ||
|
|
|
|
!lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) {
|
2012-04-05 10:29:29 +08:00
|
|
|
wsi->state = WSI_STATE_HTTP;
|
2013-02-11 11:27:44 +08:00
|
|
|
n = 0;
|
2010-11-12 10:44:16 +00:00
|
|
|
if (wsi->protocol->callback)
|
2013-02-11 11:27:44 +08:00
|
|
|
n = wsi->protocol->callback(context, wsi,
|
2013-02-04 08:55:42 +08:00
|
|
|
LWS_CALLBACK_HTTP,
|
|
|
|
wsi->user_space,
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI),
|
2013-02-11 11:27:44 +08:00
|
|
|
lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI));
|
|
|
|
|
|
|
|
/* drop the header info */
|
|
|
|
if (wsi->u.hdr.ah)
|
|
|
|
free(wsi->u.hdr.ah);
|
|
|
|
|
|
|
|
if (n) {
|
|
|
|
lwsl_info("LWS_CALLBACK_HTTP wanted to close\n");
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-11-07 19:53:23 +08:00
|
|
|
if (!wsi->protocol)
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_err("NULL protocol at libwebsocket_read\n");
|
2011-05-23 10:00:03 +01:00
|
|
|
|
2011-01-18 17:14:03 +00:00
|
|
|
/*
|
|
|
|
* It's websocket
|
|
|
|
*
|
|
|
|
* Make sure user side is happy about protocol
|
|
|
|
*/
|
2010-11-11 12:28:29 +00:00
|
|
|
|
2010-11-12 10:44:16 +00:00
|
|
|
while (wsi->protocol->callback) {
|
|
|
|
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
if (!lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) {
|
2010-11-12 10:44:16 +00:00
|
|
|
if (wsi->protocol->name == NULL)
|
|
|
|
break;
|
|
|
|
} else
|
2012-04-03 17:22:19 +01:00
|
|
|
if (wsi->protocol->name && strcmp(
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL),
|
2010-11-12 10:44:16 +00:00
|
|
|
wsi->protocol->name) == 0)
|
|
|
|
break;
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2010-11-12 10:44:16 +00:00
|
|
|
wsi->protocol++;
|
|
|
|
}
|
2010-11-12 11:15:49 +00:00
|
|
|
|
|
|
|
/* we didn't find a protocol he wanted? */
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2010-11-12 10:44:16 +00:00
|
|
|
if (wsi->protocol->callback == NULL) {
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL) == NULL) {
|
2013-01-30 12:26:14 +08:00
|
|
|
lwsl_info("[no protocol] "
|
|
|
|
"mapped to protocol 0 handler\n");
|
|
|
|
wsi->protocol = &context->protocols[0];
|
|
|
|
} else {
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_err("Requested protocol %s "
|
2010-11-12 10:44:16 +00:00
|
|
|
"not supported\n",
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL));
|
2013-01-30 12:26:14 +08:00
|
|
|
goto bail;
|
|
|
|
}
|
2010-11-12 10:44:16 +00:00
|
|
|
}
|
|
|
|
|
2011-02-13 08:25:26 +00:00
|
|
|
/*
|
|
|
|
* Give the user code a chance to study the request and
|
|
|
|
* have the opportunity to deny it
|
|
|
|
*/
|
|
|
|
|
2011-02-14 09:14:25 +00:00
|
|
|
if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi,
|
2011-02-13 08:25:26 +00:00
|
|
|
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL),
|
|
|
|
NULL, 0)) {
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_warn("User code denied connection\n");
|
2011-02-13 08:25:26 +00:00
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-18 17:14:03 +00:00
|
|
|
/*
|
2011-01-19 12:20:27 +00:00
|
|
|
* Perform the handshake according to the protocol version the
|
|
|
|
* client announced
|
2011-01-18 17:14:03 +00:00
|
|
|
*/
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2011-01-18 17:14:03 +00:00
|
|
|
switch (wsi->ietf_spec_revision) {
|
2011-09-25 09:32:54 +01:00
|
|
|
case 13:
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_parser("libwebsocket_parse calling handshake_04\n");
|
2013-01-20 17:08:31 +08:00
|
|
|
if (handshake_0405(context, wsi)) {
|
|
|
|
lwsl_info("handshake_0405 xor 05 has failed the connection\n");
|
2011-01-18 17:14:03 +00:00
|
|
|
goto bail;
|
2013-01-20 17:08:31 +08:00
|
|
|
}
|
2011-01-18 17:14:03 +00:00
|
|
|
break;
|
2011-02-09 08:49:14 +00:00
|
|
|
|
2011-01-18 17:14:03 +00:00
|
|
|
default:
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_warn("Unknown client spec version %d\n",
|
2011-01-18 17:14:03 +00:00
|
|
|
wsi->ietf_spec_revision);
|
2010-11-08 20:20:42 +00:00
|
|
|
goto bail;
|
|
|
|
}
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2013-02-06 15:15:25 +09:00
|
|
|
/* drop the header info */
|
|
|
|
|
replace per header mallocs with single malloc 3 level struct
This big patch replaces the malloc / realloc per header
approach used until now with a single three-level struct
that gets malloc'd during the header union phase and freed
in one go when we transition to a different union phase.
It's more expensive in that we malloc a bit more than 4Kbytes,
but it's a lot cheaper in terms of malloc, frees, heap fragmentation,
no reallocs, nothing to configure. It also moves from arrays of
pointers (8 bytes on x86_64) to unsigned short offsets into the
data array, (2 bytes on all platforms).
The 3-level thing is all in one struct
- array indexed by the header enum, pointing to first "fragment" index
(ie, header type to fragment lookup, or 0 for none)
- array of fragments indexes, enough for 2 x the number of known headers
(fragment array... note that fragments can point to a "next"
fragment if the same header is spread across multiple entries)
- linear char array where the known header payload gets written
(fragments point into null-terminated strings stored in here,
only the known header content is stored)
http headers can legally be split over multiple headers of the same
name which should be concatenated. This scheme does not linearly
conatenate them but uses a linked list in the fragment structs to
link them. There are apis to get the total length and copy out a
linear, concatenated version to a buffer.
Signed-off-by: Andy Green <andy.green@linaro.org>
2013-02-10 18:02:31 +08:00
|
|
|
if (wsi->u.hdr.ah)
|
|
|
|
free(wsi->u.hdr.ah);
|
2013-02-06 15:15:25 +09:00
|
|
|
|
2013-01-15 13:40:23 +08:00
|
|
|
wsi->mode = LWS_CONNMODE_WS_SERVING;
|
|
|
|
|
2013-01-21 11:04:23 +08:00
|
|
|
/* union transition */
|
|
|
|
memset(&wsi->u, 0, sizeof wsi->u);
|
|
|
|
|
2013-02-06 21:10:16 +09:00
|
|
|
/*
|
|
|
|
* create the frame buffer for this connection according to the
|
|
|
|
* size mentioned in the protocol definition. If 0 there, use
|
|
|
|
* a big default for compatibility
|
|
|
|
*/
|
|
|
|
|
|
|
|
n = wsi->protocol->rx_buffer_size;
|
|
|
|
if (!n)
|
|
|
|
n = LWS_MAX_SOCKET_IO_BUF;
|
|
|
|
n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
|
|
|
|
wsi->u.ws.rx_user_buffer = malloc(n);
|
|
|
|
if (!wsi->u.ws.rx_user_buffer) {
|
|
|
|
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
|
2013-02-08 20:10:03 +08:00
|
|
|
goto bail;
|
2013-02-06 21:10:16 +09:00
|
|
|
}
|
2013-02-08 20:10:03 +08:00
|
|
|
lwsl_info("Allocating RX buffer %d\n", n);
|
2013-02-06 21:10:16 +09:00
|
|
|
|
2013-01-10 19:50:35 +08:00
|
|
|
lwsl_parser("accepted v%02d connection\n",
|
2011-02-09 08:49:14 +00:00
|
|
|
wsi->ietf_spec_revision);
|
2013-01-18 11:43:21 +08:00
|
|
|
#endif
|
2010-11-08 20:20:42 +00:00
|
|
|
break;
|
|
|
|
|
2011-03-07 07:08:12 +00:00
|
|
|
case WSI_STATE_AWAITING_CLOSE_ACK:
|
2010-11-08 20:20:42 +00:00
|
|
|
case WSI_STATE_ESTABLISHED:
|
2013-01-16 11:47:40 +08:00
|
|
|
#ifndef LWS_NO_CLIENT
|
2011-02-09 07:16:34 +00:00
|
|
|
switch (wsi->mode) {
|
|
|
|
case LWS_CONNMODE_WS_CLIENT:
|
2011-01-22 12:51:57 +00:00
|
|
|
for (n = 0; n < len; n++)
|
2013-01-20 17:08:31 +08:00
|
|
|
if (libwebsocket_client_rx_sm(wsi, *buf++) < 0) {
|
|
|
|
lwsl_info("client rx has bailed\n");
|
2011-05-24 22:07:45 +01:00
|
|
|
goto bail;
|
2013-01-20 17:08:31 +08:00
|
|
|
}
|
2011-01-22 12:51:57 +00:00
|
|
|
|
|
|
|
return 0;
|
2011-02-09 07:16:34 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-01-22 12:51:57 +00:00
|
|
|
}
|
2013-01-16 11:47:40 +08:00
|
|
|
#endif
|
2013-01-18 11:43:21 +08:00
|
|
|
#ifndef LWS_NO_SERVER
|
2011-02-09 07:16:34 +00:00
|
|
|
/* LWS_CONNMODE_WS_SERVING */
|
|
|
|
|
2013-01-20 17:08:31 +08:00
|
|
|
if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) {
|
|
|
|
lwsl_info("interpret_incoming_packet has bailed\n");
|
2010-11-08 20:20:42 +00:00
|
|
|
goto bail;
|
2013-01-20 17:08:31 +08:00
|
|
|
}
|
2013-01-18 11:43:21 +08:00
|
|
|
#endif
|
2010-11-08 20:20:42 +00:00
|
|
|
break;
|
|
|
|
default:
|
2013-01-15 13:40:23 +08:00
|
|
|
lwsl_err("libwebsocket_read: Unhandled state\n");
|
2010-11-08 20:20:42 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
return 0;
|
2010-11-13 10:03:47 +00:00
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
bail:
|
2013-01-20 17:08:31 +08:00
|
|
|
lwsl_info("closing connection at libwebsocket_read bail:\n");
|
2013-02-06 15:15:25 +09:00
|
|
|
|
2011-03-02 22:03:47 +00:00
|
|
|
libwebsocket_close_and_free_session(context, wsi,
|
2011-02-26 11:04:01 +00:00
|
|
|
LWS_CLOSE_STATUS_NOSTATUS);
|
2011-01-23 16:50:33 +00:00
|
|
|
|
2010-11-08 20:20:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|