http-client-request.c revision 65c0e43da8cfc730eeb4634f8aa384081bbfa4e7
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
50d1446e71cfbdc5b6d7bafcf91b7bff453989d3Stephan Boschstatic inline void
7384b4e78eaab44693c985192276e31322155e32Stephan Boschhttp_client_request_debug(struct http_client_request *req,
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic inline void
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainenhttp_client_request_debug(struct http_client_request *req,
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen const char *format, ...)
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen http_client_request_label(req), t_strdup_vprintf(format, args));
7384b4e78eaab44693c985192276e31322155e32Stephan Boschhttp_client_request(struct http_client *client,
56d1345c43bbd28c36b7faa85e4163bd9e874290Timo Sirainen const char *method, const char *host, const char *target,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch http_client_request_callback_t *callback, void *context)
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen pool = pool_alloconly_create("http client request", 2048);
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen req = p_new(pool, struct http_client_request, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_ref(struct http_client_request *req)
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Boschvoid http_client_request_unref(struct http_client_request **_req)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* only decrease pending request counter if this request was submitted */
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch http_client_request_debug(req, "Destroy (requests left=%d)",
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Boschvoid http_client_request_set_port(struct http_client_request *req,
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch unsigned int port)
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Boschvoid http_client_request_set_ssl(struct http_client_request *req,
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen if (!req->ssl && req->port == HTTP_DEFAULT_PORT)
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen if (req->ssl && req->port == HTTPS_DEFAULT_PORT)
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainenvoid http_client_request_set_urgent(struct http_client_request *req)
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Boschvoid http_client_request_add_header(struct http_client_request *req,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch str_printfa(req->headers, "%s: %s\r\n", key, value);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschvoid http_client_request_set_payload(struct http_client_request *req,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (i_stream_get_size(input, TRUE, &req->payload_size) <= 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* prepare request payload sync using 100 Continue response from server */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if ((req->payload_chunked || req->payload_size > 0) && sync)
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_submit(struct http_client_request *req)
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch i_assert(req->state == HTTP_REQUEST_STATE_NEW);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch host = http_client_host_get(req->client, req->hostname);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschint http_client_request_send_more(struct http_client_request *req)
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch struct http_client_connection *conn = req->conn;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (o_stream_send_istream(output, req->payload_input) < 0)
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch o_stream_set_max_buffer_size(output, (size_t)-1);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (!i_stream_have_bytes_left(req->payload_input)) {
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch req->payload_input->v_offset - req->payload_offset != req->payload_size) {
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch http_client_request_debug(req, "Sent all payload");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch http_client_request_debug(req, "Partially sent payload");
84740b03d3ee9e96a2e446a54729188764c99292Timo Sirainenint http_client_request_send(struct http_client_request *req)
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch struct http_client_connection *conn = req->conn;
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch if ((!req->ssl &&req->port != HTTP_DEFAULT_PORT) ||
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch (req->ssl && req->port != HTTPS_DEFAULT_PORT)) {
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch str_append(rtext, "Expect: 100-continue\r\n");
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen str_append(rtext, "Transfer-Encoding: chunked\r\n");
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (ret >= 0 && req->payload_output != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch http_client_request_debug(req, "Waiting for 100-continue");
return ret;
const char *error;
unsigned int newport;