Fixed binary chunk response in API.
This commit is contained in:
parent
cd922633b2
commit
495a92f5f8
2 changed files with 45 additions and 4 deletions
47
core/api.c
47
core/api.c
|
@ -326,6 +326,47 @@ struct HttpRequest* api_build_http_request(struct s_request* req) {
|
|||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write bytes into chunks.
|
||||
* @param socket, buffer array, length
|
||||
* @returns 1 when success or 0 if it fails.
|
||||
*/
|
||||
int api_send_resp_chunks(int fd, void *buf, size_t size)
|
||||
{
|
||||
char head[20];
|
||||
size_t s;
|
||||
int l;
|
||||
struct iovec iov[3];
|
||||
|
||||
// will be reused in each write, so defined only once.
|
||||
iov[2].iov_base = "\r\n";
|
||||
iov[2].iov_len = 2;
|
||||
|
||||
while (size > 0) {
|
||||
s = size > MAX_CHUNK ? MAX_CHUNK : size; // write only MAX_CHUNK at once
|
||||
l = snprintf(head, sizeof head, "%x\r\n", (unsigned int)s);
|
||||
if (l <= 0)
|
||||
return 0; // fail at snprintf
|
||||
|
||||
iov[0].iov_base = head;
|
||||
iov[0].iov_len = l; // head length.
|
||||
iov[1].iov_base = buf;
|
||||
iov[1].iov_len = s;
|
||||
|
||||
buf += s;
|
||||
size -= s;
|
||||
|
||||
if (size == 0) { // last chunk
|
||||
iov[2].iov_base = "\r\n0\r\n\r\n";
|
||||
iov[2].iov_len = 7;
|
||||
}
|
||||
libp2p_logger_error("api", "writing chunk block of %d bytes\n", s);
|
||||
if (writev(fd, iov, 3) == -1)
|
||||
return 0; // fail writing.
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pthread to take care of each client connection.
|
||||
* @param ptr an ApiConnectionParam
|
||||
|
@ -518,11 +559,9 @@ void *api_connection_thread (void *ptr)
|
|||
"Connection: close\r\n"
|
||||
"Transfer-Encoding: chunked\r\n"
|
||||
"\r\n"
|
||||
"%x\r\n"
|
||||
"%s\r\n"
|
||||
"0\r\n\r\n"
|
||||
,req.buf + req.http_ver, http_response->content_type, (unsigned int)http_response->bytes_size, http_response->bytes);
|
||||
,req.buf + req.http_ver, http_response->content_type);
|
||||
write_str (s, resp);
|
||||
api_send_resp_chunks(s, http_response->bytes, http_response->bytes_size);
|
||||
libp2p_logger_debug("api", "resp = {\n%s\n}\n", resp);
|
||||
}
|
||||
ipfs_core_http_request_free(http_request);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#endif
|
||||
|
||||
#define MAX_READ (32*1024) // 32k
|
||||
#define MAX_CHUNK (32*1024) // 32k
|
||||
|
||||
struct ApiContext {
|
||||
int socket;
|
||||
|
@ -86,6 +87,7 @@ struct s_request {
|
|||
#define cstrstart(a,b) (memcmp(a,b,sizeof(b)-1)==0)
|
||||
#define strstart(a,b) (memcmp(a,b,strlen(b))==0)
|
||||
|
||||
int api_send_resp_chunks(int fd, void *buf, size_t size);
|
||||
void *api_connection_thread (void *ptr);
|
||||
void api_connections_cleanup (struct IpfsNode* node);
|
||||
void *api_listen_thread (void *ptr);
|
||||
|
|
Loading…
Reference in a new issue