From d7d0a71d872d65af2332c2d6c5c08464c75c44ce Mon Sep 17 00:00:00 2001 From: Unbit Date: Mon, 11 Nov 2013 14:42:28 +0100 Subject: [PATCH] completed rpc 64bit network client --- core/cache.c | 4 ++-- core/io.c | 8 ++++++-- core/rpc.c | 27 ++++++++++++++++++++++++++- uwsgi.h | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/core/cache.c b/core/cache.c index ac00c621..186ad158 100644 --- a/core/cache.c +++ b/core/cache.c @@ -1432,7 +1432,7 @@ static int cache_magic_send_and_manage(int fd, struct uwsgi_buffer *ub, char *st // ok now wait for the response, using the same buffer of the request // NOTE: after using a uwsgi_buffer in that way we basically destroy (even if we can safely free it) size_t rlen = ub->pos; - if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, timeout)) return -1; + if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, timeout, NULL, NULL)) return -1; // try to fix the buffer to maintain size info ub->pos = rlen; @@ -1867,7 +1867,7 @@ void uwsgi_cache_sync_from_nodes(struct uwsgi_cache *uc) { } size_t rlen = ub->pos; - if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { + if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL, NULL)) { uwsgi_buffer_destroy(ub); uwsgi_log("[cache-sync] unable to read from the cache server\n"); close(fd); diff --git a/core/io.c b/core/io.c index 2b27ff51..1b06bc68 100644 --- a/core/io.c +++ b/core/io.c @@ -943,12 +943,12 @@ int uwsgi_read_whole_true_nb(int fd, char *buf, size_t remains, int timeout) { } /* - this is a pretty magic function used for read a full uwsgi response + this is a pretty magic function used for reading a full uwsgi response it is true non blocking, so you can use it in request plugins buffer is expected to be at least 4 bytes, rlen is a get/set value */ -int uwsgi_read_with_realloc(int fd, char **buffer, size_t *rlen, int timeout) { +int uwsgi_read_with_realloc(int fd, char **buffer, size_t *rlen, int timeout, uint8_t *modifier1, uint8_t *modifier2) { if (*rlen < 4) return -1; char *buf = *buffer; int ret; @@ -979,6 +979,10 @@ readok: struct uwsgi_header *uh = (struct uwsgi_header *) buf; uint16_t pktsize = uh->pktsize; + if (modifier1) + *modifier1 = uh->modifier1; + if (modifier2) + *modifier2 = uh->modifier2; if (pktsize > *rlen) { char *tmp_buf = realloc(buf, pktsize); diff --git a/core/rpc.c b/core/rpc.c index 6802a819..30a18482 100644 --- a/core/rpc.c +++ b/core/rpc.c @@ -85,6 +85,13 @@ uint64_t uwsgi_rpc(char *name, uint8_t argc, char *argv[], uint16_t argvs[], cha return ret; } +static void rpc_context_hook(char *key, uint16_t kl, char *value, uint16_t vl, void *data) { + size_t *r = (size_t *) data; + + if (!uwsgi_strncmp(key, kl, "CONTENT_LENGTH", 14)) { + *r = uwsgi_str_num(value, vl); + } +} char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t argvs[], uint64_t * len) { @@ -155,10 +162,28 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t // ok time to wait for the response in non blocking way size_t rlen = buffer_size+4; - if (uwsgi_read_with_realloc(fd, &buffer, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { + uint8_t modifier2 = 0; + if (uwsgi_read_with_realloc(fd, &buffer, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL, &modifier2)) { goto error; } + // 64bit response ? + if (modifier2 == 5) { + size_t content_len = 0; + if (uwsgi_hooked_parse(buffer, rlen, rpc_context_hook, &content_len )) goto error; + + if (content_len > rlen) { + char *tmp_buf = realloc(buffer, content_len); + if (!tmp_buf) goto error; + buffer = tmp_buf; + } + + // read the raw value from the socket + if (uwsgi_read_whole_true_nb(fd, buffer, content_len, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { + goto error; + } + } + close(fd); *len = rlen; if (*len == 0) { diff --git a/uwsgi.h b/uwsgi.h index dca0494a..60036dea 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -3281,7 +3281,7 @@ int uwsgi_read_whole_true_nb(int, char *, size_t, int); int uwsgi_read_uh(int fd, struct uwsgi_header *, int); int uwsgi_proxy_nb(struct wsgi_request *, char *, struct uwsgi_buffer *, size_t, int); -int uwsgi_read_with_realloc(int, char **, size_t *, int); +int uwsgi_read_with_realloc(int, char **, size_t *, int, uint8_t *, uint8_t *); int uwsgi_write_true_nb(int, char *, size_t, int); void uwsgi_destroy_request(struct wsgi_request *);