summaryrefslogtreecommitdiffstats
path: root/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'http.c')
-rw-r--r--http.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/http.c b/http.c
index 4d59f11ad2..bc64e57799 100644
--- a/http.c
+++ b/http.c
@@ -19,6 +19,7 @@
#include "string-list.h"
#include "object-file.h"
#include "object-store-ll.h"
+#include "tempfile.h"
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
static int trace_curl_data = 1;
@@ -2232,17 +2233,19 @@ static int http_request_reauth(const char *url,
case HTTP_REQUEST_STRBUF:
strbuf_reset(result);
break;
- case HTTP_REQUEST_FILE:
- if (fflush(result)) {
+ case HTTP_REQUEST_FILE: {
+ FILE *f = result;
+ if (fflush(f)) {
error_errno("unable to flush a file");
return HTTP_START_FAILED;
}
- rewind(result);
- if (ftruncate(fileno(result), 0) < 0) {
+ rewind(f);
+ if (ftruncate(fileno(f), 0) < 0) {
error_errno("unable to truncate a file");
return HTTP_START_FAILED;
}
break;
+ }
default:
BUG("Unknown http_request target");
}
@@ -2330,8 +2333,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
strbuf_addf(&buf, "objects/pack/pack-%s.idx", hash_to_hex(hash));
url = strbuf_detach(&buf, NULL);
- strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(hash));
- tmp = strbuf_detach(&buf, NULL);
+ /*
+ * Don't put this into packs/, since it's just temporary and we don't
+ * want to confuse it with our local .idx files. We'll generate our
+ * own index if we choose to download the matching packfile.
+ *
+ * It's tempting to use xmks_tempfile() here, but it's important that
+ * the file not exist, otherwise http_get_file() complains. So we
+ * create a filename that should be unique, and then just register it
+ * as a tempfile so that it will get cleaned up on exit.
+ *
+ * In theory we could hold on to the tempfile and delete these as soon
+ * as we download the matching pack, but it would take a bit of
+ * refactoring. Leaving them until the process ends is probably OK.
+ */
+ tmp = xstrfmt("%s/tmp_pack_%s.idx",
+ repo_get_object_directory(the_repository),
+ hash_to_hex(hash));
+ register_tempfile(tmp);
if (http_get_file(url, tmp, NULL) != HTTP_OK) {
error("Unable to get pack index %s", url);
@@ -2345,15 +2364,17 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
static int fetch_and_setup_pack_index(struct packed_git **packs_head,
unsigned char *sha1, const char *base_url)
{
- struct packed_git *new_pack;
+ struct packed_git *new_pack, *p;
char *tmp_idx = NULL;
int ret;
- if (has_pack_index(sha1)) {
- new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
- if (!new_pack)
- return -1; /* parse_pack_index() already issued error message */
- goto add_pack;
+ /*
+ * If we already have the pack locally, no need to fetch its index or
+ * even add it to list; we already have all of its objects.
+ */
+ for (p = get_all_packs(the_repository); p; p = p->next) {
+ if (hasheq(p->hash, sha1, the_repository->hash_algo))
+ return 0;
}
tmp_idx = fetch_pack_index(sha1, base_url);
@@ -2369,15 +2390,12 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
}
ret = verify_pack_index(new_pack);
- if (!ret) {
+ if (!ret)
close_pack_index(new_pack);
- ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1));
- }
free(tmp_idx);
if (ret)
return -1;
-add_pack:
new_pack->next = *packs_head;
*packs_head = new_pack;
return 0;
@@ -2505,7 +2523,8 @@ struct http_pack_request *new_direct_http_pack_request(
preq->url = url;
- strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(packed_git_hash));
+ odb_pack_name(&preq->tmpfile, packed_git_hash, "pack");
+ strbuf_addstr(&preq->tmpfile, ".temp");
preq->packfile = fopen(preq->tmpfile.buf, "a");
if (!preq->packfile) {
error("Unable to open local file %s for pack",