From 02f8de65165ef161a21ace25da3652e1fb13b99b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 9 Feb 2020 15:28:03 +0100 Subject: [PATCH] altsvc: keep a copy of the file name to survive handle reset The alt-svc cache survives a call to curl_easy_reset fine, but the file name to use for saving the cache was cleared. Now the alt-svc cache has a copy of the file name to survive handle resets. Added test 1908 to verify. Reported-by: Craig Andrews Fixes #4898 Closes #4902 --- docs/libcurl/curl_easy_reset.3 | 5 ++- lib/altsvc.c | 17 +++++++- tests/data/Makefile.inc | 1 + tests/data/test1908 | 71 ++++++++++++++++++++++++++++++++++ tests/libtest/Makefile.inc | 6 ++- tests/libtest/lib1908.c | 47 ++++++++++++++++++++++ 6 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 tests/data/test1908 create mode 100644 tests/libtest/lib1908.c diff --git a/docs/libcurl/curl_easy_reset.3 b/docs/libcurl/curl_easy_reset.3 index 539f9c716..3c844c7dd 100644 --- a/docs/libcurl/curl_easy_reset.3 +++ b/docs/libcurl/curl_easy_reset.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -33,7 +33,8 @@ default values. This puts back the handle to the same state as it was in when it was just created with \fIcurl_easy_init(3)\fP. It does not change the following information kept in the handle: live -connections, the Session ID cache, the DNS cache, the cookies and shares. +connections, the Session ID cache, the DNS cache, the cookies, the shares or +the alt-svc cache. .SH AVAILABILITY This function was added in libcurl 7.12.1 .SH RETURN VALUE diff --git a/lib/altsvc.c b/lib/altsvc.c index 93cc302bd..c05562985 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -185,7 +185,16 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) { CURLcode result = CURLE_OK; char *line = NULL; - FILE *fp = fopen(file, FOPEN_READTEXT); + FILE *fp; + + /* we need a private copy of the file name so that the altsvc cache file + name survives an easy handle reset */ + free(asi->filename); + asi->filename = strdup(file); + if(!asi->filename) + return CURLE_OUT_OF_MEMORY; + + fp = fopen(file, FOPEN_READTEXT); if(fp) { line = malloc(MAX_ALTSVC_LINE); if(!line) @@ -206,6 +215,7 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) return result; fail: + Curl_safefree(asi->filename); free(line); fclose(fp); return CURLE_OUT_OF_MEMORY; @@ -299,6 +309,7 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) n = e->next; altsvc_free(as); } + free(altsvc->filename); free(altsvc); } } @@ -317,6 +328,10 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file) /* no cache activated */ return CURLE_OK; + /* if not new name is given, use the one we stored from the load */ + if(!file && altsvc->filename) + file = altsvc->filename; + if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0]) /* marked as read-only, no file or zero length file name */ return CURLE_OK; diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 5fbe18396..be55f0460 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -192,6 +192,7 @@ test1700 test1701 test1702 \ test1800 test1801 \ \ test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 \ +test1908 \ \ test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \ diff --git a/tests/data/test1908 b/tests/data/test1908 new file mode 100644 index 000000000..de34d0ee2 --- /dev/null +++ b/tests/data/test1908 @@ -0,0 +1,71 @@ + + + +CURLINFO_EFFECTIVE_URL + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Funny-head: yesyes swsclose +Content-Length: 0 +alt-svc: h2="3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example:443"; ma=315360000; persist=1 + + + + +# Client-side + + +http + + +# require debug so that alt-svc can work over plain old HTTP + +alt-svc +debug + + +alt-svc cache save after resetting the handle + + +# make debug-curl accept Alt-Svc over plain HTTP +CURL_ALTSVC_HTTP="yeah" + + +lib1908 + + + +%HOSTIP:%HTTPPORT/1908 + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* + + +GET /1908 HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Accept: */* + + + +# strip out the (dynamic) expire date from the file so that the rest +# matches +s/\"([^\"]*)\"/TIMESTAMP/ + + +# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html +# This file was generated by libcurl! Edit at your own risk. +h1 127.0.0.1 8990 h2 3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example 443 TIMESTAMP 1 0 + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 374a66747..95ef8309b 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -33,7 +33,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \ lib1558 lib1559 lib1560 lib1564 lib1565 \ lib1591 lib1592 lib1593 lib1594 lib1596 \ - lib1900 lib1905 lib1906 lib1907 \ + lib1900 lib1905 lib1906 lib1907 lib1908 \ lib2033 chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \ @@ -578,6 +578,10 @@ lib1907_SOURCES = lib1907.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1907_LDADD = $(TESTUTIL_LIBS) lib1907_CPPFLAGS = $(AM_CPPFLAGS) +lib1908_SOURCES = lib1908.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1908_LDADD = $(TESTUTIL_LIBS) +lib1908_CPPFLAGS = $(AM_CPPFLAGS) + lib2033_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib2033_LDADD = $(TESTUTIL_LIBS) lib2033_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_PIPELINING diff --git a/tests/libtest/lib1908.c b/tests/libtest/lib1908.c new file mode 100644 index 000000000..bacbc9710 --- /dev/null +++ b/tests/libtest/lib1908.c @@ -0,0 +1,47 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2013 - 2020, Linus Nielsen Feltzing, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "test.h" + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +int test(char *URL) +{ + CURLcode ret = CURLE_OK; + CURL *hnd; + start_test_timing(); + + curl_global_init(CURL_GLOBAL_ALL); + + hnd = curl_easy_init(); + if(hnd) { + curl_easy_setopt(hnd, CURLOPT_URL, URL); + curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(hnd, CURLOPT_ALTSVC, "log/altsvc-1908"); + ret = curl_easy_perform(hnd); + curl_easy_reset(hnd); + curl_easy_cleanup(hnd); + } + curl_global_cleanup(); + return (int)ret; +}