Lines Matching +full:- +full:- +full:without +full:- +full:nghttp2
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * SPDX-License-Identifier: curl
29 #include <nghttp2/nghttp2.h>
42 #include "cf-h2-proxy.h"
91 ts->state = H2_TUNNEL_INIT; in tunnel_stream_init()
92 ts->stream_id = -1; in tunnel_stream_init()
93 Curl_bufq_init2(&ts->recvbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS, in tunnel_stream_init()
95 Curl_bufq_init(&ts->sendbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS); in tunnel_stream_init()
101 ts->authority = /* host:port with IPv6 support */ in tunnel_stream_init()
103 if(!ts->authority) in tunnel_stream_init()
111 Curl_http_resp_free(ts->resp); in tunnel_stream_clear()
112 Curl_bufq_free(&ts->recvbuf); in tunnel_stream_clear()
113 Curl_bufq_free(&ts->sendbuf); in tunnel_stream_clear()
114 Curl_safefree(ts->authority); in tunnel_stream_clear()
116 ts->state = H2_TUNNEL_INIT; in tunnel_stream_clear()
126 if(ts->state == new_state) in h2_tunnel_go_state()
129 switch(ts->state) { in h2_tunnel_go_state()
131 data->req.ignorebody = FALSE; in h2_tunnel_go_state()
139 CURL_TRC_CF(data, cf, "[%d] new tunnel state 'init'", ts->stream_id); in h2_tunnel_go_state()
144 CURL_TRC_CF(data, cf, "[%d] new tunnel state 'connect'", ts->stream_id); in h2_tunnel_go_state()
145 ts->state = H2_TUNNEL_CONNECT; in h2_tunnel_go_state()
149 CURL_TRC_CF(data, cf, "[%d] new tunnel state 'response'", ts->stream_id); in h2_tunnel_go_state()
150 ts->state = H2_TUNNEL_RESPONSE; in h2_tunnel_go_state()
155 ts->stream_id); in h2_tunnel_go_state()
157 data->state.authproxy.done = TRUE; in h2_tunnel_go_state()
158 data->state.authproxy.multipass = FALSE; in h2_tunnel_go_state()
162 CURL_TRC_CF(data, cf, "[%d] new tunnel state 'failed'", ts->stream_id); in h2_tunnel_go_state()
163 ts->state = new_state; in h2_tunnel_go_state()
164 /* If a proxy-authorization header was used for the proxy, then we should in h2_tunnel_go_state()
167 Curl_safefree(data->state.aptr.proxyuserpwd); in h2_tunnel_go_state()
191 ((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
195 struct cf_call_data save = ctx->call_data; in cf_h2_proxy_ctx_clear()
197 if(ctx->h2) { in cf_h2_proxy_ctx_clear()
198 nghttp2_session_del(ctx->h2); in cf_h2_proxy_ctx_clear()
200 Curl_bufq_free(&ctx->inbufq); in cf_h2_proxy_ctx_clear()
201 Curl_bufq_free(&ctx->outbufq); in cf_h2_proxy_ctx_clear()
202 tunnel_stream_clear(&ctx->tunnel); in cf_h2_proxy_ctx_clear()
204 ctx->call_data = save; in cf_h2_proxy_ctx_clear()
223 if(!tunnel->closed && !tunnel->reset && tunnel->upload_blocked_len) in drain_tunnel()
225 if(data->state.select_bits != bits) { in drain_tunnel()
227 tunnel->stream_id, bits); in drain_tunnel()
228 data->state.select_bits = bits; in drain_tunnel()
242 nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, buflen, err); in proxy_nw_in_reader()
243 CURL_TRC_CF(data, cf, "[0] nw_in_reader(len=%zu) -> %zd, %d", in proxy_nw_in_reader()
261 nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, in proxy_h2_nw_out_writer()
263 CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %zd, %d", in proxy_h2_nw_out_writer()
275 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_client_new()
289 rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o); in proxy_h2_client_new()
324 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_ctx_init()
329 DEBUGASSERT(!ctx->h2); in cf_h2_proxy_ctx_init()
330 memset(&ctx->tunnel, 0, sizeof(ctx->tunnel)); in cf_h2_proxy_ctx_init()
332 Curl_bufq_init(&ctx->inbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS); in cf_h2_proxy_ctx_init()
333 Curl_bufq_init(&ctx->outbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS); in cf_h2_proxy_ctx_init()
335 if(tunnel_stream_init(cf, &ctx->tunnel)) in cf_h2_proxy_ctx_init()
340 failf(data, "Couldn't initialize nghttp2 callbacks"); in cf_h2_proxy_ctx_init()
357 /* The nghttp2 session is not yet setup, do it */ in cf_h2_proxy_ctx_init()
360 failf(data, "Couldn't initialize nghttp2"); in cf_h2_proxy_ctx_init()
368 iv[0].value = Curl_multi_max_concurrent_streams(data->multi); in cf_h2_proxy_ctx_init()
373 rc = nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE, iv, 3); in cf_h2_proxy_ctx_init()
382 rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0, in cf_h2_proxy_ctx_init()
398 CURL_TRC_CF(data, cf, "[0] init proxy ctx -> %d", result); in cf_h2_proxy_ctx_init()
404 return !nghttp2_session_want_read(ctx->h2) && in proxy_h2_should_close_session()
405 !nghttp2_session_want_write(ctx->h2); in proxy_h2_should_close_session()
411 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_nw_out_flush()
416 if(Curl_bufq_is_empty(&ctx->outbufq)) in proxy_h2_nw_out_flush()
419 nwritten = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf, in proxy_h2_nw_out_flush()
423 CURL_TRC_CF(data, cf, "[0] flush nw send buffer(%zu) -> EAGAIN", in proxy_h2_nw_out_flush()
424 Curl_bufq_len(&ctx->outbufq)); in proxy_h2_nw_out_flush()
425 ctx->nw_out_blocked = 1; in proxy_h2_nw_out_flush()
430 return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN; in proxy_h2_nw_out_flush()
435 * This function returns 0 if it succeeds, or -1 and error code will
442 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_process_pending_input()
447 while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) { in proxy_h2_process_pending_input()
449 rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen); in proxy_h2_process_pending_input()
450 CURL_TRC_CF(data, cf, "[0] %zu bytes to nghttp2 -> %zd", blen, rv); in proxy_h2_process_pending_input()
456 return -1; in proxy_h2_process_pending_input()
458 Curl_bufq_skip(&ctx->inbufq, (size_t)rv); in proxy_h2_process_pending_input()
459 if(Curl_bufq_is_empty(&ctx->inbufq)) { in proxy_h2_process_pending_input()
465 "in connection buffer", Curl_bufq_len(&ctx->inbufq)); in proxy_h2_process_pending_input()
475 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_progress_ingress()
480 if(!Curl_bufq_is_empty(&ctx->inbufq)) { in proxy_h2_progress_ingress()
482 Curl_bufq_len(&ctx->inbufq)); in proxy_h2_progress_ingress()
489 while(!ctx->conn_closed && /* not closed the connection */ in proxy_h2_progress_ingress()
490 !ctx->tunnel.closed && /* nor the tunnel */ in proxy_h2_progress_ingress()
491 Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */ in proxy_h2_progress_ingress()
492 !Curl_bufq_is_full(&ctx->tunnel.recvbuf)) { in proxy_h2_progress_ingress()
494 nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result); in proxy_h2_progress_ingress()
495 CURL_TRC_CF(data, cf, "[0] read %zu bytes nw data -> %zd, %d", in proxy_h2_progress_ingress()
496 Curl_bufq_len(&ctx->inbufq), nread, result); in proxy_h2_progress_ingress()
505 ctx->conn_closed = TRUE; in proxy_h2_progress_ingress()
513 if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) { in proxy_h2_progress_ingress()
514 connclose(cf->conn, "GOAWAY received"); in proxy_h2_progress_ingress()
523 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_progress_egress()
526 ctx->nw_out_blocked = 0; in proxy_h2_progress_egress()
527 while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2)) in proxy_h2_progress_egress()
528 rv = nghttp2_session_send(ctx->h2); in proxy_h2_progress_egress()
543 struct cf_h2_proxy_ctx *ctx = cf->ctx; in on_session_send()
552 nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen, in on_session_send()
572 switch(frame->hd.type) { in proxy_h2_fr_print()
576 (int)frame->hd.length, in proxy_h2_fr_print()
577 !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM), in proxy_h2_fr_print()
578 (int)frame->data.padlen); in proxy_h2_fr_print()
583 (int)frame->hd.length, in proxy_h2_fr_print()
584 !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS), in proxy_h2_fr_print()
585 !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)); in proxy_h2_fr_print()
590 (int)frame->hd.length, frame->hd.flags); in proxy_h2_fr_print()
595 (int)frame->hd.length, frame->hd.flags, in proxy_h2_fr_print()
596 frame->rst_stream.error_code); in proxy_h2_fr_print()
599 if(frame->hd.flags & NGHTTP2_FLAG_ACK) { in proxy_h2_fr_print()
603 "FRAME[SETTINGS, len=%d]", (int)frame->hd.length); in proxy_h2_fr_print()
608 (int)frame->hd.length, in proxy_h2_fr_print()
609 !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS)); in proxy_h2_fr_print()
614 (int)frame->hd.length, in proxy_h2_fr_print()
615 frame->hd.flags&NGHTTP2_FLAG_ACK); in proxy_h2_fr_print()
620 size_t len = (frame->goaway.opaque_data_len < s_len)? in proxy_h2_fr_print()
621 frame->goaway.opaque_data_len : s_len-1; in proxy_h2_fr_print()
623 memcpy(scratch, frame->goaway.opaque_data, len); in proxy_h2_fr_print()
626 "last_stream=%d]", frame->goaway.error_code, in proxy_h2_fr_print()
627 scratch, frame->goaway.last_stream_id); in proxy_h2_fr_print()
632 frame->window_update.window_size_increment); in proxy_h2_fr_print()
636 frame->hd.type, (int)frame->hd.length, in proxy_h2_fr_print()
637 frame->hd.flags); in proxy_h2_fr_print()
653 len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1); in proxy_h2_on_frame_send()
655 CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer); in proxy_h2_on_frame_send()
666 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_on_frame_recv()
668 int32_t stream_id = frame->hd.stream_id; in proxy_h2_on_frame_recv()
676 len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1); in proxy_h2_on_frame_recv()
678 CURL_TRC_CF(data, cf, "[%d] <- %s",frame->hd.stream_id, buffer); in proxy_h2_on_frame_recv()
683 /* stream ID zero is for connection-oriented stuff */ in proxy_h2_on_frame_recv()
685 switch(frame->hd.type) { in proxy_h2_on_frame_recv()
693 drain_tunnel(cf, data, &ctx->tunnel); in proxy_h2_on_frame_recv()
697 ctx->goaway = TRUE; in proxy_h2_on_frame_recv()
705 if(stream_id != ctx->tunnel.stream_id) { in proxy_h2_on_frame_recv()
710 switch(frame->hd.type) { in proxy_h2_on_frame_recv()
712 /* nghttp2 guarantees that :status is received, and we store it to in proxy_h2_on_frame_recv()
713 stream->status_code. Fuzzing has proven this can still be reached in proxy_h2_on_frame_recv()
714 without status code having been set. */ in proxy_h2_on_frame_recv()
715 if(!ctx->tunnel.resp) in proxy_h2_on_frame_recv()
719 stream_id, ctx->tunnel.resp->status); in proxy_h2_on_frame_recv()
720 if(!ctx->tunnel.has_final_response) { in proxy_h2_on_frame_recv()
721 if(ctx->tunnel.resp->status / 100 != 1) { in proxy_h2_on_frame_recv()
722 ctx->tunnel.has_final_response = TRUE; in proxy_h2_on_frame_recv()
728 drain_tunnel(cf, data, &ctx->tunnel); in proxy_h2_on_frame_recv()
745 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_on_header()
747 int32_t stream_id = frame->hd.stream_id; in proxy_h2_on_header()
754 if(stream_id != ctx->tunnel.stream_id) { in proxy_h2_on_header()
755 CURL_TRC_CF(data, cf, "[%d] header for non-tunnel stream: " in proxy_h2_on_header()
761 if(frame->hd.type == NGHTTP2_PUSH_PROMISE) in proxy_h2_on_header()
764 if(ctx->tunnel.has_final_response) { in proxy_h2_on_header()
769 if(namelen == sizeof(HTTP_PSEUDO_STATUS) - 1 && in proxy_h2_on_header()
783 resp->prev = ctx->tunnel.resp; in proxy_h2_on_header()
784 ctx->tunnel.resp = resp; in proxy_h2_on_header()
786 stream_id, ctx->tunnel.resp->status); in proxy_h2_on_header()
790 if(!ctx->tunnel.resp) in proxy_h2_on_header()
793 result = Curl_dynhds_add(&ctx->tunnel.resp->headers, in proxy_h2_on_header()
813 struct cf_h2_proxy_ctx *ctx = cf->ctx; in tunnel_send_callback()
829 DEBUGASSERT(ts == &ctx->tunnel); in tunnel_send_callback()
831 nread = Curl_bufq_read(&ts->sendbuf, buf, length, &result); in tunnel_send_callback()
837 if(ts->closed && Curl_bufq_is_empty(&ts->sendbuf)) in tunnel_send_callback()
840 CURL_TRC_CF(data, cf, "[%d] tunnel_send_callback -> %zd", in tunnel_send_callback()
841 ts->stream_id, nread); in tunnel_send_callback()
850 struct cf_h2_proxy_ctx *ctx = cf->ctx; in tunnel_recv_callback()
858 if(stream_id != ctx->tunnel.stream_id) in tunnel_recv_callback()
861 nwritten = Curl_bufq_write(&ctx->tunnel.recvbuf, mem, len, &result); in tunnel_recv_callback()
876 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_on_stream_close()
882 if(stream_id != ctx->tunnel.stream_id) in proxy_h2_on_stream_close()
887 ctx->tunnel.closed = TRUE; in proxy_h2_on_stream_close()
888 ctx->tunnel.error = error_code; in proxy_h2_on_stream_close()
905 int32_t stream_id = -1; in proxy_h2_submit()
953 struct cf_h2_proxy_ctx *ctx = cf->ctx; in submit_CONNECT()
964 infof(data, "Establish HTTP/2 proxy tunnel to %s", req->authority); in submit_CONNECT()
966 result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req, in submit_CONNECT()
970 ts->stream_id, nghttp2_strerror(ts->stream_id)); in submit_CONNECT()
989 DEBUGASSERT(ts->resp); in inspect_response()
990 if(ts->resp->status/100 == 2) { in inspect_response()
991 infof(data, "CONNECT tunnel established, response %d", ts->resp->status); in inspect_response()
996 if(ts->resp->status == 401) { in inspect_response()
997 auth_reply = Curl_dynhds_cget(&ts->resp->headers, "WWW-Authenticate"); in inspect_response()
999 else if(ts->resp->status == 407) { in inspect_response()
1000 auth_reply = Curl_dynhds_cget(&ts->resp->headers, "Proxy-Authenticate"); in inspect_response()
1005 auth_reply->value); in inspect_response()
1006 result = Curl_http_input_auth(data, ts->resp->status == 407, in inspect_response()
1007 auth_reply->value); in inspect_response()
1010 if(data->req.newurl) { in inspect_response()
1012 Curl_safefree(data->req.newurl); in inspect_response()
1026 struct cf_h2_proxy_ctx *ctx = cf->ctx; in H2_CONNECT()
1030 DEBUGASSERT(ts->authority); in H2_CONNECT()
1032 switch(ts->state) { in H2_CONNECT()
1035 CURL_TRC_CF(data, cf, "[0] CONNECT start for %s", ts->authority); in H2_CONNECT()
1052 if(ts->has_final_response) { in H2_CONNECT()
1062 DEBUGASSERT(ts->has_final_response); in H2_CONNECT()
1078 } while(ts->state == H2_TUNNEL_INIT); in H2_CONNECT()
1081 if(result || ctx->tunnel.closed) in H2_CONNECT()
1090 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_connect()
1094 struct tunnel_stream *ts = &ctx->tunnel; in cf_h2_proxy_connect()
1096 if(cf->connected) { in cf_h2_proxy_connect()
1102 if(!cf->next->connected) { in cf_h2_proxy_connect()
1103 result = Curl_conn_cf_connect(cf->next, data, blocking, done); in cf_h2_proxy_connect()
1111 if(!ctx->h2) { in cf_h2_proxy_connect()
1116 DEBUGASSERT(ts->authority); in cf_h2_proxy_connect()
1131 *done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED); in cf_h2_proxy_connect()
1133 cf->connected = TRUE; in cf_h2_proxy_connect()
1135 Curl_req_soft_reset(&data->req, data); in cf_h2_proxy_connect()
1144 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_close()
1153 if(cf->next) in cf_h2_proxy_close()
1154 cf->next->cft->do_close(cf->next, data); in cf_h2_proxy_close()
1160 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_destroy()
1165 cf->ctx = NULL; in cf_h2_proxy_destroy()
1172 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_data_pending()
1173 if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) || in cf_h2_proxy_data_pending()
1174 (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED && in cf_h2_proxy_data_pending()
1175 !Curl_bufq_is_empty(&ctx->tunnel.recvbuf))) in cf_h2_proxy_data_pending()
1177 return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE; in cf_h2_proxy_data_pending()
1184 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_adjust_pollset()
1189 if(ctx->h2 && (want_recv || want_send)) { in cf_h2_proxy_adjust_pollset()
1194 c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2); in cf_h2_proxy_adjust_pollset()
1195 s_exhaust = ctx->tunnel.stream_id >= 0 && in cf_h2_proxy_adjust_pollset()
1197 ctx->h2, ctx->tunnel.stream_id); in cf_h2_proxy_adjust_pollset()
1200 (!c_exhaust && nghttp2_session_want_write(ctx->h2)); in cf_h2_proxy_adjust_pollset()
1211 struct cf_h2_proxy_ctx *ctx = cf->ctx; in h2_handle_tunnel_close()
1214 if(ctx->tunnel.error == NGHTTP2_REFUSED_STREAM) { in h2_handle_tunnel_close()
1216 "connection", ctx->tunnel.stream_id); in h2_handle_tunnel_close()
1217 connclose(cf->conn, "REFUSED_STREAM"); /* don't use this anymore */ in h2_handle_tunnel_close()
1219 return -1; in h2_handle_tunnel_close()
1221 else if(ctx->tunnel.error != NGHTTP2_NO_ERROR) { in h2_handle_tunnel_close()
1223 ctx->tunnel.stream_id, nghttp2_http2_strerror(ctx->tunnel.error), in h2_handle_tunnel_close()
1224 ctx->tunnel.error); in h2_handle_tunnel_close()
1226 return -1; in h2_handle_tunnel_close()
1228 else if(ctx->tunnel.reset) { in h2_handle_tunnel_close()
1229 failf(data, "HTTP/2 stream %u was reset", ctx->tunnel.stream_id); in h2_handle_tunnel_close()
1231 return -1; in h2_handle_tunnel_close()
1236 CURL_TRC_CF(data, cf, "[%d] handle_tunnel_close -> %zd, %d", in h2_handle_tunnel_close()
1237 ctx->tunnel.stream_id, rv, *err); in h2_handle_tunnel_close()
1244 struct cf_h2_proxy_ctx *ctx = cf->ctx; in tunnel_recv()
1245 ssize_t nread = -1; in tunnel_recv()
1248 if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) { in tunnel_recv()
1249 nread = Curl_bufq_read(&ctx->tunnel.recvbuf, in tunnel_recv()
1257 if(ctx->tunnel.closed) { in tunnel_recv()
1260 else if(ctx->tunnel.reset || in tunnel_recv()
1261 (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) || in tunnel_recv()
1262 (ctx->goaway && ctx->last_stream_id < ctx->tunnel.stream_id)) { in tunnel_recv()
1264 nread = -1; in tunnel_recv()
1269 nread = -1; in tunnel_recv()
1273 CURL_TRC_CF(data, cf, "[%d] tunnel_recv(len=%zu) -> %zd, %d", in tunnel_recv()
1274 ctx->tunnel.stream_id, len, nread, *err); in tunnel_recv()
1282 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_recv()
1283 ssize_t nread = -1; in cf_h2_proxy_recv()
1287 if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { in cf_h2_proxy_recv()
1289 return -1; in cf_h2_proxy_recv()
1293 if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) { in cf_h2_proxy_recv()
1303 ctx->tunnel.stream_id, nread); in cf_h2_proxy_recv()
1304 nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread); in cf_h2_proxy_recv()
1314 ctx->tunnel.stream_id); in cf_h2_proxy_recv()
1315 drain_tunnel(cf, data, &ctx->tunnel); in cf_h2_proxy_recv()
1319 nread = -1; in cf_h2_proxy_recv()
1323 if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && in cf_h2_proxy_recv()
1327 drain_tunnel(cf, data, &ctx->tunnel); in cf_h2_proxy_recv()
1329 CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %zd %d", in cf_h2_proxy_recv()
1330 ctx->tunnel.stream_id, len, nread, *err); in cf_h2_proxy_recv()
1339 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_send()
1346 if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { in cf_h2_proxy_send()
1348 return -1; in cf_h2_proxy_send()
1352 if(ctx->tunnel.closed) { in cf_h2_proxy_send()
1353 nwritten = -1; in cf_h2_proxy_send()
1357 else if(ctx->tunnel.upload_blocked_len) { in cf_h2_proxy_send()
1360 DEBUGASSERT(len >= ctx->tunnel.upload_blocked_len); in cf_h2_proxy_send()
1361 if(len < ctx->tunnel.upload_blocked_len) { in cf_h2_proxy_send()
1366 nwritten = -1; in cf_h2_proxy_send()
1369 nwritten = (ssize_t)ctx->tunnel.upload_blocked_len; in cf_h2_proxy_send()
1370 ctx->tunnel.upload_blocked_len = 0; in cf_h2_proxy_send()
1374 nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err); in cf_h2_proxy_send()
1382 if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { in cf_h2_proxy_send()
1384 rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id); in cf_h2_proxy_send()
1387 nwritten = -1; in cf_h2_proxy_send()
1395 nwritten = -1; in cf_h2_proxy_send()
1399 /* Call the nghttp2 send loop and flush to write ALL buffered data, in cf_h2_proxy_send()
1407 nwritten = -1; in cf_h2_proxy_send()
1410 else if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { in cf_h2_proxy_send()
1411 /* although we wrote everything that nghttp2 wants to send now, in cf_h2_proxy_send()
1419 * exhaustion. Data is left in our stream buffer, or nghttp2's internal in cf_h2_proxy_send()
1422 ctx->h2, ctx->tunnel.stream_id); in cf_h2_proxy_send()
1430 "window is exhausted", ctx->tunnel.stream_id); in cf_h2_proxy_send()
1436 ctx->tunnel.upload_blocked_len = nwritten; in cf_h2_proxy_send()
1439 ctx->tunnel.stream_id, len, in cf_h2_proxy_send()
1440 nghttp2_session_get_remote_window_size(ctx->h2), rwin, in cf_h2_proxy_send()
1442 drain_tunnel(cf, data, &ctx->tunnel); in cf_h2_proxy_send()
1444 nwritten = -1; in cf_h2_proxy_send()
1448 /* nghttp2 thinks this session is done. If the stream has not been in cf_h2_proxy_send()
1450 if(ctx->tunnel.closed) { in cf_h2_proxy_send()
1452 nwritten = -1; in cf_h2_proxy_send()
1457 nwritten = -1; in cf_h2_proxy_send()
1462 if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && in cf_h2_proxy_send()
1466 drain_tunnel(cf, data, &ctx->tunnel); in cf_h2_proxy_send()
1468 CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %zd, %d, " in cf_h2_proxy_send()
1469 "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)", in cf_h2_proxy_send()
1470 ctx->tunnel.stream_id, len, nwritten, *err, in cf_h2_proxy_send()
1472 ctx->h2, ctx->tunnel.stream_id), in cf_h2_proxy_send()
1473 nghttp2_session_get_remote_window_size(ctx->h2), in cf_h2_proxy_send()
1474 Curl_bufq_len(&ctx->tunnel.sendbuf), in cf_h2_proxy_send()
1475 Curl_bufq_len(&ctx->outbufq)); in cf_h2_proxy_send()
1484 struct cf_h2_proxy_ctx *ctx = cf->ctx; in proxy_h2_connisalive()
1488 if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) in proxy_h2_connisalive()
1496 ssize_t nread = -1; in proxy_h2_connisalive()
1499 nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result); in proxy_h2_connisalive()
1500 if(nread != -1) { in proxy_h2_connisalive()
1521 struct cf_h2_proxy_ctx *ctx = cf->ctx; in cf_h2_proxy_is_alive()
1526 result = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending)); in cf_h2_proxy_is_alive()
1527 CURL_TRC_CF(data, cf, "[0] conn alive -> %d, input_pending=%d", in cf_h2_proxy_is_alive()
1534 "H2-PROXY",