if (spin == 5)
lwsl_err("symlink loop %s \n", path);
- n = sprintf(sym, "%08lX%08lX",
- (unsigned long)lws_vfs_get_length(wsi->u.http.fop_fd),
+ n = sprintf(sym, "%08llX%08lX",
+ (unsigned long long)lws_vfs_get_length(wsi->u.http.fop_fd),
(unsigned long)lws_vfs_get_mod_time(wsi->u.http.fop_fd));
/* disable ranges if IF_RANGE token invalid */
if (n > (int)strlen(pvo->name) &&
!strcmp(&path[n - strlen(pvo->name)], pvo->name)) {
wsi->sending_chunked = 1;
- wsi->protocol_interpret_idx = (char)(long)pvo->value;
+ wsi->protocol_interpret_idx = (char)(lws_intptr_t)pvo->value;
lwsl_info("want %s interpreted by %s\n", path,
- wsi->vhost->protocols[(int)(long)(pvo->value)].name);
- wsi->protocol = &wsi->vhost->protocols[(int)(long)(pvo->value)];
+ wsi->vhost->protocols[(int)(lws_intptr_t)(pvo->value)].name);
+ wsi->protocol = &wsi->vhost->protocols[(int)(lws_intptr_t)(pvo->value)];
if (lws_ensure_user_space(wsi))
return -1;
break;
int lws_clean_url(char *p)
{
+ if (p[0] == 'h' && p[1] == 't' && p[2] == 't' && p[3] == 'p') {
+ p += 4;
+ if (*p == 's')
+ p++;
+ if (*p == ':') {
+ p++;
+ if (*p == '/')
+ p++;
+ }
+ }
+
while (*p) {
if (p[0] == '/' && p[1] == '/') {
char *p1 = p;
/* we insist on absolute paths */
- if (uri_ptr[0] != '/') {
+ if (!uri_ptr || uri_ptr[0] != '/') {
lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
goto bail_nuke_ah;
if (!pa)
pa = "(unknown)";
- if (meth >= 0)
- me = method_names[meth];
- else
- me = "unknown";
+ me = method_names[meth];
lws_snprintf(wsi->access_log.header_log, l,
"%s - - [%s] \"%s %s %s\"",
hit->origin);
else
n = lws_snprintf((char *)end, 256,
- "%s%s%s/", oprot[lws_is_ssl(wsi)],
+ "%s%s%s/", oprot[!!lws_is_ssl(wsi)],
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST),
uri_ptr);
+
+ lwsl_notice("%s\n", end);
lws_clean_url((char *)end);
+ lwsl_notice("%s\n", end);
n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
end, n, &p, end);
#endif
}
+static int
+lws_server_init_wsi_for_ws(struct lws *wsi)
+{
+ int n;
+
+ wsi->state = LWSS_ESTABLISHED;
+ lws_restart_ws_ping_pong_timer(wsi);
+
+ /*
+ * 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 = wsi->context->pt_serv_buf_size;
+ n += LWS_PRE;
+ wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */);
+ if (!wsi->u.ws.rx_ubuf) {
+ lwsl_err("Out of Mem allocating rx buffer %d\n", n);
+ return 1;
+ }
+ wsi->u.ws.rx_ubuf_alloc = n;
+ lwsl_debug("Allocating RX buffer %d\n", n);
+
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
+ if (!wsi->parent_carries_io)
+ if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF,
+ (const char *)&n, sizeof n)) {
+ lwsl_warn("Failed to set SNDBUF to %d", n);
+ return 1;
+ }
+#endif
+
+ /* notify user code that we're ready to roll */
+
+ if (wsi->protocol->callback)
+ if (wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED,
+ wsi->user_space,
+#ifdef LWS_OPENSSL_SUPPORT
+ wsi->ssl,
+#else
+ NULL,
+#endif
+ 0))
+ return 1;
+
+ return 0;
+}
+
int
lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
{
wsi->u.hdr = hdr;
lws_pt_unlock(pt);
- lws_restart_ws_ping_pong_timer(wsi);
-
- /*
- * 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 = context->pt_serv_buf_size;
- n += LWS_PRE;
- wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */);
- if (!wsi->u.ws.rx_ubuf) {
- lwsl_err("Out of Mem allocating rx buffer %d\n", n);
- return 1;
- }
- wsi->u.ws.rx_ubuf_alloc = n;
- lwsl_debug("Allocating RX buffer %d\n", n);
-#if LWS_POSIX && !defined(LWS_WITH_ESP32)
- if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF,
- (const char *)&n, sizeof n)) {
- lwsl_warn("Failed to set SNDBUF to %d", n);
- return 1;
- }
-#endif
-
+ lws_server_init_wsi_for_ws(wsi);
lwsl_parser("accepted v%02d connection\n",
wsi->ietf_spec_revision);
- /* notify user code that we're ready to roll */
-
- if (wsi->protocol->callback)
- if (wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED,
- wsi->user_space,
-#ifdef LWS_OPENSSL_SUPPORT
- wsi->ssl,
-#else
- NULL,
-#endif
- 0))
- return 1;
-
/* !!! drop ah unreservedly after ESTABLISHED */
if (!wsi->more_rx_waiting) {
lws_header_table_force_to_detachable_state(wsi);
new_wsi->user_space = NULL;
new_wsi->ietf_spec_revision = 0;
new_wsi->desc.sockfd = LWS_SOCK_INVALID;
+ new_wsi->position_in_fds_table = -1;
+
vhost->context->count_wsi_allocated++;
/*
return 0;
}
- lwsl_notice("%s: wsi %p\n", __func__, wsi);
+ lwsl_debug("%s: wsi %p\n", __func__, wsi);
/* if we can't go back to accept new headers, drop the connection */
if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
lwsl_info("%s: %p: close connection\n", __func__, wsi);
int n, ssl = 0;
if (!new_wsi) {
- if (type & LWS_ADOPT_SOCKET)
+ if (type & LWS_ADOPT_SOCKET && !(type & LWS_ADOPT_WS_PARENTIO))
compatible_close(fd.sockfd);
return NULL;
}
new_wsi->parent = parent;
new_wsi->sibling_list = parent->child_list;
parent->child_list = new_wsi;
+
+ if (type & LWS_ADOPT_WS_PARENTIO)
+ new_wsi->parent_carries_io = 1;
}
new_wsi->desc = fd;
lwsl_notice("OOM trying to get user_space\n");
goto bail;
}
+ if (type & LWS_ADOPT_WS_PARENTIO) {
+ new_wsi->desc.sockfd = LWS_SOCK_INVALID;
+ lwsl_debug("binding to %s\n", new_wsi->protocol->name);
+ lws_bind_protocol(new_wsi, new_wsi->protocol);
+ lws_union_transition(new_wsi, LWSCM_WS_SERVING);
+ lws_server_init_wsi_for_ws(new_wsi);
+
+ return new_wsi;
+ }
} else
if (type & LWS_ADOPT_HTTP) /* he will transition later */
new_wsi->protocol =
if (type & LWS_ADOPT_SOCKET) { /* socket desc */
lwsl_debug("%s: new wsi %p, sockfd %d\n", __func__, new_wsi,
- (int)(size_t)fd.sockfd);
+ (int)(lws_intptr_t)fd.sockfd);
if (type & LWS_ADOPT_HTTP)
/* the transport is accepted...
#endif
} else /* file desc */
lwsl_debug("%s: new wsi %p, filefd %d\n", __func__, new_wsi,
- (int)(size_t)fd.filefd);
+ (int)(lws_intptr_t)fd.filefd);
/*
* A new connection was accepted. Give the user a chance to
goto fail;
if (type & LWS_ADOPT_HTTP) {
- if (!lws_header_table_attach(new_wsi, 0)) {
+ if (!lws_header_table_attach(new_wsi, 0))
lwsl_debug("Attached ah immediately\n");
- } else {
- lwsl_notice("%s: waiting for ah\n", __func__);
- }
+ else
+ lwsl_info("%s: waiting for ah\n", __func__);
}
return new_wsi;
ah->rxlen = ah->rxpos = 0;
goto try_pollout;
}
+
+ /*
+ * make sure ah does not get detached if we
+ * have live data in the rx
+ */
+ if (ah->rxlen)
+ wsi->more_rx_waiting = 1;
}
if (!(ah->rxpos != ah->rxlen && ah->rxlen)) {
break;
}
- /* >0 == completion, <0 == error */
+ /* >0 == completion, <0 == error
+ *
+ * We'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION callback when
+ * it's done. That's the case even if we just completed the
+ * send, so wait for that.
+ */
n = lws_serve_http_file_fragment(wsi);
- if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi))) {
- lwsl_info("completed\n");
+ if (n < 0)
goto fail;
- }
break;
*/
if ((wsi->vhost->protocols[0].callback)(wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
- NULL, (void *)(long)accept_fd, 0)) {
+ NULL, (void *)(lws_intptr_t)accept_fd, 0)) {
lwsl_debug("Callback denied network connection\n");
compatible_close(accept_fd);
break;