Loading docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 +7 −14 Original line number Diff line number Diff line Loading @@ -27,15 +27,8 @@ CURLMOPT_PUSHFUNCTION \- approve or deny server pushes .nf #include <curl/curl.h> struct curl_headerpair { unsigned char *name; /* zero terminated name */ size_t namelen; /* length of 'name' */ unsigned char *value; /* zero terminated name */ size_t valuelen; /* length of 'value' */ }; struct curl_headerpair *curl_pushheader_bynum(push_headers, int num); struct curl_headerpair *curl_pushheader_byname(push_headers, char *name); char *curl_pushheader_bynum(push_headers, int num); char *curl_pushheader_byname(push_headers, char *name); int curl_push_callback(CURL *parent, CURL *easy, Loading Loading @@ -78,12 +71,12 @@ functions. These functions can only be used from within this callback and they can only access the PUSH_PROMISE headers. The normal response headers will be pased to the header callback for pushed streams just as for normal streams. .IP curl_pushheader_bynum Returns the header pair at index 'num' (or NULL). The returned pointer points to a struct that will be freed when this callback returns. Returns the header at index 'num' (or NULL). The returned pointer points to a "name:value" string that will be freed when this callback returns. .IP curl_pushheader_byname Returns the header pair for the given header name (or NULL). This is a shortcut so that the application doesn't have to loop through all headers to find the one it is interested in. Returns the value for the given header name (or NULL). This is a shortcut so that the application doesn't have to loop through all headers to find the one it is interested in. .SH CALLBACK RETURN VALUE .IP "CURL_PUSH_OK (0)" The application has accepted the stream and it can now start receiving data, Loading include/curl/multi.h +6 −11 Original line number Diff line number Diff line Loading @@ -294,17 +294,12 @@ typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ #define CURL_PUSH_OK 0 #define CURL_PUSH_DENY 1 struct curl_headerpair { unsigned char *name; /* zero terminated name */ size_t namelen; /* length of 'name' */ unsigned char *value; /* zero terminated name */ size_t valuelen; /* length of 'value' */ }; 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, CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num); CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, char *name); typedef int (*curl_push_callback)(CURL *parent, Loading lib/http.c +4 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ static CURLcode http_disconnect(struct connectdata *conn, bool dead_connection) if(http) { Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ free(http->push_headers); http->push_headers = NULL; } #else (void)conn; Loading Loading @@ -1492,6 +1494,8 @@ CURLcode Curl_http_done(struct connectdata *conn, DEBUGF(infof(data, "free header_recvbuf!!\n")); Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ free(http->push_headers); http->push_headers = NULL; } #endif Loading lib/http.h +4 −1 Original line number Diff line number Diff line Loading @@ -176,7 +176,10 @@ struct HTTP { const uint8_t *upload_mem; /* points to a buffer to read from */ size_t upload_len; /* size of the buffer 'upload_mem' points to */ curl_off_t upload_left; /* number of bytes left to upload */ Curl_send_buffer *push_recvbuf; /* store incoming push headers */ char **push_headers; /* allocated array */ size_t push_headers_used; /* number of entries filled in */ size_t push_headers_alloc; /* number of entries allocated */ #endif }; Loading lib/http2.c +61 −17 Original line number Diff line number Diff line Loading @@ -219,14 +219,42 @@ struct curl_pushheaders { /* * 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) char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t 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; else { struct HTTP *stream = h->data->req.protop; if(num < stream->push_headers_used) return stream->push_headers[num]; } return NULL; } /* * push header access function. Only to be used from within the push callback */ char *curl_pushheader_byname(struct curl_pushheaders *h, char *header) { /* 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) || !header) return NULL; else { struct HTTP *stream = h->data->req.protop; size_t len = strlen(header); size_t i; for(i=0; i<stream->push_headers_used; i++) { if(!strncmp(header, stream->push_headers[i], len)) { /* sub-match, make sure that it us followed by a colon */ if(stream->push_headers[i][len] != ':') continue; return &stream->push_headers[i][len+1]; } } } return NULL; } Loading Loading @@ -283,13 +311,14 @@ static int push_promise(struct SessionHandle *data, stream = data->req.protop; #ifdef CURLDEBUG fprintf(stderr, "PUSHHDR %s\n", stream->push_recvbuf->buffer); #endif rv = data->multi->push_cb(data, newhandle, frame->nvlen, &heads, stream->push_headers_used, &heads, data->multi->push_userp); /* free the headers array again */ free(stream->push_headers); stream->push_headers = NULL; if(rv) { /* denied, kill off the new handle again */ (void)Curl_close(newhandle); Loading Loading @@ -667,15 +696,30 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, /* Store received PUSH_PROMISE headers to be used when the subsequent PUSH_PROMISE callback comes */ if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { fprintf(stderr, "*** PUSH_PROMISE headers on stream %u for %u\n", stream_id, frame->push_promise.promised_stream_id); if(!stream->push_recvbuf) stream->push_recvbuf = Curl_add_buffer_init(); Curl_add_buffer(stream->push_recvbuf, name, namelen); Curl_add_buffer(stream->push_recvbuf, ":", 1); Curl_add_buffer(stream->push_recvbuf, value, valuelen); Curl_add_buffer(stream->push_recvbuf, "\r\n", 2); char *h; if(!stream->push_headers) { stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * sizeof(char *)); stream->push_headers_used = 0; } else if(stream->push_headers_used == stream->push_headers_alloc) { char **headp; stream->push_headers_alloc *= 2; headp = realloc(stream->push_headers, stream->push_headers_alloc * sizeof(char *)); if(!headp) { free(stream->push_headers); stream->push_headers = NULL; return 1; } stream->push_headers = headp; } h = aprintf("%s:%s", name, value); if(h) stream->push_headers[stream->push_headers_used++] = h; return 0; } Loading Loading
docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 +7 −14 Original line number Diff line number Diff line Loading @@ -27,15 +27,8 @@ CURLMOPT_PUSHFUNCTION \- approve or deny server pushes .nf #include <curl/curl.h> struct curl_headerpair { unsigned char *name; /* zero terminated name */ size_t namelen; /* length of 'name' */ unsigned char *value; /* zero terminated name */ size_t valuelen; /* length of 'value' */ }; struct curl_headerpair *curl_pushheader_bynum(push_headers, int num); struct curl_headerpair *curl_pushheader_byname(push_headers, char *name); char *curl_pushheader_bynum(push_headers, int num); char *curl_pushheader_byname(push_headers, char *name); int curl_push_callback(CURL *parent, CURL *easy, Loading Loading @@ -78,12 +71,12 @@ functions. These functions can only be used from within this callback and they can only access the PUSH_PROMISE headers. The normal response headers will be pased to the header callback for pushed streams just as for normal streams. .IP curl_pushheader_bynum Returns the header pair at index 'num' (or NULL). The returned pointer points to a struct that will be freed when this callback returns. Returns the header at index 'num' (or NULL). The returned pointer points to a "name:value" string that will be freed when this callback returns. .IP curl_pushheader_byname Returns the header pair for the given header name (or NULL). This is a shortcut so that the application doesn't have to loop through all headers to find the one it is interested in. Returns the value for the given header name (or NULL). This is a shortcut so that the application doesn't have to loop through all headers to find the one it is interested in. .SH CALLBACK RETURN VALUE .IP "CURL_PUSH_OK (0)" The application has accepted the stream and it can now start receiving data, Loading
include/curl/multi.h +6 −11 Original line number Diff line number Diff line Loading @@ -294,17 +294,12 @@ typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ #define CURL_PUSH_OK 0 #define CURL_PUSH_DENY 1 struct curl_headerpair { unsigned char *name; /* zero terminated name */ size_t namelen; /* length of 'name' */ unsigned char *value; /* zero terminated name */ size_t valuelen; /* length of 'value' */ }; 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, CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num); CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, char *name); typedef int (*curl_push_callback)(CURL *parent, Loading
lib/http.c +4 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ static CURLcode http_disconnect(struct connectdata *conn, bool dead_connection) if(http) { Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ free(http->push_headers); http->push_headers = NULL; } #else (void)conn; Loading Loading @@ -1492,6 +1494,8 @@ CURLcode Curl_http_done(struct connectdata *conn, DEBUGF(infof(data, "free header_recvbuf!!\n")); Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ free(http->push_headers); http->push_headers = NULL; } #endif Loading
lib/http.h +4 −1 Original line number Diff line number Diff line Loading @@ -176,7 +176,10 @@ struct HTTP { const uint8_t *upload_mem; /* points to a buffer to read from */ size_t upload_len; /* size of the buffer 'upload_mem' points to */ curl_off_t upload_left; /* number of bytes left to upload */ Curl_send_buffer *push_recvbuf; /* store incoming push headers */ char **push_headers; /* allocated array */ size_t push_headers_used; /* number of entries filled in */ size_t push_headers_alloc; /* number of entries allocated */ #endif }; Loading
lib/http2.c +61 −17 Original line number Diff line number Diff line Loading @@ -219,14 +219,42 @@ struct curl_pushheaders { /* * 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) char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t 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; else { struct HTTP *stream = h->data->req.protop; if(num < stream->push_headers_used) return stream->push_headers[num]; } return NULL; } /* * push header access function. Only to be used from within the push callback */ char *curl_pushheader_byname(struct curl_pushheaders *h, char *header) { /* 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) || !header) return NULL; else { struct HTTP *stream = h->data->req.protop; size_t len = strlen(header); size_t i; for(i=0; i<stream->push_headers_used; i++) { if(!strncmp(header, stream->push_headers[i], len)) { /* sub-match, make sure that it us followed by a colon */ if(stream->push_headers[i][len] != ':') continue; return &stream->push_headers[i][len+1]; } } } return NULL; } Loading Loading @@ -283,13 +311,14 @@ static int push_promise(struct SessionHandle *data, stream = data->req.protop; #ifdef CURLDEBUG fprintf(stderr, "PUSHHDR %s\n", stream->push_recvbuf->buffer); #endif rv = data->multi->push_cb(data, newhandle, frame->nvlen, &heads, stream->push_headers_used, &heads, data->multi->push_userp); /* free the headers array again */ free(stream->push_headers); stream->push_headers = NULL; if(rv) { /* denied, kill off the new handle again */ (void)Curl_close(newhandle); Loading Loading @@ -667,15 +696,30 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, /* Store received PUSH_PROMISE headers to be used when the subsequent PUSH_PROMISE callback comes */ if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { fprintf(stderr, "*** PUSH_PROMISE headers on stream %u for %u\n", stream_id, frame->push_promise.promised_stream_id); if(!stream->push_recvbuf) stream->push_recvbuf = Curl_add_buffer_init(); Curl_add_buffer(stream->push_recvbuf, name, namelen); Curl_add_buffer(stream->push_recvbuf, ":", 1); Curl_add_buffer(stream->push_recvbuf, value, valuelen); Curl_add_buffer(stream->push_recvbuf, "\r\n", 2); char *h; if(!stream->push_headers) { stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * sizeof(char *)); stream->push_headers_used = 0; } else if(stream->push_headers_used == stream->push_headers_alloc) { char **headp; stream->push_headers_alloc *= 2; headp = realloc(stream->push_headers, stream->push_headers_alloc * sizeof(char *)); if(!headp) { free(stream->push_headers); stream->push_headers = NULL; return 1; } stream->push_headers = headp; } h = aprintf("%s:%s", name, value); if(h) stream->push_headers[stream->push_headers_used++] = h; return 0; } Loading