Loading docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 +1 −1 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ struct curl_headerpair *curl_pushheader_byname(push_headers, char *name); int curl_push_callback(CURL *parent, int curl_push_callback(CURL *parent, CURL *easy, CURL *easy, int num_headers, size_t num_headers, struct curl_pushheaders *headers, struct curl_pushheaders *headers, void *userp); void *userp); Loading include/curl/multi.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -302,10 +302,14 @@ struct curl_headerpair { }; }; struct curl_pushheaders; /* forward declaration only */ struct curl_pushheaders; /* forward declaration only */ struct curl_headerpair *curl_pushheader_bynum(struct curl_pushheaders *h, int num); struct curl_headerpair *curl_pushheader_byname(struct curl_pushheaders *h, char *name); typedef int (*curl_push_callback)(CURL *parent, typedef int (*curl_push_callback)(CURL *parent, CURL *easy, CURL *easy, int num_headers, size_t num_headers, struct curl_pushheaders *headers, struct curl_pushheaders *headers, void *userp); void *userp); Loading lib/http2.c +74 −6 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include "rawstr.h" #include "rawstr.h" #include "multiif.h" #include "multiif.h" #include "conncache.h" #include "conncache.h" #include "url.h" /* The last #include files should be: */ /* The last #include files should be: */ #include "curl_memory.h" #include "curl_memory.h" Loading Loading @@ -205,6 +206,71 @@ static ssize_t send_callback(nghttp2_session *h2, return written; return written; } } /* We pass a pointer to this struct in the push callback, but the contents of the struct are hidden from the user. */ struct curl_pushheaders { struct SessionHandle *data; const nghttp2_push_promise *frame; }; /* * push header access function. Only to be used from within the push callback */ struct curl_headerpair *curl_pushheader_bynum(struct curl_pushheaders *h, int num) { /* Verify that we got a good easy handle in the push header struct, mostly to detect rubbish input fast(er). */ if(!h || !GOOD_EASY_HANDLE(h->data)) return NULL; (void)num; return NULL; } static int push_promise(struct SessionHandle *data, const nghttp2_push_promise *frame) { int rv; if(data->multi->push_cb) { /* clone the parent */ CURL *newhandle = curl_easy_duphandle(data); if(!newhandle) { infof(data, "failed to duplicate handle\n"); rv = 1; /* FAIL HARD */ } else { struct curl_pushheaders heads; heads.data = data; heads.frame = frame; /* ask the application */ DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); rv = data->multi->push_cb(data, newhandle, frame->nvlen, &heads, data->multi->push_userp); if(rv) /* denied, kill off the new handle again */ (void)Curl_close(newhandle); else { /* approved, add to the multi handle */ CURLMcode rc = curl_multi_add_handle(data->multi, newhandle); if(rc) { infof(data, "failed to add handle to multi\n"); Curl_close(newhandle); rv = 1; } else rv = 0; } } } else { DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); rv = 1; } return rv; } static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, void *userp) void *userp) { { Loading Loading @@ -292,13 +358,15 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, Curl_expire(data_s, 1); Curl_expire(data_s, 1); break; break; case NGHTTP2_PUSH_PROMISE: case NGHTTP2_PUSH_PROMISE: DEBUGF(infof(data_s, "Got PUSH_PROMISE, RST_STREAM it!\n")); rv = push_promise(data_s, &frame->push_promise); if(rv) { /* deny! */ rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, frame->push_promise.promised_stream_id, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); NGHTTP2_CANCEL); if(nghttp2_is_fatal(rv)) { if(nghttp2_is_fatal(rv)) { return rv; return rv; } } } break; break; case NGHTTP2_SETTINGS: case NGHTTP2_SETTINGS: { { Loading lib/multi.c +6 −2 Original line number Original line Diff line number Diff line Loading @@ -62,8 +62,6 @@ #define GOOD_MULTI_HANDLE(x) \ #define GOOD_MULTI_HANDLE(x) \ ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE)) ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE)) #define GOOD_EASY_HANDLE(x) \ ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)) static void singlesocket(struct Curl_multi *multi, static void singlesocket(struct Curl_multi *multi, struct SessionHandle *data); struct SessionHandle *data); Loading Loading @@ -2341,6 +2339,12 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle, case CURLMOPT_SOCKETDATA: case CURLMOPT_SOCKETDATA: multi->socket_userp = va_arg(param, void *); multi->socket_userp = va_arg(param, void *); break; break; case CURLMOPT_PUSHFUNCTION: multi->push_cb = va_arg(param, curl_push_callback); break; case CURLMOPT_PUSHDATA: multi->push_userp = va_arg(param, void *); break; case CURLMOPT_PIPELINING: case CURLMOPT_PIPELINING: multi->pipelining = va_arg(param, long); multi->pipelining = va_arg(param, long); break; break; Loading lib/multihandle.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ struct Curl_multi { curl_socket_callback socket_cb; curl_socket_callback socket_cb; void *socket_userp; void *socket_userp; /* callback function and user data pointer for server push */ curl_push_callback push_cb; void *push_userp; /* Hostname cache */ /* Hostname cache */ struct curl_hash hostcache; struct curl_hash hostcache; Loading Loading
docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 +1 −1 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ struct curl_headerpair *curl_pushheader_byname(push_headers, char *name); int curl_push_callback(CURL *parent, int curl_push_callback(CURL *parent, CURL *easy, CURL *easy, int num_headers, size_t num_headers, struct curl_pushheaders *headers, struct curl_pushheaders *headers, void *userp); void *userp); Loading
include/curl/multi.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -302,10 +302,14 @@ struct curl_headerpair { }; }; struct curl_pushheaders; /* forward declaration only */ struct curl_pushheaders; /* forward declaration only */ struct curl_headerpair *curl_pushheader_bynum(struct curl_pushheaders *h, int num); struct curl_headerpair *curl_pushheader_byname(struct curl_pushheaders *h, char *name); typedef int (*curl_push_callback)(CURL *parent, typedef int (*curl_push_callback)(CURL *parent, CURL *easy, CURL *easy, int num_headers, size_t num_headers, struct curl_pushheaders *headers, struct curl_pushheaders *headers, void *userp); void *userp); Loading
lib/http2.c +74 −6 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include "rawstr.h" #include "rawstr.h" #include "multiif.h" #include "multiif.h" #include "conncache.h" #include "conncache.h" #include "url.h" /* The last #include files should be: */ /* The last #include files should be: */ #include "curl_memory.h" #include "curl_memory.h" Loading Loading @@ -205,6 +206,71 @@ static ssize_t send_callback(nghttp2_session *h2, return written; return written; } } /* We pass a pointer to this struct in the push callback, but the contents of the struct are hidden from the user. */ struct curl_pushheaders { struct SessionHandle *data; const nghttp2_push_promise *frame; }; /* * push header access function. Only to be used from within the push callback */ struct curl_headerpair *curl_pushheader_bynum(struct curl_pushheaders *h, int num) { /* Verify that we got a good easy handle in the push header struct, mostly to detect rubbish input fast(er). */ if(!h || !GOOD_EASY_HANDLE(h->data)) return NULL; (void)num; return NULL; } static int push_promise(struct SessionHandle *data, const nghttp2_push_promise *frame) { int rv; if(data->multi->push_cb) { /* clone the parent */ CURL *newhandle = curl_easy_duphandle(data); if(!newhandle) { infof(data, "failed to duplicate handle\n"); rv = 1; /* FAIL HARD */ } else { struct curl_pushheaders heads; heads.data = data; heads.frame = frame; /* ask the application */ DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); rv = data->multi->push_cb(data, newhandle, frame->nvlen, &heads, data->multi->push_userp); if(rv) /* denied, kill off the new handle again */ (void)Curl_close(newhandle); else { /* approved, add to the multi handle */ CURLMcode rc = curl_multi_add_handle(data->multi, newhandle); if(rc) { infof(data, "failed to add handle to multi\n"); Curl_close(newhandle); rv = 1; } else rv = 0; } } } else { DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); rv = 1; } return rv; } static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, void *userp) void *userp) { { Loading Loading @@ -292,13 +358,15 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, Curl_expire(data_s, 1); Curl_expire(data_s, 1); break; break; case NGHTTP2_PUSH_PROMISE: case NGHTTP2_PUSH_PROMISE: DEBUGF(infof(data_s, "Got PUSH_PROMISE, RST_STREAM it!\n")); rv = push_promise(data_s, &frame->push_promise); if(rv) { /* deny! */ rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, frame->push_promise.promised_stream_id, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); NGHTTP2_CANCEL); if(nghttp2_is_fatal(rv)) { if(nghttp2_is_fatal(rv)) { return rv; return rv; } } } break; break; case NGHTTP2_SETTINGS: case NGHTTP2_SETTINGS: { { Loading
lib/multi.c +6 −2 Original line number Original line Diff line number Diff line Loading @@ -62,8 +62,6 @@ #define GOOD_MULTI_HANDLE(x) \ #define GOOD_MULTI_HANDLE(x) \ ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE)) ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE)) #define GOOD_EASY_HANDLE(x) \ ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)) static void singlesocket(struct Curl_multi *multi, static void singlesocket(struct Curl_multi *multi, struct SessionHandle *data); struct SessionHandle *data); Loading Loading @@ -2341,6 +2339,12 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle, case CURLMOPT_SOCKETDATA: case CURLMOPT_SOCKETDATA: multi->socket_userp = va_arg(param, void *); multi->socket_userp = va_arg(param, void *); break; break; case CURLMOPT_PUSHFUNCTION: multi->push_cb = va_arg(param, curl_push_callback); break; case CURLMOPT_PUSHDATA: multi->push_userp = va_arg(param, void *); break; case CURLMOPT_PIPELINING: case CURLMOPT_PIPELINING: multi->pipelining = va_arg(param, long); multi->pipelining = va_arg(param, long); break; break; Loading
lib/multihandle.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ struct Curl_multi { curl_socket_callback socket_cb; curl_socket_callback socket_cb; void *socket_userp; void *socket_userp; /* callback function and user data pointer for server push */ curl_push_callback push_cb; void *push_userp; /* Hostname cache */ /* Hostname cache */ struct curl_hash hostcache; struct curl_hash hostcache; Loading