Add function and interface to handle prime-clone input, extracting
and using duplicate functionality from discover_refs as function
request_service.
Because part of our goal is for prime_clone to recover from errors,
HTTP errors are only optionally printed to screen and never cause
death in this case.
Signed-off-by: Kevin Wern
---
remote-curl.c | 165 ++
1 file changed, 121 insertions(+), 44 deletions(-)
diff --git a/remote-curl.c b/remote-curl.c
index 15e48e2..8ebb587 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -13,6 +13,8 @@
#include "sha1-array.h"
#include "send-pack.h"
+#define HTTP_ERROR_GENTLE (1u << 0)
+
static struct remote *remote;
/* always ends with a trailing slash */
static struct strbuf url = STRBUF_INIT;
@@ -244,7 +246,31 @@ static int show_http_message(struct strbuf *type, struct
strbuf *charset,
return 0;
}
-static struct discovery *discover_refs(const char *service, int for_push)
+static char *http_handle_result(int http_return)
+{
+ struct strbuf error = STRBUF_INIT;
+
+ switch (http_return) {
+ case HTTP_OK:
+ return NULL;
+ case HTTP_MISSING_TARGET:
+ strbuf_addf(&error, "repository '%s' not found", url.buf);
+ break;
+ case HTTP_NOAUTH:
+ strbuf_addf(&error, "Authentication failed for '%s'",
+ url.buf);
+ break;
+ default:
+ strbuf_addf(&error, "unable to access '%s': %s", url.buf,
+ curl_errorstr);
+ break;
+ }
+
+ return strbuf_detach(&error, NULL);
+}
+
+static int request_service(char const *const service, char **buffer_full,
+ char **buffer_msg, size_t *buffer_len, int flags)
{
struct strbuf exp = STRBUF_INIT;
struct strbuf type = STRBUF_INIT;
@@ -252,13 +278,9 @@ static struct discovery *discover_refs(const char
*service, int for_push)
struct strbuf buffer = STRBUF_INIT;
struct strbuf refs_url = STRBUF_INIT;
struct strbuf effective_url = STRBUF_INIT;
- struct discovery *last = last_discovery;
- int http_ret, maybe_smart = 0;
- struct http_get_options options;
-
- if (last && !strcmp(service, last->service))
- return last;
- free_discovery(last);
+ int http_ret, maybe_smart = 0, ran_smart = 0;
+ struct http_get_options get_options;
+ const char *error_string;
strbuf_addf(&refs_url, "%sinfo/refs", url.buf);
if ((starts_with(url.buf, "http://";) || starts_with(url.buf,
"https://";)) &&
@@ -271,45 +293,41 @@ static struct discovery *discover_refs(const char
*service, int for_push)
strbuf_addf(&refs_url, "service=%s", service);
}
- memset(&options, 0, sizeof(options));
- options.content_type = &type;
- options.charset = &charset;
- options.effective_url = &effective_url;
- options.base_url = &url;
- options.no_cache = 1;
- options.keep_error = 1;
-
- http_ret = http_get_strbuf(refs_url.buf, &buffer, &options);
- switch (http_ret) {
- case HTTP_OK:
- break;
- case HTTP_MISSING_TARGET:
- show_http_message(&type, &charset, &buffer);
- die("repository '%s' not found", url.buf);
- case HTTP_NOAUTH:
- show_http_message(&type, &charset, &buffer);
- die("Authentication failed for '%s'", url.buf);
- default:
- show_http_message(&type, &charset, &buffer);
- die("unable to access '%s': %s", url.buf, curl_errorstr);
+ memset(&get_options, 0, sizeof(get_options));
+ get_options.content_type = &type;
+ get_options.charset = &charset;
+ get_options.effective_url = &effective_url;
+ get_options.base_url = &url;
+ get_options.no_cache = 1;
+ get_options.keep_error = 1;
+
+ http_ret = http_get_strbuf(refs_url.buf, &buffer, &get_options);
+ error_string = http_handle_result(http_ret);
+ if (error_string) {
+ if (!(flags & HTTP_ERROR_GENTLE)) {
+ show_http_message(&type, &charset, &buffer);
+ die("%s", error_string);
+ }
+ else if (options.verbosity > 1) {
+ show_http_message(&type, &charset, &buffer);
+ fprintf(stderr, "%s\n", error_string);
+ }
}
- last= xcalloc(1, sizeof(*last_discovery));
- last->service = service;
- last->buf_alloc = strbuf_detach(&buffer, &last->len);
- last->buf = last->buf_alloc;
+ *buffer_full = strbuf_detach(&buffer, buffer_len);
+ *buffer_msg = *buffer_full;
strbuf_addf(&exp, "application/x-%s-advertisement", service);
if (maybe_smart &&
- (5 <= last->len && last->buf[4] == '#')