Add flags to sock_splice_chunked
This commit is contained in:
@ -439,7 +439,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
|
|||||||
if (content_len > 0) {
|
if (content_len > 0) {
|
||||||
ret = sock_splice(&proxy->proxy, client, buffer, sizeof(buffer), content_len);
|
ret = sock_splice(&proxy->proxy, client, buffer, sizeof(buffer), content_len);
|
||||||
} else if (strcontains(transfer_encoding, "chunked")) {
|
} else if (strcontains(transfer_encoding, "chunked")) {
|
||||||
ret = sock_splice_chunked(&proxy->proxy, client, buffer, sizeof(buffer));
|
ret = sock_splice_chunked(&proxy->proxy, client, buffer, sizeof(buffer), SOCK_CHUNKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0 || (content_len != 0 && ret != content_len)) {
|
if (ret < 0 || (content_len != 0 && ret != content_len)) {
|
||||||
|
@ -90,6 +90,11 @@ int sock_set_timeout(sock *s, double sec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long sock_send(sock *s, void *buf, unsigned long len, int flags) {
|
long sock_send(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
|
if (s->socket == 0) {
|
||||||
|
errno = ENOTCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
long ret;
|
long ret;
|
||||||
if (s->enc) {
|
if (s->enc) {
|
||||||
ret = SSL_write(s->ssl, buf, (int) len);
|
ret = SSL_write(s->ssl, buf, (int) len);
|
||||||
@ -121,6 +126,11 @@ long sock_send_x(sock *s, void *buf, unsigned long len, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
|
if (s->socket == 0) {
|
||||||
|
errno = ENOTCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
long ret;
|
long ret;
|
||||||
if (s->enc) {
|
if (s->enc) {
|
||||||
int (*func)(SSL*, void*, int) = (flags & MSG_PEEK) ? SSL_peek : SSL_read;
|
int (*func)(SSL*, void*, int) = (flags & MSG_PEEK) ? SSL_peek : SSL_read;
|
||||||
@ -140,7 +150,7 @@ long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
|||||||
|
|
||||||
long sock_recv_x(sock *s, void *buf, unsigned long len, int flags) {
|
long sock_recv_x(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
for (long ret, rcv = 0; rcv < len; rcv += ret) {
|
for (long ret, rcv = 0; rcv < len; rcv += ret) {
|
||||||
if ((ret = sock_recv(s, (unsigned char *) buf + rcv, len - rcv, flags)) <= 0) {
|
if ((ret = sock_recv(s, (unsigned char *) buf + rcv, len - rcv, flags | MSG_WAITALL)) <= 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
errno = 0, ret = 0;
|
errno = 0, ret = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -169,20 +179,37 @@ long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigne
|
|||||||
return (long) send_len;
|
return (long) send_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
long sock_splice_chunked(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) {
|
||||||
long ret;
|
long ret;
|
||||||
unsigned long send_len = 0;
|
unsigned long send_len = 0, next_len;
|
||||||
unsigned long next_len;
|
|
||||||
|
|
||||||
while (1) {
|
while (!(flags & SOCK_SINGLE_CHUNK)) {
|
||||||
ret = sock_get_chunk_header(src);
|
ret = sock_get_chunk_header(src);
|
||||||
if (ret < 0) return -2;
|
if (ret < 0) return -2;
|
||||||
|
|
||||||
next_len = ret;
|
next_len = ret;
|
||||||
if (next_len <= 0) break;
|
|
||||||
|
|
||||||
ret = sock_splice(dst, src, buf, buf_len, next_len);
|
if (flags & SOCK_CHUNKED) {
|
||||||
if (ret < 0) return ret;
|
ret = sprintf(buf, "%lX\r\n", next_len);
|
||||||
|
if (sock_send_x(dst, buf, ret, 0) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((ret = sock_splice(dst, src, buf, buf_len, next_len)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
send_len += ret;
|
||||||
|
|
||||||
|
if (flags & SOCK_CHUNKED) {
|
||||||
|
if (sock_send_x(dst, "\r\n", 2, 0) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock_recv_x(src, buf, 2, 0) == -1)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (long) send_len;
|
return (long) send_len;
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define SOCK_CHUNKED 1
|
||||||
|
#define SOCK_SINGLE_CHUNK 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int enc:1;
|
unsigned int enc:1;
|
||||||
int socket;
|
int socket;
|
||||||
@ -48,7 +51,7 @@ 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(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
|
||||||
|
|
||||||
long sock_splice_chunked(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);
|
int sock_close(sock *s);
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ typedef struct {
|
|||||||
char *filename; // "/account/index.php"
|
char *filename; // "/account/index.php"
|
||||||
char *uri; // "/account/login?username=test"
|
char *uri; // "/account/login?username=test"
|
||||||
metadata_t *meta;
|
metadata_t *meta;
|
||||||
unsigned int is_static:1;
|
unsigned int is_static:1, is_dir:1;
|
||||||
unsigned int is_dir:1;
|
|
||||||
} http_uri;
|
} http_uri;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user