/* any socket with events to service? */
for (n = 0; n < context->fds_count; n++) {
+#ifdef LWS_OPENSSL_SUPPORT
+ struct libwebsocket *wsi;
+
+ wsi = context->lws_lookup[context->fds[n].fd];
+ if (wsi == NULL)
+ continue;
+ /*
+ * if he's not flowcontrolled, make sure we service ssl
+ * pending read data
+ */
+ if (wsi->ssl && wsi->buffered_reads_pending) {
+ lwsl_debug("wsi %p: forcing POLLIN\n", wsi);
+ context->fds[n].revents |= context->fds[n].events & POLLIN;
+ }
+#endif
if (!context->fds[n].revents)
continue;
SSL *ssl;
BIO *client_bio;
unsigned int use_ssl:2;
+ unsigned int buffered_reads_pending:1;
#endif
#ifdef _WIN32
#define lws_context_init_server_ssl(_a, _b) (0)
#define lws_ssl_destroy(_a)
#define lws_context_init_http2_ssl(_a)
-#define lws_ssl_pending(_a) (0)
#define lws_ssl_capable_read lws_ssl_capable_read_no_ssl
#define lws_ssl_capable_write lws_ssl_capable_write_no_ssl
#define lws_server_socket_service_ssl(_a, _b, _c, _d, _e) (0)
#define lws_ssl_context_destroy(_a)
#else
#define LWS_SSL_ENABLED(context) (context->use_ssl)
-LWS_EXTERN int lws_ssl_pending(struct libwebsocket *wsi);
LWS_EXTERN int openssl_websocket_private_data_index;
LWS_EXTERN int
lws_ssl_capable_read(struct libwebsocket *wsi, unsigned char *buf, int len);
if (!(pollfd->revents & LWS_POLLIN))
break;
-read_pending:
eff_buf.token_len = lws_ssl_capable_read(wsi,
context->service_buffer,
sizeof(context->service_buffer));
n = _libwebsocket_rx_flow_control(wsi); /* n ignored, needed for NO_SERVER case */
}
- if (lws_ssl_pending(wsi))
- goto read_pending;
break;
default:
if (!wsi->ssl)
return lws_ssl_capable_read_no_ssl(wsi, buf, len);
+
+ wsi->buffered_reads_pending = 0;
n = SSL_read(wsi->ssl, buf, len);
- if (n >= 0)
+ if (n >= 0) {
+ /*
+ * if it was our buffer that limited what we read,
+ * check if SSL has additional data pending inside SSL buffers.
+ *
+ * Because these won't signal at the network layer with POLLIN
+ * and if we don't realize, this data will sit there forever
+ */
+ if (n == len && wsi->ssl && SSL_pending(wsi->ssl))
+ wsi->buffered_reads_pending = 1;
+
return n;
-
+ }
n = SSL_get_error(wsi->ssl, n);
if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE)
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
LWS_VISIBLE int
-lws_ssl_pending(struct libwebsocket *wsi)
-{
- if (wsi->ssl)
- return SSL_pending(wsi->ssl);
- return 0;
-}
-
-LWS_VISIBLE int
lws_ssl_close(struct libwebsocket *wsi)
{
int n;