*/
if (m) {
- fprintf(stderr, "extension vetoed close\n");
+ debug("extension vetoed close\n");
return;
}
}
if (old_state == WSI_STATE_ESTABLISHED &&
reason != LWS_CLOSE_STATUS_NOSTATUS) {
- fprintf(stderr, "sending close indication...\n");
+ debug("sending close indication...\n");
n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING],
0, LWS_WRITE_CLOSE);
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_CLOSE_ACK, 5);
- fprintf(stderr, "sent close indication, awaiting ack\n");
+ debug("sent close indication, awaiting ack\n");
return;
}
just_kill_connection:
- fprintf(stderr, "libwebsocket_close_and_free_session: just_kill_connection\n");
+ debug("libwebsocket_close_and_free_session: just_kill_connection\n");
/*
* we won't be servicing or receiving anything further from this guy
((old_state == WSI_STATE_ESTABLISHED) ||
(old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
(old_state == WSI_STATE_AWAITING_CLOSE_ACK))) {
- fprintf(stderr, "calling back CLOSED\n");
+ debug("calling back CLOSED\n");
wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
wsi->user_space, NULL, 0);
- } else {
- fprintf(stderr, "not calling back closed due to old_state=%d\n", old_state);
- }
+ } else
+ debug("not calling back closed due to old_state=%d\n",
+ old_state);
+
/* deallocate any active extension contexts */
/* no we could add more */
continue;
- fprintf(stderr, "choked in POLLOUT service\n");
+ debug("choked in POLLOUT service\n");
/*
* Yes, he's choked. Leave the POLLOUT masked on so we will
*/
if (sec > wsi->pending_timeout_limit) {
- fprintf(stderr, "TIMEDOUT WAITING\n");
+ debug("TIMEDOUT WAITING\n");
libwebsocket_close_and_free_session(context,
wsi, LWS_CLOSE_STATUS_NOSTATUS);
}
if (n) {
/* an extension vetos us */
- fprintf(stderr, "ext %s vetoed\n", (char *)ext->name);
+ debug("ext %s vetoed\n", (char *)ext->name);
ext++;
continue;
}
issue_hdr:
- puts(pkt);
+// puts(pkt);
/* done with these now */
char ext_name[128];
struct libwebsocket_extension *ext;
void *v;
- int len;
+ int len = 0;
int n;
static const char magic_websocket_04_masking_guid[] =
"61AC5F19-FBBA-4540-B96F-6561F1AB40A8";
!wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
(!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
wsi->c_protocol != NULL)) {
- fprintf(stderr, "libwebsocket_client_handshake "
+ debug("libwebsocket_client_handshake "
"missing required header(s)\n");
pkt[len] = '\0';
- fprintf(stderr, "%s", pkt);
+ debug("%s", pkt);
goto bail3;
}
strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
- if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
- "101 websocket protocol handshake")) {
+ if (strncmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
+ "101", 3)) {
fprintf(stderr, "libwebsocket_client_handshake "
"server sent bad HTTP response '%s'\n",
wsi->utf8_token[WSI_TOKEN_HTTP].token);
wsi->utf8_token[
WSI_TOKEN_CHALLENGE].token_len);
pkt[len] = '\0';
- fprintf(stderr, "%s", pkt);
+ debug("%s", pkt);
goto bail3;
}
wsi->ietf_spec_revision == 4) ||
(!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
wsi->c_protocol != NULL)) {
- fprintf(stderr, "libwebsocket_client_handshake "
+ debug("libwebsocket_client_handshake "
"missing required header(s)\n");
pkt[len] = '\0';
- fprintf(stderr, "%s", pkt);
+ debug("%s", pkt);
goto bail3;
}
*/
strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
- if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
- "101 switching protocols")) {
+ if (strncmp(wsi->utf8_token[WSI_TOKEN_HTTP].token, "101", 3)) {
fprintf(stderr, "libwebsocket_client_handshake "
"server sent bad HTTP response '%s'\n",
wsi->utf8_token[WSI_TOKEN_HTTP].token);
if (pc == NULL)
fprintf(stderr, "lws_client_interpret_server_handshake: NULL c_protocol\n");
else
- fprintf(stderr, "lws_client_interpret_server_handshake: cPprotocol='%s'\n", pc);
+ debug("lws_client_interpret_server_handshake: cPprotocol='%s'\n", pc);
/*
* confirm the protocol the server wants to talk was in the list
/* instantiate the accepted extensions */
if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len) {
- fprintf(stderr, "no client extenstions allowed by server \n");
+ debug("no client extenstions allowed by server \n");
goto check_accept;
}
/* check we actually support it */
- fprintf(stderr, "checking client ext %s\n", ext_name);
+ debug("checking client ext %s\n", ext_name);
n = 0;
ext = wsi->protocol->owning_server->extensions;
n = 1;
- fprintf(stderr, "instantiating client ext %s\n", ext_name);
+ debug("instantiating client ext %s\n", ext_name);
/* instantiate the extension on this conn */
accept_ok:
/* allocate the per-connection user memory (if any) */
-
- if (wsi->protocol->per_session_data_size) {
- wsi->user_space = malloc(
- wsi->protocol->per_session_data_size);
- if (wsi->user_space == NULL) {
- fprintf(stderr, "Out of memory for "
- "conn user space\n");
- goto bail2;
- }
- } else
- wsi->user_space = NULL;
+ if (wsi->protocol->per_session_data_size && !libwebsocket_ensure_user_space(wsi))
+ goto bail2;
/* clear his proxy connection timeout */
struct libwebsocket *new_wsi;
int n;
int m;
- size_t len;
+ ssize_t len;
int accept_fd;
unsigned int clilen;
struct sockaddr_in cli_addr;
int more = 1;
struct lws_tokens eff_buf;
int opt = 1;
+ char c;
#ifdef LWS_OPENSSL_SUPPORT
char ssl_err_buf[512];
if (!pollfd->revents & POLLIN)
break;
+ if (context->fds_count >= MAX_CLIENTS) {
+ fprintf(stderr, "too busy to accept new client\n");
+ break;
+ }
+
/* listen socket got an unencrypted connection... */
clilen = sizeof(cli_addr);
/* Disable Nagle */
opt = 1;
- setsockopt(accept_fd, IPPROTO_TCP, TCP_NODELAY, &opt,
+ setsockopt(accept_fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&opt,
sizeof(opt));
- if (context->fds_count >= MAX_CLIENTS) {
- fprintf(stderr, "too busy to accept new client\n");
-#ifdef WIN32
- closesocket(accept_fd);
-#else
- close(accept_fd);
-#endif
- break;
- }
-
/*
* look at who we connected to and give user code a chance
* to reject based on client IP. There's no protocol selected
if ((context->protocols[0].callback)(context, wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
(void*)(long)accept_fd, NULL, 0)) {
- fprintf(stderr, "Callback denied network connection\n");
+ debug("Callback denied network connection\n");
#ifdef WIN32
closesocket(accept_fd);
#else
* Sec-WebSocket-Protocol: chat
*/
- #ifdef LWS_OPENSSL_SUPPORT
- if (wsi->use_ssl)
- len = SSL_read(wsi->ssl, pkt, sizeof pkt);
- else
- #endif
- len = recv(wsi->sock, pkt, sizeof pkt, 0);
+ /*
+ * we have to take some care here to only take from the
+ * socket bytewise. The browser may (and has been seen to
+ * in the case that onopen() performs websocket traffic)
+ * coalesce both handshake response and websocket traffic
+ * in one packet, since at that point the connection is
+ * definitively ready from browser pov.
+ */
- if (len < 0) {
- fprintf(stderr,
- "libwebsocket_client_handshake read error\n");
- goto bail3;
- }
+ len = 1;
+ while (wsi->parser_state != WSI_PARSING_COMPLETE && len > 0) {
+#ifdef LWS_OPENSSL_SUPPORT
+ if (wsi->use_ssl)
+ len = SSL_read(wsi->ssl, &c, 1);
+ else
+#endif
+ len = recv(wsi->sock, &c, 1, 0);
- p = pkt;
- for (n = 0; n < len; n++)
- libwebsocket_parse(wsi, *p++);
+ libwebsocket_parse(wsi, c);
+ }
/*
- * may be coming in multiple packets, there is a 5-second
+ * hs may also be coming in multiple packets, there is a 5-second
* libwebsocket timeout still active here too, so if parsing did
* not complete just wait for next packet coming in this state
*/
if (wsi->parser_state != WSI_PARSING_COMPLETE)
break;
+ /*
+ * otherwise deal with the handshake. If there's any
+ * packet traffic already arrived we'll trigger poll() again
+ * right away and deal with it that way
+ */
+
return lws_client_interpret_server_handshake(context, wsi);
bail3:
if (eff_buf.token_len < 0) {
fprintf(stderr, "Socket read returned %d\n",
eff_buf.token_len);
- break;
+ if (errno != EINTR)
+ libwebsocket_close_and_free_session(context, wsi,
+ LWS_CLOSE_STATUS_NOSTATUS);
+ return 1;
}
if (!eff_buf.token_len) {
libwebsocket_close_and_free_session(context, wsi,
WORD wVersionRequested;
WSADATA wsaData;
int err;
+ HMODULE wsdll;
/* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
wVersionRequested = MAKEWORD(2, 2);
err);
return NULL;
}
+
+ wsdll = GetModuleHandle("Ws2_32.dll");
+ if (wsdll)
+ {
+ poll = (PFNWSAPOLL)GetProcAddress(wsdll, "WSAPoll");
+ }
+
+ if (!poll)
+ {
+ poll = emulated_poll;
+ }
}
#endif
}
/* allow us to restart even if old sockets in TIME_WAIT */
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
/* Disable Nagle */
opt = 1;
- setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+ setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const void *)&opt, sizeof(opt));
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
}
/* allow us to restart even if old sockets in TIME_WAIT */
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
{
return wsi->final;
}
+
+void *
+libwebsocket_ensure_user_space(struct libwebsocket *wsi)
+{
+ /* allocate the per-connection user memory (if any) */
+
+ if (wsi->protocol->per_session_data_size && !wsi->user_space) {
+ wsi->user_space = malloc(
+ wsi->protocol->per_session_data_size);
+ if (wsi->user_space == NULL) {
+ fprintf(stderr, "Out of memory for "
+ "conn user space\n");
+ return NULL;
+ }
+ memset(wsi->user_space, 0, wsi->protocol->per_session_data_size);
+ }
+ return wsi->user_space;
+}