if (!aborted) {
bool handled = FALSE;
- /* failed Expect: */
- if (response.status == 417 && req->payload_sync) {
- /* drop Expect: continue */
- req->payload_sync = FALSE;
- conn->output_locked = FALSE;
- conn->peer->no_payload_sync = TRUE;
- if (http_client_request_try_retry(req))
- handled = TRUE;
- /* redirection */
- } else if (!req->client->set.no_auto_redirect &&
- response.status / 100 == 3 && response.status != 304 &&
- response.location != NULL) {
- /* redirect (possibly after delay) */
- if (http_client_request_delay_from_response(req, &response) >= 0) {
- http_client_request_redirect
- (req, response.status, response.location);
- handled = TRUE;
+ /* don't redirect/retry if we're sending data in small
+ blocks via http_client_request_send_payload()
+ and we're not waiting for 100 continue */
+ if (!req->payload_wait ||
+ (req->payload_sync && !conn->payload_continue)) {
+ /* failed Expect: */
+ if (response.status == 417 && req->payload_sync) {
+ /* drop Expect: continue */
+ req->payload_sync = FALSE;
+ conn->output_locked = FALSE;
+ conn->peer->no_payload_sync = TRUE;
+ if (http_client_request_try_retry(req))
+ handled = TRUE;
+ /* redirection */
+ } else if (!req->client->set.no_auto_redirect &&
+ response.status / 100 == 3 && response.status != 304 &&
+ response.location != NULL) {
+ /* redirect (possibly after delay) */
+ if (http_client_request_delay_from_response(req, &response) >= 0) {
+ http_client_request_redirect
+ (req, response.status, response.location);
+ handled = TRUE;
+ }
+ /* service unavailable */
+ } else if (response.status == 503) {
+ /* automatically retry after delay if indicated */
+ if ( response.retry_after != (time_t)-1 &&
+ http_client_request_delay_from_response(req, &response) > 0 &&
+ http_client_request_try_retry(req))
+ handled = TRUE;
}
- /* service unavailable */
- } else if (response.status == 503) {
- /* automatically retry after delay if indicated */
- if ( response.retry_after != (time_t)-1 &&
- http_client_request_delay_from_response(req, &response) > 0 &&
- http_client_request_try_retry(req))
- handled = TRUE;
}
if (!handled) {
if (!req->have_hdr_expect && req->payload_sync) {
str_append(rtext, "Expect: 100-continue\r\n");
}
- if (req->payload_chunked) {
- // FIXME: can't do this for a HTTP/1.0 server
- if (!req->have_hdr_body_spec)
- str_append(rtext, "Transfer-Encoding: chunked\r\n");
- req->payload_output =
- http_transfer_chunked_ostream_create(output);
- } else if (req->payload_input != NULL) {
- /* send Content-Length if we have specified a payload,
- even if it's 0 bytes. */
- if (!req->have_hdr_body_spec) {
- str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
- req->payload_size);
+ if (req->payload_input != NULL) {
+ if (req->payload_chunked) {
+ // FIXME: can't do this for a HTTP/1.0 server
+ if (!req->have_hdr_body_spec)
+ str_append(rtext, "Transfer-Encoding: chunked\r\n");
+ req->payload_output =
+ http_transfer_chunked_ostream_create(output);
+ } else {
+ /* send Content-Length if we have specified a payload,
+ even if it's 0 bytes. */
+ if (!req->have_hdr_body_spec) {
+ str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
+ req->payload_size);
+ }
+ req->payload_output = output;
+ o_stream_ref(output);
}
- req->payload_output = output;
- o_stream_ref(output);
}
if (!req->have_hdr_connection && req->host_url == &req->origin_url) {
/* https://tools.ietf.org/html/rfc2068
struct http_url *url;
const char *error, *target, *origin_url;
+ i_assert(!req->payload_wait);
+
/* parse URL */
if (http_url_parse(location, NULL, 0,
pool_datastack_create(), &url, &error) < 0) {
void http_client_request_resubmit(struct http_client_request *req)
{
+ i_assert(!req->payload_wait);
+
http_client_request_debug(req, "Resubmitting request");
/* rewind payload stream */