#define DYN_PAUSE_BUFFER (64 * 1024 * 1024)
#define DYN_HAXPROXY 2048
#define DYN_HTTP_REQUEST (1024*1024)
-#define DYN_H2_HEADERS (128*1024)
-#define DYN_H2_TRAILERS (128*1024)
#define DYN_APRINTF 8000000
#define DYN_RTSP_REQ_HEADER (64*1024)
#define DYN_TRAILERS (64*1024)
|| IS_HTTPS_PROXY(conn->http_proxy.proxytype)
#endif
)
- && conn->httpversion != 20) {
+ && conn->httpversion < 20) {
/* Make sure this doesn't send more body bytes than what the max send
speed says. The request bytes do not count to the max speed.
*/
if(!req->path)
goto out;
}
- Curl_dynhds_init(&req->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&req->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
if(result)
goto out;
- Curl_dynhds_init(&req->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&req->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
if(!resp->description)
goto out;
}
- Curl_dynhds_init(&resp->headers, 0, DYN_H2_HEADERS);
- Curl_dynhds_init(&resp->trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&resp->headers, 0, DYN_HTTP_REQUEST);
+ Curl_dynhds_init(&resp->trailers, 0, DYN_HTTP_REQUEST);
result = CURLE_OK;
out:
H2_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE);
Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
H2_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- Curl_dynhds_init(&stream->resp_trailers, 0, DYN_H2_TRAILERS);
+ Curl_dynhds_init(&stream->resp_trailers, 0, DYN_HTTP_REQUEST);
stream->resp_hds_len = 0;
stream->bodystarted = FALSE;
stream->status_code = -1;
/* Call the nghttp2 send loop and flush to write ALL buffered data,
* headers and/or request body completely out to the network */
result = h2_progress_egress(cf, data);
- if(result == CURLE_AGAIN) {
+ /* if the stream has been closed in egress handling (nghttp2 does that
+ * when it does not like the headers, for example */
+ if(stream && stream->closed) {
+ nwritten = http2_handle_stream_close(cf, data, stream, err);
+ goto out;
+ }
+ else if(result == CURLE_AGAIN) {
blocked = 1;
}
else if(result) {
nwritten = -1;
goto out;
}
- else if(!Curl_bufq_is_empty(&stream->sendbuf)) {
+ else if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) {
/* although we wrote everything that nghttp2 wants to send now,
* there is data left in our stream send buffer unwritten. This may
* be due to the stream's HTTP/2 flow window being exhausted. */
blocked = 1;
}
- if(blocked) {
+ if(stream && blocked) {
/* Unable to send all data, due to connection blocked or H2 window
* exhaustion. Data is left in our stream buffer, or nghttp2's internal
* frame buffer or our network out buffer. */
*err = result;
sent = -1;
}
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send(len=%zu) -> %zd, %d",
+ stream? stream->id : -1, len, sent, *err));
CF_DATA_RESTORE(cf, save);
return sent;
}
def _class_scope(self, env, httpd, nghttpx):
if env.have_h3():
nghttpx.start_if_needed()
+ env.make_data_file(indir=env.gen_dir, fname="data-10m", fsize=10*1024*1024)
httpd.clear_extra_configs()
httpd.reload()
'--digest', '--user', 'test:test'
])
r.check_response(http_status=200)
+
+ # PUT data, digest auth large pw
+ @pytest.mark.parametrize("proto", ['h2', 'h3'])
+ def test_14_04_digest_large_pw(self, env: Env, httpd, nghttpx, repeat, proto):
+ if proto == 'h3' and not env.have_h3():
+ pytest.skip("h3 not supported")
+ data='0123456789'
+ password = 'x' * 65535
+ curl = CurlClient(env=env)
+ url = f'https://{env.authority_for(env.domain1, proto)}/restricted/digest/data.json'
+ r = curl.http_upload(urls=[url], data=data, alpn_proto=proto, extra_args=[
+ '--digest', '--user', f'test:{password}'
+ ])
+ # digest does not submit the password, but a hash of it, so all
+ # works and, since the pw is not correct, we get a 401
+ r.check_response(http_status=401)
+
+ # PUT data, basic auth large pw
+ @pytest.mark.parametrize("proto", ['h2', 'h3'])
+ def test_14_05_basic_large_pw(self, env: Env, httpd, nghttpx, repeat, proto):
+ if proto == 'h3' and not env.have_h3():
+ pytest.skip("h3 not supported")
+ # just large enought that nghttp2 will submit
+ password = 'x' * (47 * 1024)
+ fdata = os.path.join(env.gen_dir, 'data-10m')
+ curl = CurlClient(env=env)
+ url = f'https://{env.authority_for(env.domain1, proto)}/restricted/digest/data.json'
+ r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, extra_args=[
+ '--basic', '--user', f'test:{password}'
+ ])
+ # but apache denies on length limit
+ r.check_response(http_status=431)
+
+ # PUT data, basic auth with very large pw
+ @pytest.mark.parametrize("proto", ['h2', 'h3'])
+ def test_14_06_basic_very_large_pw(self, env: Env, httpd, nghttpx, repeat, proto):
+ if proto == 'h3' and not env.have_h3():
+ pytest.skip("h3 not supported")
+ data='0123456789'
+ password = 'x' * (64 * 1024)
+ fdata = os.path.join(env.gen_dir, 'data-10m')
+ curl = CurlClient(env=env)
+ url = f'https://{env.authority_for(env.domain1, proto)}/restricted/digest/data.json'
+ r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, extra_args=[
+ '--basic', '--user', f'test:{password}'
+ ])
+ # request was never sent
+ r.check_response(exitcode=55, http_status=0)