Handle the case where the entire body has been received before the connect
In this case, we're already using a header that says TE:chunked, so we
must also chunk the body, even if we have it completely.
@@ -429,6 +429,24 @@ static void swap_buffers(h2o_buffer_t **a, h2o_buffer_t **b)
*a = swap;
}
+void write_chunk_to_socket(struct st_h2o_http1client_private_t *client, h2o_iovec_t headers, h2o_iovec_t chunk, h2o_socket_cb cb)
+{
+ int i = 0;
+ h2o_iovec_t chunk_and_reqbufs[4];
+
+ if (headers.base)
+ chunk_and_reqbufs[i++] = headers;
+
+ chunk_and_reqbufs[i].len = snprintf(client->_chunk_len_str, sizeof(client->_chunk_len_str), "%zX\r\n", chunk.len);
+ chunk_and_reqbufs[i++].base = client->_chunk_len_str;
+
+ if (chunk.base != NULL)
+ chunk_and_reqbufs[i++] = h2o_iovec_init(chunk.base, chunk.len);
+ chunk_and_reqbufs[i++] = h2o_iovec_init("\r\n", 2);
+
+ h2o_socket_write(client->super.sock, chunk_and_reqbufs, i, cb);
+}
+
int h2o_http1client_write_req_chunk(void *priv, h2o_iovec_t req_chunk, int is_end)
{
h2o_socket_t *sock = priv;
@@ -462,18 +480,9 @@ int h2o_http1client_write_req_chunk(void *priv, h2o_iovec_t req_chunk, int is_en
on_send_request(sock, NULL);
return 0;
}
- int i = 0;
- h2o_iovec_t chunk_and_reqbufs[3];
-
- chunk_and_reqbufs[i].len =
- snprintf(client->_chunk_len_str, sizeof(client->_chunk_len_str), "%zX\r\n", client->_body_buf_in_flight->size);
- chunk_and_reqbufs[i++].base = client->_chunk_len_str;
-
- if (client->_body_buf_in_flight != NULL)
- chunk_and_reqbufs[i++] = h2o_iovec_init(client->_body_buf_in_flight->bytes, client->_body_buf_in_flight->size);
- chunk_and_reqbufs[i++] = h2o_iovec_init("\r\n", 2);
-
- h2o_socket_write(client->super.sock, chunk_and_reqbufs, i, on_req_body_done);
+ write_chunk_to_socket(client, h2o_iovec_init(NULL, 0),
+ h2o_iovec_init(client->_body_buf_in_flight->bytes, client->_body_buf_in_flight->size),
+ on_req_body_done);
} else {
h2o_iovec_t iov = h2o_iovec_init(client->_body_buf_in_flight->bytes, client->_body_buf_in_flight->size);
@@ -517,9 +526,14 @@ static void on_connection_ready(struct st_h2o_http1client_private_t *client)
}
}
h2o_socket_write(client->super.sock, reqbufs, reqbufcnt, on_req_body_done);
+ } else {
+ if (client->_is_chunked) {
+ assert(reqbufcnt == 2);
+ write_chunk_to_socket(client, reqbufs[0], reqbufs[1], on_send_request);
} else {
h2o_socket_write(client->super.sock, reqbufs, reqbufcnt, on_send_request);
}
+ }
/* TODO no need to set the timeout if all data has been written into TCP sendbuf */
client->_timeout.cb = on_send_timeout;
