diff --git a/src/lib/sock.c b/src/lib/sock.c
index 4e58beb..2bd7417 100644
--- a/src/lib/sock.c
+++ b/src/lib/sock.c
@@ -182,11 +182,31 @@ long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigne
     return send_len;
 }
 
+long sock_splice_all(sock *dst, sock *src, void *buf, unsigned long buf_len) {
+    long send_len = 0;
+    for (long ret;; send_len += ret) {
+        if ((ret = sock_recv(src, buf, buf_len, 0)) <= 0) {
+            if (errno == EINTR) {
+                errno = 0, ret = 0;
+                continue;
+            } else if (ret == 0) {
+                break;
+            } else {
+                return -1;
+            }
+        }
+
+        if (sock_send_x(dst, buf, ret, 0) == -1)
+            return -1;
+    }
+    return send_len;
+}
+
 long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, int flags) {
     long ret;
     unsigned long send_len = 0, next_len;
 
-    while (!(flags & SOCK_SINGLE_CHUNK)) {
+    do {
         ret = sock_get_chunk_header(src);
         if (ret < 0) {
             errno = EPROTO;
@@ -200,9 +220,6 @@ long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len,
                 return -1;
         }
 
-        if (next_len == 0)
-            break;
-
         if ((ret = sock_splice(dst, src, buf, buf_len, next_len)) < 0)
             return ret;
 
@@ -219,7 +236,7 @@ long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len,
             errno = EPROTO;
             return -2;
         }
-    }
+    } while (!(flags & SOCK_SINGLE_CHUNK) && next_len != 0);
 
     return (long) send_len;
 }
@@ -263,7 +280,7 @@ long sock_parse_chunk_header(const char *buf, long len, long *ret_len) {
 }
 
 long sock_get_chunk_header(sock *s) {
-    long ret, len;
+    long ret, len = 0;
     char buf[16];
 
     do {
diff --git a/src/lib/sock.h b/src/lib/sock.h
index 8371b3d..4a273b3 100644
--- a/src/lib/sock.h
+++ b/src/lib/sock.h
@@ -51,6 +51,8 @@ long sock_recv_x(sock *s, void *buf, unsigned long len, int flags);
 
 long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
 
+long sock_splice_all(sock *dst, sock *src, void *buf, unsigned long buf_len);
+
 long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, int flags);
 
 int sock_close(sock *s);