}
pcgi = &(*pcgi)->cgi_list;
}
- if (wsi->cgi->headers_buf)
+ if (wsi->cgi->headers_buf) {
+ lwsl_debug("close: freed cgi headers\n");
lws_free_set_NULL(wsi->cgi->headers_buf);
+ }
/* we have a cgi going, we must kill it */
wsi->cgi->being_closed = 1;
lws_cgi_kill(wsi);
#endif
struct sockaddr_in serv_addr4;
#ifndef LWS_PLAT_OPTEE
- socklen_t len = sizeof(struct sockaddr);
+ socklen_t len = sizeof(struct sockaddr_storage);
#endif
int n;
- struct sockaddr_in sin;
+ struct sockaddr_storage sin;
struct sockaddr *v;
#ifdef LWS_USE_UNIX_SOCK
v = (struct sockaddr *)&serv_addr6;
n = sizeof(struct sockaddr_in6);
bzero((char *) &serv_addr6, sizeof(serv_addr6));
- if (iface &&
- interface_to_sa(vhost, iface,
- (struct sockaddr_in *)v, n) < 0) {
- lwsl_err("Unable to find interface %s\n", iface);
- return -1;
- }
-
if (iface) {
- struct ifaddrs *addrs, *addr;
- char ip[NI_MAXHOST];
- unsigned int i;
-
- getifaddrs(&addrs);
- for (addr = addrs; addr; addr = addr->ifa_next) {
- if (!addr->ifa_addr ||
- addr->ifa_addr->sa_family != AF_INET6)
- continue;
-
- getnameinfo(addr->ifa_addr,
- sizeof(struct sockaddr_in6),
- ip, sizeof(ip),
- NULL, 0, NI_NUMERICHOST);
-
- i = 0;
- while (ip[i])
- if (ip[i++] == '%') {
- ip[i - 1] = '\0';
- break;
- }
-
- if (!strcmp(ip, iface)) {
- serv_addr6.sin6_scope_id =
- if_nametoindex(addr->ifa_name);
- break;
- }
+ if (interface_to_sa(vhost, iface,
+ (struct sockaddr_in *)v, n) < 0) {
+ lwsl_err("Unable to find interface %s\n", iface);
+ return -1;
}
- freeifaddrs(addrs);
+ serv_addr6.sin6_scope_id = lws_get_addr_scope(iface);
}
serv_addr6.sin6_family = AF_INET6;
lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO));
else
#endif
- port = ntohs(sin.sin_port);
+#if defined(LWS_USE_IPV6)
+ port = (sin.ss_family == AF_INET6) ?
+ ntohs(((struct sockaddr_in6 *) &sin)->sin6_port) :
+ ntohs(((struct sockaddr_in *) &sin)->sin_port);
+#else
+ port = ntohs(((struct sockaddr_in *) &sin)->sin_port);
+#endif
#endif
return port;
}
+#if defined(LWS_USE_IPV6)
+LWS_EXTERN unsigned long
+lws_get_addr_scope(const char *ipaddr)
+{
+ unsigned long scope = 0;
+
+#ifndef WIN32
+ struct ifaddrs *addrs, *addr;
+ char ip[NI_MAXHOST];
+ unsigned int i;
+
+ getifaddrs(&addrs);
+ for (addr = addrs; addr; addr = addr->ifa_next) {
+ if (!addr->ifa_addr ||
+ addr->ifa_addr->sa_family != AF_INET6)
+ continue;
+
+ getnameinfo(addr->ifa_addr,
+ sizeof(struct sockaddr_in6),
+ ip, sizeof(ip),
+ NULL, 0, NI_NUMERICHOST);
+
+ i = 0;
+ while (ip[i])
+ if (ip[i++] == '%') {
+ ip[i - 1] = '\0';
+ break;
+ }
+
+ if (!strcmp(ip, ipaddr)) {
+ scope = if_nametoindex(addr->ifa_name);
+ break;
+ }
+ }
+ freeifaddrs(addrs);
+#else
+ PIP_ADAPTER_ADDRESSES adapter, addrs = NULL;
+ PIP_ADAPTER_UNICAST_ADDRESS addr;
+ ULONG size = 0;
+ DWORD ret;
+ struct sockaddr_in6 *sockaddr;
+ char ip[NI_MAXHOST];
+ unsigned int i;
+ int found = 0;
+
+ for (i = 0; i < 5; i++)
+ {
+ ret = GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX,
+ NULL, addrs, &size);
+ if ((ret == NO_ERROR) || (ret == ERROR_NO_DATA)) {
+ break;
+ } else if (ret == ERROR_BUFFER_OVERFLOW)
+ {
+ if (addrs)
+ free(addrs);
+ addrs = (IP_ADAPTER_ADDRESSES *) malloc(size);
+ } else
+ {
+ if (addrs)
+ {
+ free(addrs);
+ addrs = NULL;
+ }
+ lwsl_err("Failed to get IPv6 address table (%d)", ret);
+ break;
+ }
+ }
+
+ if ((ret == NO_ERROR) && (addrs))
+ {
+ adapter = addrs;
+ while ((adapter) && (!found))
+ {
+ addr = adapter->FirstUnicastAddress;
+ while ((addr) && (!found))
+ {
+ if (addr->Address.lpSockaddr->sa_family == AF_INET6)
+ {
+ sockaddr = (struct sockaddr_in6 *) (addr->Address.lpSockaddr);
+
+ lws_plat_inet_ntop(sockaddr->sin6_family, &sockaddr->sin6_addr,
+ ip, sizeof(ip));
+
+ if (!strcmp(ip, ipaddr)) {
+ scope = sockaddr->sin6_scope_id;
+ found = 1;
+ break;
+ }
+ }
+ addr = addr->Next;
+ }
+ adapter = adapter->Next;
+ }
+ }
+ if (addrs)
+ free(addrs);
+#endif
+
+ return scope;
+}
+#endif
+
LWS_EXTERN void
lws_restart_ws_ping_pong_timer(struct lws *wsi)
{
* process is OK. Stuff that happens after the execvpe() is OK.
*/
- for (n = 0; n < 3; n++)
+ for (n = 0; n < 3; n++) {
if (dup2(cgi->pipe_fds[n][!(n == 0)], n) < 0) {
lwsl_err("%s: stdin dup2 failed\n", __func__);
goto bail3;
}
+ close(cgi->pipe_fds[n][!(n == 0)]);
+ }
#if !defined(LWS_HAVE_VFORK) || !defined(LWS_HAVE_EXECVPE)
for (m = 0; m < n; m++) {
"content-length: ",
"location: ",
"status: ",
+ "transfer-encoding: chunked",
};
LWS_VISIBLE LWS_EXTERN int
if (n > 512)
n = 512;
+ lwsl_debug("LHCS_DUMP_HEADERS: %d\n", n);
+
m = lws_write(wsi, (unsigned char *)wsi->cgi->headers_dumped,
n, LWS_WRITE_HTTP_HEADERS);
if (m < 0) {
if (wsi->cgi->headers_dumped == wsi->cgi->headers_pos) {
wsi->hdr_state = LHCS_PAYLOAD;
lws_free_set_NULL(wsi->cgi->headers_buf);
+ lwsl_debug("freed cgi headers\n");
} else {
wsi->reason_bf |= 8;
lws_callback_on_writable(wsi);
lwsl_err("OOM\n");
return -1;
}
+
+ lwsl_debug("allocated cgi hdrs\n");
wsi->cgi->headers_pos = wsi->cgi->headers_buf;
wsi->cgi->headers_dumped = wsi->cgi->headers_pos;
wsi->cgi->headers_end = wsi->cgi->headers_buf + n - 1;
if (c == '\x0d')
wsi->hdr_state = LCHS_LF1;
+ if (wsi->hdr_state != LCHS_HEADER &&
+ !significant_hdr[SIGNIFICANT_HDR_TRANSFER_ENCODING][wsi->cgi->match[SIGNIFICANT_HDR_TRANSFER_ENCODING]]) {
+ lwsl_debug("cgi produced chunked\n");
+ wsi->cgi->explicitly_chunked = 1;
+ }
+
/* presence of Location: mandates 302 retcode */
if (wsi->hdr_state != LCHS_HEADER &&
!significant_hdr[SIGNIFICANT_HDR_LOCATION][wsi->cgi->match[SIGNIFICANT_HDR_LOCATION]]) {
lwsl_debug("%s: found PID %d on cgi list\n",
__func__, n);
- if (!cgi->content_length) {
+ if (!cgi->content_length && cgi->explicitly_chunked) {
/*
* well, if he sends chunked... give him 5s after the
* cgi terminated to send buffered