mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 09:21:50 -05:00
CURL_PUSH_ERROROUT: allow the push callback to fail the parent stream
... by adding support for a new dedicated return code. Suggested-by: Jonathan Cardoso Assisted-by: Erik Johansson URL: https://curl.haxx.se/mail/lib-2020-06/0099.html Closes #5636
This commit is contained in:
parent
2f5d0e497e
commit
954cd3eb48
@ -36,7 +36,6 @@
|
||||
1.17 Add support for IRIs
|
||||
1.18 try next proxy if one doesn't work
|
||||
1.20 SRV and URI DNS records
|
||||
1.21 Add return code to CURLMOPT_PUSHFUNCTION to fail the connection
|
||||
1.22 CURLINFO_PAUSE_STATE
|
||||
1.23 Offer API to flush the connection pool
|
||||
1.24 TCP Fast Open for windows
|
||||
@ -358,13 +357,6 @@
|
||||
Offer support for resolving SRV and URI DNS records for libcurl to know which
|
||||
server to connect to for various protocols (including HTTP!).
|
||||
|
||||
1.21 Add return code to CURLMOPT_PUSHFUNCTION to fail the connection
|
||||
|
||||
Allow the callback to return a value that would stop the entire operation,
|
||||
like it can be done from most other callbacks.
|
||||
|
||||
See https://curl.haxx.se/mail/lib-2020-06/0099.html
|
||||
|
||||
1.22 CURLINFO_PAUSE_STATE
|
||||
|
||||
Return information about the transfer's current pause state, in both
|
||||
|
@ -86,6 +86,9 @@ the ownership of the CURL handle has been taken over by the application.
|
||||
.IP "CURL_PUSH_DENY (1)"
|
||||
The callback denies the stream and no data for this will reach the
|
||||
application, the easy handle will be destroyed by libcurl.
|
||||
.IP "CURL_PUSH_ERROROUT (2)"
|
||||
Returning this will reject the pushed stream and return an error back on the
|
||||
parent stream making it get closed with an error. (Added in curl 7.72.0)
|
||||
.IP *
|
||||
All other return codes are reserved for future use.
|
||||
.SH DEFAULT
|
||||
|
@ -892,6 +892,7 @@ CURL_PROGRESSFUNC_CONTINUE 7.68.0
|
||||
CURL_PROGRESS_BAR 7.1.1 - 7.4.1
|
||||
CURL_PROGRESS_STATS 7.1.1 - 7.4.1
|
||||
CURL_PUSH_DENY 7.44.0
|
||||
CURL_PUSH_ERROROUT 7.72.0
|
||||
CURL_PUSH_OK 7.44.0
|
||||
CURL_READFUNC_ABORT 7.12.1
|
||||
CURL_READFUNC_PAUSE 7.18.0
|
||||
|
@ -427,12 +427,14 @@ CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream.
|
||||
* server. It approves or denies the new stream. It can also decide
|
||||
* to completely fail the connection.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
|
||||
* Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
|
27
lib/http2.c
27
lib/http2.c
@ -514,7 +514,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const nghttp2_push_promise *frame)
|
||||
{
|
||||
int rv;
|
||||
int rv; /* one of the CURL_PUSH_* defines */
|
||||
H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
@ -528,7 +528,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
struct Curl_easy *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
rv = 1; /* FAIL HARD */
|
||||
rv = CURL_PUSH_DENY; /* FAIL HARD */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -541,13 +541,15 @@ static int push_promise(struct Curl_easy *data,
|
||||
if(!stream) {
|
||||
failf(data, "Internal NULL stream!\n");
|
||||
(void)Curl_close(&newhandle);
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rv = set_transfer_url(newhandle, &heads);
|
||||
if(rv)
|
||||
if(rv) {
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
Curl_set_in_callback(data, true);
|
||||
rv = data->multi->push_cb(data, newhandle,
|
||||
@ -563,6 +565,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
stream->push_headers_used = 0;
|
||||
|
||||
if(rv) {
|
||||
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
|
||||
/* denied, kill off the new handle again */
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
newhandle->req.protop = NULL;
|
||||
@ -583,7 +586,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
newhandle->req.protop = NULL;
|
||||
Curl_close(&newhandle);
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -595,12 +598,13 @@ static int push_promise(struct Curl_easy *data,
|
||||
infof(data, "failed to set user_data for stream %d\n",
|
||||
frame->promised_stream_id);
|
||||
DEBUGASSERT(0);
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
}
|
||||
fail:
|
||||
return rv;
|
||||
@ -737,11 +741,16 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
rv = push_promise(data_s, conn, &frame->push_promise);
|
||||
if(rv) { /* deny! */
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
int h2;
|
||||
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
|
||||
h2 = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_CANCEL);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
if(nghttp2_is_fatal(h2))
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(rv == CURL_PUSH_ERROROUT) {
|
||||
DEBUGF(infof(data_s, "Fail the parent stream (too)\n"));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user