mirror of
https://github.com/moparisthebest/curl
synced 2024-08-13 17:03:50 -04:00
altsvc: make saving the cache an atomic operation
... by writing the file to temp name then rename to the final when done. Assisted-by: Jay Satiro Fixes #4936 Closes #4942
This commit is contained in:
parent
330f133224
commit
14916a82e2
45
lib/altsvc.c
45
lib/altsvc.c
@ -34,6 +34,8 @@
|
|||||||
#include "parsedate.h"
|
#include "parsedate.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
|
#include "rand.h"
|
||||||
|
#include "rename.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -317,12 +319,15 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
|
|||||||
/*
|
/*
|
||||||
* Curl_altsvc_save() writes the altsvc cache to a file.
|
* Curl_altsvc_save() writes the altsvc cache to a file.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
|
CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
||||||
|
struct altsvcinfo *altsvc, const char *file)
|
||||||
{
|
{
|
||||||
struct curl_llist_element *e;
|
struct curl_llist_element *e;
|
||||||
struct curl_llist_element *n;
|
struct curl_llist_element *n;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
char *tempstore;
|
||||||
|
unsigned char randsuffix[9];
|
||||||
|
|
||||||
if(!altsvc)
|
if(!altsvc)
|
||||||
/* no cache activated */
|
/* no cache activated */
|
||||||
@ -335,20 +340,36 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
|
|||||||
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
|
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
|
||||||
/* marked as read-only, no file or zero length file name */
|
/* marked as read-only, no file or zero length file name */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
out = fopen(file, FOPEN_WRITETEXT);
|
|
||||||
|
if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
|
tempstore = aprintf("%s.%s.tmp", file, randsuffix);
|
||||||
|
if(!tempstore)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
out = fopen(tempstore, FOPEN_WRITETEXT);
|
||||||
if(!out)
|
if(!out)
|
||||||
return CURLE_WRITE_ERROR;
|
result = CURLE_WRITE_ERROR;
|
||||||
fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
|
else {
|
||||||
"# This file was generated by libcurl! Edit at your own risk.\n",
|
fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
|
||||||
out);
|
"# This file was generated by libcurl! Edit at your own risk.\n",
|
||||||
for(e = altsvc->list.head; e; e = n) {
|
out);
|
||||||
struct altsvc *as = e->ptr;
|
for(e = altsvc->list.head; e; e = n) {
|
||||||
n = e->next;
|
struct altsvc *as = e->ptr;
|
||||||
result = altsvc_out(as, out);
|
n = e->next;
|
||||||
|
result = altsvc_out(as, out);
|
||||||
|
if(result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(out);
|
||||||
|
if(!result && Curl_rename(tempstore, file))
|
||||||
|
result = CURLE_WRITE_ERROR;
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
break;
|
unlink(tempstore);
|
||||||
}
|
}
|
||||||
fclose(out);
|
free(tempstore);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -59,7 +59,8 @@ struct altsvcinfo {
|
|||||||
const char *Curl_alpnid2str(enum alpnid id);
|
const char *Curl_alpnid2str(enum alpnid id);
|
||||||
struct altsvcinfo *Curl_altsvc_init(void);
|
struct altsvcinfo *Curl_altsvc_init(void);
|
||||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
|
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
|
||||||
CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
|
CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
||||||
|
struct altsvcinfo *asi, const char *file);
|
||||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
|
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
|
||||||
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
|
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
|
||||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||||
@ -70,9 +71,9 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|||||||
enum alpnid srcalpnid, const char *srchost,
|
enum alpnid srcalpnid, const char *srchost,
|
||||||
int srcport,
|
int srcport,
|
||||||
struct altsvc **dstentry,
|
struct altsvc **dstentry,
|
||||||
int versions); /* one or more CURLALTSVC_H* bits */
|
const int versions); /* CURLALTSVC_H* bits */
|
||||||
#else
|
#else
|
||||||
/* disabled */
|
/* disabled */
|
||||||
#define Curl_altsvc_save(a,b)
|
#define Curl_altsvc_save(a,b,c)
|
||||||
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
||||||
#endif /* HEADER_CURL_ALTSVC_H */
|
#endif /* HEADER_CURL_ALTSVC_H */
|
||||||
|
@ -380,7 +380,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
|
|||||||
Curl_safefree(data->state.ulbuf);
|
Curl_safefree(data->state.ulbuf);
|
||||||
Curl_flush_cookies(data, TRUE);
|
Curl_flush_cookies(data, TRUE);
|
||||||
#ifdef USE_ALTSVC
|
#ifdef USE_ALTSVC
|
||||||
Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]);
|
Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
|
||||||
Curl_altsvc_cleanup(data->asi);
|
Curl_altsvc_cleanup(data->asi);
|
||||||
data->asi = NULL;
|
data->asi = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -124,7 +124,7 @@ UNITTEST_START
|
|||||||
}
|
}
|
||||||
fail_unless(asi->num == 10, "wrong number of entries");
|
fail_unless(asi->num == 10, "wrong number of entries");
|
||||||
|
|
||||||
Curl_altsvc_save(asi, outname);
|
Curl_altsvc_save(curl, asi, outname);
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
fail:
|
fail:
|
||||||
|
Loading…
Reference in New Issue
Block a user