#include <nghttp2/nghttp2.h>
#include "urldata.h"
+#include "url.h"
#include "cfilters.h"
#include "connect.h"
#include "curl_trc.h"
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
struct cf_call_data save;
- CURLcode result, r2;
+ CURLcode result;
*pnread = 0;
CF_DATA_SAVE(save, cf, data);
nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, *pnread);
}
- r2 = proxy_h2_progress_egress(cf, data);
- if(r2 && (r2 != CURLE_AGAIN))
- result = r2;
+ result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data));
out:
if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
struct cf_h2_proxy_ctx *ctx = cf->ctx;
struct cf_call_data save;
int rv;
- CURLcode result, r2;
+ CURLcode result;
(void)eos;
*pnwritten = 0;
}
}
- r2 = proxy_h2_progress_ingress(cf, data);
- if(r2 && (r2 != CURLE_AGAIN)) {
- result = r2;
- goto out;
- }
-
- /* Call the nghttp2 send loop and flush to write ALL buffered data,
- * headers and/or request body completely out to the network */
- r2 = proxy_h2_progress_egress(cf, data);
- if(r2 && (r2 != CURLE_AGAIN)) {
- result = r2;
- goto out;
- }
+ result = Curl_1st_fatal(result, proxy_h2_progress_ingress(cf, data));
+ result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data));
if(!result && proxy_h2_should_close_session(ctx)) {
/* nghttp2 thinks this session is done. If the stream has not been
*/
CURLcode curl_easy_pause(CURL *d, int action)
{
- CURLcode result = CURLE_OK, r2;
+ CURLcode result = CURLE_OK;
bool recursive = FALSE;
bool changed = FALSE;
struct Curl_easy *data = d;
if(send_paused != send_paused_new) {
changed = TRUE;
- r2 = Curl_xfer_pause_send(data, send_paused_new);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, Curl_xfer_pause_send(data, send_paused_new));
}
if(recv_paused != recv_paused_new) {
changed = TRUE;
- r2 = Curl_xfer_pause_recv(data, recv_paused_new);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, Curl_xfer_pause_recv(data, recv_paused_new));
}
/* If not completely pausing both directions now, run again in any case. */
out:
if(last_hd) {
/* if not written yet, write it now */
- CURLcode r2 = http_write_header(data, last_hd, last_hd_len);
- if(!result)
- result = r2;
+ result = Curl_1st_err(
+ result, http_write_header(data, last_hd, last_hd_len));
}
return result;
}
after an error was detected */
bool premature)
{
- CURLcode result, r2;
+ CURLcode result;
struct connectdata *conn = data->conn;
struct multi_done_ctx mdctx;
}
/* Make sure that transfer client writes are really done now. */
- r2 = Curl_xfer_write_done(data, premature);
- if(r2 && !result)
- result = r2;
+ result = Curl_1st_err(result, Curl_xfer_write_done(data, premature));
/* Inform connection filters that this transfer is done */
Curl_conn_ev_data_done(data, premature);
{
return Curl_hash_pick(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1);
}
+
+CURLcode Curl_1st_err(CURLcode r1, CURLcode r2)
+{
+ return r1 ? r1 : r2;
+}
+
+CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2)
+{
+ if(r1 && (r1 != CURLE_AGAIN))
+ return r1;
+ if(r2 && (r2 != CURLE_AGAIN))
+ return r2;
+ return r1;
+}
struct connectdata *conn,
struct curltime *now);
+/**
+ * Always eval all arguments, return the first result != CURLE_OK.
+ * A non-short-circuit evaluation.
+ */
+CURLcode Curl_1st_err(CURLcode r1, CURLcode r2);
+
+/**
+ * Always eval all arguments, return the first
+ * result != (CURLE_OK|CURLE_AGAIN) or `r1`.
+ * A non-short-circuit evaluation.
+ */
+CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2);
+
#if defined(USE_HTTP2) || defined(USE_HTTP3)
void Curl_data_priority_clear_state(struct Curl_easy *data);
#else
#endif
#include "../urldata.h"
+#include "../url.h"
#include "../uint-hash.h"
#include "../sendf.h"
#include "../strdup.h"
result = CURLE_AGAIN;
out:
- if(cf_progress_egress(cf, data, &pktx)) {
- result = CURLE_SEND_ERROR;
- }
- else {
- CURLcode r2 = check_and_set_expiry(cf, data, &pktx);
- if(r2)
- result = r2;
- }
+ result = Curl_1st_err(result, cf_progress_egress(cf, data, &pktx));
+ result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx));
+
CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %dm, %zu",
+
stream ? stream->id : -1, blen, result, *pnread);
CF_DATA_RESTORE(cf, save);
return result;
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
struct cf_call_data save;
struct pkt_io_ctx pktx;
- CURLcode result = CURLE_OK, r2;
+ CURLcode result = CURLE_OK;
CF_DATA_SAVE(save, cf, data);
DEBUGASSERT(cf->connected);
return ctx->tls_vrfy_result;
(void)eos; /* use for stream EOF and block handling */
- r2 = cf_progress_ingress(cf, data, &pktx);
- if(r2) {
- result = r2;
- }
+ result = cf_progress_ingress(cf, data, &pktx);
+ if(result)
+ goto out;
if(!stream || stream->id < 0) {
if(ctx->shutdown_started) {
if(*pnwritten > 0 && !ctx->tls_handshake_complete && ctx->use_earlydata)
ctx->earlydata_skip += *pnwritten;
- r2 = cf_progress_egress(cf, data, &pktx);
- if(r2)
- result = r2;
+ DEBUGASSERT(!result);
+ result = cf_progress_egress(cf, data, &pktx);
out:
- r2 = check_and_set_expiry(cf, data, &pktx);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx));
CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu",
stream ? stream->id : -1, len, result, *pnwritten);
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
struct cf_call_data save;
ssize_t nwritten;
- CURLcode result = CURLE_OK, r2;
+ CURLcode result = CURLE_OK;
(void)eos; /* use to end stream */
CF_DATA_SAVE(save, cf, data);
(void)nghttp3_conn_resume_stream(ctx->h3.conn, stream->s.id);
}
- r2 = cf_progress_egress(cf, data);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, cf_progress_egress(cf, data));
out:
- r2 = check_and_set_expiry(cf, data);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, check_and_set_expiry(cf, data));
+
CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu",
stream ? stream->s.id : -1, len, result, *pnwritten);
CF_DATA_RESTORE(cf, save);
struct cf_osslq_ctx *ctx = cf->ctx;
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
struct cf_call_data save;
- CURLcode result = CURLE_OK, r2;
+ CURLcode result = CURLE_OK;
(void)ctx;
CF_DATA_SAVE(save, cf, data);
}
}
- r2 = cf_progress_ingress(cf, data);
- if(r2) {
- result = r2;
+ result = Curl_1st_err(result, cf_progress_ingress(cf, data));
+ if(result)
goto out;
- }
/* recvbuf had nothing before, maybe after progressing ingress? */
if(!*pnread && !Curl_bufq_is_empty(&stream->recvbuf)) {
}
out:
- if(cf_progress_egress(cf, data)) {
- result = CURLE_SEND_ERROR;
- }
- else {
- r2 = check_and_set_expiry(cf, data);
- if(r2)
- result = r2;
- }
+ result = Curl_1st_err(result, cf_progress_egress(cf, data));
+ result = Curl_1st_err(result, check_and_set_expiry(cf, data));
+
CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(len=%zu) -> %d, %zu",
stream ? stream->s.id : -1, len, result, *pnread);
CF_DATA_RESTORE(cf, save);
{
struct cf_quiche_ctx *ctx = cf->ctx;
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
- CURLcode result = CURLE_OK, r2;
+ CURLcode result = CURLE_OK;
*pnread = 0;
vquic_ctx_update_time(&ctx->q);
}
out:
- r2 = cf_flush_egress(cf, data);
- if(r2) {
- CURL_TRC_CF(data, cf, "cf_recv, flush egress failed");
- result = r2;
- }
+ result = Curl_1st_err(result, cf_flush_egress(cf, data));
if(*pnread > 0)
ctx->data_recvd += *pnread;
CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] cf_recv(total=%"
{
struct cf_quiche_ctx *ctx = cf->ctx;
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
- CURLcode result, r2;
+ CURLcode result;
*pnwritten = 0;
vquic_ctx_update_time(&ctx->q);
}
out:
- r2 = cf_flush_egress(cf, data);
- if(r2)
- result = r2;
+ result = Curl_1st_err(result, cf_flush_egress(cf, data));
CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_send(len=%zu) -> %d, %zu",
stream ? stream->id : (curl_uint64_t)~0, len,