mime: fix unpausing of readers
No binary (build failed)
—
(log yok)
| @@ -1165,7 +1165,8 @@ CURLcode curl_easy_pause(CURL *d, int action) | |
| send_paused = Curl_xfer_send_is_paused(data); | |
| send_paused_new = (action & CURLPAUSE_SEND); | |
| - | if(send_paused != send_paused_new) { |
| + | if((send_paused != send_paused_new) || |
| + | (send_paused_new != Curl_creader_is_paused(data))) { |
| changed = TRUE; | |
| result = Curl_1st_err(result, Curl_xfer_pause_send(data, send_paused_new)); | |
| } | |
| @@ -1442,6 +1442,7 @@ CURLcode Curl_creader_unpause(struct Curl_easy *data) | |
| while(reader) { | |
| result = reader->crt->cntrl(data, reader, CURL_CRCNTRL_UNPAUSE); | |
| + | CURL_TRC_READ(data, "unpausing %s -> %d", reader->crt->name, result); |
| if(result) | |
| break; | |
| reader = reader->next; | |
| @@ -671,6 +671,25 @@ class TestUpload: | |
| ]) | |
| r.check_stats(count=1, http_status=200, exitcode=0) | |
| + | @pytest.mark.parametrize("proto", ['http/1.1']) |
| + | def test_07_63_upload_exp100_paused(self, env: Env, httpd, nghttpx, proto): |
| + | read_delay = 1 |
| + | url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-0]'\ |
| + | f'&read_delay={read_delay}s' |
| + | upload_size = 128 * 1024 |
| + | client = LocalClient(name='cli_hx_upload', env=env) |
| + | if not client.exists(): |
| + | pytest.skip(f'example client not built: {client.name}') |
| + | r = client.run(args=[ |
| + | '-n', '1', |
| + | '-S', f'{upload_size}', |
| + | '-P', '1', |
| + | '-M', 'MIME', |
| + | '-r', f'{env.domain1}:{env.port_for(proto)}:127.0.0.1', |
| + | '-V', proto, url |
| + | ]) |
| + | r.check_exit_code(0) |
| + | |
| # nghttpx is the only server we have that supports TLS early data and | |
| # has a limit of 16k it announces | |
| @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx") | |
| @@ -575,11 +575,13 @@ class Httpd: | |
| return | |
| local_dir = os.path.dirname(inspect.getfile(Httpd)) | |
| out_dir = os.path.join(self.env.gen_dir, 'mod_curltest') | |
| + | in_source = os.path.join(local_dir, 'mod_curltest/mod_curltest.c') |
| out_source = os.path.join(out_dir, 'mod_curltest.c') | |
| if not os.path.exists(out_dir): | |
| os.mkdir(out_dir) | |
| - | if not os.path.exists(out_source): |
| - | shutil.copy(os.path.join(local_dir, 'mod_curltest/mod_curltest.c'), out_source) |
| + | if not os.path.exists(out_source) or \ |
| + | os.stat(in_source).st_mtime > os.stat(out_source).st_mtime: |
| + | shutil.copy(in_source, out_source) |
| p = subprocess.run([ | |
| self.env.apxs, '-c', out_source | |
| ], capture_output=True, cwd=out_dir) | |
| @@ -188,6 +188,7 @@ static int curltest_echo_handler(request_rec *r) | |
| char buffer[8192]; | |
| const char *ct; | |
| apr_off_t die_after_len = -1, total_read_len = 0; | |
| + | apr_time_t read_delay = 0; |
| int just_die = 0, die_after_100 = 0; | |
| long l; | |
| @@ -221,6 +222,12 @@ static int curltest_echo_handler(request_rec *r) | |
| die_after_100 = 1; | |
| continue; | |
| } | |
| + | else if(!strcmp("read_delay", arg)) { |
| + | rv = duration_parse(&read_delay, val, "s"); |
| + | if(APR_SUCCESS == rv) { |
| + | continue; |
| + | } |
| + | } |
| } | |
| } | |
| } | |
| @@ -258,6 +265,12 @@ static int curltest_echo_handler(request_rec *r) | |
| apr_table_setn(r->headers_out, "Request-TE", | |
| apr_table_get(r->headers_in, "TE")); | |
| + | if(read_delay) { |
| + | ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, |
| + | "put_handler: read_delay"); |
| + | apr_sleep(read_delay); |
| + | } |
| + | |
| bb = apr_brigade_create(r->pool, c->bucket_alloc); | |
| /* copy any request body into the response */ | |
| rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); | |
| @@ -637,6 +650,8 @@ static int curltest_put_handler(request_rec *r) | |
| ap_set_content_type(r, ct ? ct : "text/plain"); | |
| if(read_delay) { | |
| + | ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, |
| + | "put_handler: read_delay"); |
| apr_sleep(read_delay); | |
| } | |
| bb = apr_brigade_create(r->pool, c->bucket_alloc); | |
| @@ -33,6 +33,7 @@ struct transfer_u { | |
| CURL *easy; | |
| const char *method; | |
| char filename[128]; | |
| + | curl_mime *mime; |
| FILE *out; | |
| curl_off_t send_total; | |
| curl_off_t recv_size; | |
| @@ -158,18 +159,28 @@ static int setup_hx_upload(CURL *hnd, const char *url, struct transfer_u *t, | |
| if(use_earlydata) | |
| curl_easy_setopt(hnd, CURLOPT_SSL_OPTIONS, CURLSSLOPT_EARLYDATA); | |
| - | if(!t->method || !strcmp("PUT", t->method)) |
| - | curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); |
| - | else if(!strcmp("POST", t->method)) |
| - | curl_easy_setopt(hnd, CURLOPT_POST, 1L); |
| + | if(!strcmp("MIME", t->method)) { |
| + | curl_mimepart *part; |
| + | t->mime = curl_mime_init(hnd); |
| + | part = curl_mime_addpart(t->mime); |
| + | curl_mime_name(part, "file"); |
| + | curl_mime_data_cb(part, -1, my_read_cb, NULL, NULL, t); |
| + | curl_easy_setopt(hnd, CURLOPT_MIMEPOST, t->mime); |
| + | } |
| else { | |
| - | curl_mfprintf(stderr, "unsupported method '%s'\n", t->method); |
| - | return 1; |
| + | if(!t->method || !strcmp("PUT", t->method)) |
| + | curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); |
| + | else if(!strcmp("POST", t->method)) |
| + | curl_easy_setopt(hnd, CURLOPT_POST, 1L); |
| + | else { |
| + | curl_mfprintf(stderr, "unsupported method '%s'\n", t->method); |
| + | return 1; |
| + | } |
| + | curl_easy_setopt(hnd, CURLOPT_READFUNCTION, my_read_cb); |
| + | curl_easy_setopt(hnd, CURLOPT_READDATA, t); |
| + | if(announce_length) |
| + | curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, t->send_total); |
| } | |
| - | curl_easy_setopt(hnd, CURLOPT_READFUNCTION, my_read_cb); |
| - | curl_easy_setopt(hnd, CURLOPT_READDATA, t); |
| - | if(announce_length) |
| - | curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, t->send_total); |
| curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L); | |
| curl_easy_setopt(hnd, CURLOPT_XFERINFOFUNCTION, my_progress_u_cb); | |
| @@ -488,6 +499,7 @@ static CURLcode test_cli_hx_upload(const char *URL) | |
| } while(active_transfers); /* as long as we have transfers going */ | |
| + | curl_mfprintf(stderr, "all transfers done, cleanup multi\n"); |
| curl_multi_cleanup(multi_handle); | |
| } | |
| @@ -501,9 +513,13 @@ static CURLcode test_cli_hx_upload(const char *URL) | |
| curl_easy_cleanup(t->easy); | |
| t->easy = NULL; | |
| } | |
| + | if(t->mime) { |
| + | curl_mime_free(t->mime); |
| + | } |
| } | |
| free(transfer_u); | |
| curl_share_cleanup(share); | |
| + | curl_slist_free_all(host); |
| return CURLE_OK; | |
| } | |