From cb04af739c640dea72b15f9138f92494863d2820 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 2 Jul 2023 13:50:07 +0200 Subject: [PATCH] Fix nextcloud issues --- src/async.c | 2 +- src/lib/http.c | 8 ++++++++ src/lib/http.h | 2 ++ src/lib/proxy.c | 7 ++++--- src/lib/sock.c | 6 ++++-- src/lib/sock.h | 4 +++- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/async.c b/src/async.c index 9b4ea3c..83cafbb 100644 --- a/src/async.c +++ b/src/async.c @@ -108,7 +108,7 @@ static int async_exec(evt_listen_t *evt, async_evt_t r_events) { int ret, e = errno; if (r_events & evt->events) { // specified event(s) occurred - if (evt->socket && !sock_has_pending(evt->socket)) { + if (evt->socket && !sock_has_pending(evt->socket, 0)) { evt->err_cb(evt->arg); ret = 0; } else { diff --git a/src/lib/http.c b/src/lib/http.c index a5dd880..4220b9a 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -460,3 +460,11 @@ int http_get_compression(const http_req *req, const http_res *res) { } return 0; } + +long http_get_keep_alive_timeout(http_hdr *hdr) { + const char *keep_alive = http_get_header_field(hdr, "Keep-Alive"); + if (!keep_alive) return -1; + const char *timeout = strstr(keep_alive, "timeout="); + if (!timeout) return -1; + return strtol(timeout + 8, NULL, 10); +} diff --git a/src/lib/http.h b/src/lib/http.h index cd8bef2..5371a37 100644 --- a/src/lib/http.h +++ b/src/lib/http.h @@ -188,4 +188,6 @@ const http_doc_info *http_get_status_info(status_code_t status_code); int http_get_compression(const http_req *req, const http_res *res); +long http_get_keep_alive_timeout(http_hdr *hdr); + #endif //SESIMOS_HTTP_H diff --git a/src/lib/proxy.c b/src/lib/proxy.c index 62cac9f..d00d346 100644 --- a/src/lib/proxy.c +++ b/src/lib/proxy.c @@ -394,8 +394,8 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu while (retry) { errno = 0; - if (!proxy->initialized || sock_has_pending(&proxy->proxy) != 0 || srv_error || - (proxy->http_timeout != 0 && (clock_micros() - proxy->proxy.ts_last) > proxy->http_timeout)) + if (!proxy->initialized || sock_has_pending(&proxy->proxy, SOCK_DONTWAIT) != 0 || srv_error || + (proxy->http_timeout != 0 && (clock_micros() - proxy->proxy.ts_last) >= proxy->http_timeout)) { if (proxy->initialized) proxy_close(proxy); @@ -536,7 +536,8 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu } sock_recv_x(&proxy->proxy, buffer, header_len, 0); - // TODO read timeout from Keep-Alive + long keep_alive_timeout = http_get_keep_alive_timeout(&res->hdr); + proxy->http_timeout = (keep_alive_timeout > 0) ? keep_alive_timeout * 1000000 : 0; ret = proxy_response_header(req, res, conf); if (ret != 0) { diff --git a/src/lib/sock.c b/src/lib/sock.c index a1a988a..0174fd5 100644 --- a/src/lib/sock.c +++ b/src/lib/sock.c @@ -386,14 +386,16 @@ int sock_close(sock *s) { return 0; } -int sock_has_pending(sock *s) { +int sock_has_pending(sock *s, int flags) { int e = errno; long ret; if (s->pipe) { ioctl(s->socket, FIONREAD, &ret); + } else if (s->enc && (flags & SOCK_DONTWAIT)) { + ret = SSL_pending(s->ssl); } else { char buf[1]; - ret = sock_recv(s, &buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT); + ret = sock_recv(s, &buf, sizeof(buf), MSG_PEEK | ((flags & SOCK_DONTWAIT) ? MSG_DONTWAIT : 0)); } errno = e; return ret > 0; diff --git a/src/lib/sock.h b/src/lib/sock.h index 043e404..62efc8c 100644 --- a/src/lib/sock.h +++ b/src/lib/sock.h @@ -19,6 +19,8 @@ #define SOCK_ENCRYPTED 1 #define SOCK_PIPE 2 +#define SOCK_DONTWAIT 1 + typedef struct { unsigned int enc:1, pipe:1; int socket; @@ -68,7 +70,7 @@ long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, int sock_close(sock *s); -int sock_has_pending(sock *s); +int sock_has_pending(sock *s, int flags); long sock_recv_chunk_header(sock *s);