git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[WIP Patch 03/12] Two new functions for the http API

From
Mike Hommey <mh@glandium.org>
Date
Jan 18, 2009, 08:04 UTC
Message-ID
<1232265877-3649-4-git-send-email-mh@glandium.org>
In-Reply-To
<1232265877-3649-3-git-send-email-mh@glandium.org>

http_get_strbuf and http_get_file allow respectively to retrieve contents of an URL to a strbuf or an opened file handle.

Both these functions are the beginning of the http code refactoring.
Signed-off-by: Mike Hommey <mh@glandium.org>
---
 http.c |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 http.h |   17 +++++++++++++
 2 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/http.c b/http.c
index ee58799..82534cf 100644
--- a/http.c
+++ b/http.c
@@ -638,3 +638,88 @@ int http_fetch_ref(const char *base, struct ref *ref)
 	free(url);
 	return ret;
 }
+
+/* http_request() targets */
+#define HTTP_REQUEST_STRBUF	0
+#define HTTP_REQUEST_FILE	1
+
+static int http_request(const char *url, void *result, int target, int options)
+{
+	struct active_request_slot *slot;
+	struct slot_results results;
+	struct curl_slist *headers = NULL;
+	struct strbuf buf = STRBUF_INIT;
+
+	slot = get_active_slot();
+	slot->results = &results;
+	curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
+
+	if (result == NULL) {
+		curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
+	} else {
+		curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
+		curl_easy_setopt(slot->curl, CURLOPT_FILE, result);
+
+		if (target == HTTP_REQUEST_FILE) {
+			long posn = ftell(result);
+			curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
+					 fwrite);
+			if (posn > 0) {
+				strbuf_addf(&buf, "Range: bytes=%ld-", posn);
+				headers = curl_slist_append(headers, buf.buf);
+				strbuf_reset(&buf);
+			}
+			slot->local = result;
+		} else
+			curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
+					 fwrite_buffer);
+	}
+
+	strbuf_addstr(&buf, "Pragma:");
+	if (options & HTTP_NO_CACHE)
+		strbuf_addstr(&buf, " no-cache");
+
+	headers = curl_slist_append(headers, buf.buf);
+	strbuf_release(&buf);
+
+	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
+	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
+
+	if (start_active_slot(slot)) {
+		run_active_slot(slot);
+		if (results.curl_result == CURLE_OK)
+			return HTTP_OK;
+		else if (missing_target(&results))
+			return HTTP_MISSING_TARGET;
+	}
+	return HTTP_ERROR;
+}
+
+int http_get_strbuf(const char *url, struct strbuf *result, int options)
+{
+	return http_request(url, result, HTTP_REQUEST_STRBUF, options);
+}
+
+int http_get_file(const char *url, const char *filename, int options)
+{
+	int ret;
+	struct strbuf tmpfile = STRBUF_INIT;
+	FILE *result;
+
+	strbuf_addf(&tmpfile, "%s.temp", filename);
+	result = fopen(tmpfile.buf, "a");
+	if (! result) {
+		error("Unable to open local file %s", tmpfile.buf);
+		ret = HTTP_ERROR;
+		goto cleanup;
+	}
+
+	ret = http_request(url, result, HTTP_REQUEST_FILE, options);
+	fclose(result);
+
+	if ((ret == HTTP_OK) && move_temp_to_file(tmpfile.buf, filename))
+		ret = HTTP_ERROR;
+cleanup:
+	strbuf_release(&tmpfile);
+	return ret;
+}
diff --git a/http.h b/http.h
index 905b462..323c780 100644
--- a/http.h
+++ b/http.h
@@ -104,4 +104,21 @@ static inline int missing__target(int code, int result)
 
 extern int http_fetch_ref(const char *base, struct ref *ref);
 
+/* Options for http_request_*() */
+#define HTTP_NO_CACHE		1
+
+/* Return values for http_request_*() */
+#define HTTP_OK			0
+#define HTTP_MISSING_TARGET	1
+#define HTTP_ERROR		2
+
+/* Requests an url and stores the result in a strbuf.
+ * If the result pointer is NULL, a HTTP HEAD request is made instead of GET. */
+int http_get_strbuf(const char *url, struct strbuf *result, int options);
+
+/* Downloads an url and stores the result in the given file.
+ * If a previous interrupted download is detected (i.e. a previous temporary
+ * file is still around) the download is resumed. */
+int http_get_file(const char *url, const char *filename, int options);
+
 #endif /* HTTP_H */
-- 
1.6.1.141.gb32a
Previous: Mike HommeyNext: Mike Hommey
Message 8 of 33 in “http-push: fix off-by-path_len”
  1. http-push: fix off-by-path_lenJohannes Schindelin, Jan 17, 2009
  2. Where's Nick?, was Re: [PATCH] http-push: fix off-by-path_lenJohannes Schindelin, Jan 17, 2009
  3. t5540: clarify that http-push does not handle packed-refs on the remoteJohannes Schindelin, Jan 17, 2009
  4. Mike HommeyJan 18, 2009
  5. 00/12 Refactoring the http APIMike Hommey, Jan 18, 2009
  6. 01/12 Don't expect verify_pack() callers to set pack_sizeMike Hommey, Jan 18, 2009
  7. 02/12 Some cleanup in get_refs_via_curl()Mike Hommey, Jan 18, 2009
  8. 03/12 Two new functions for the http APIMike Hommey, Jan 18, 2009
  9. 04/12 Use the new http API in http_fetch_ref()Mike Hommey, Jan 18, 2009
  10. 05/12 Use the new http API in get_refs_via_curl()Mike Hommey, Jan 18, 2009
  11. 06/12 Use the new http API in http-walker.c:fetch_indices()Mike Hommey, Jan 18, 2009
  12. 07/12 Use the new http API in http-push.c:fetch_indices()Mike Hommey, Jan 18, 2009
  13. 08/12 Use the new http API in update_remote_info_refs()Mike Hommey, Jan 18, 2009
  14. 09/12 Use the new http API in fetch_symref()Mike Hommey, Jan 18, 2009
  15. 10/12 Use the new http API in http-walker.c:fetch_index()Mike Hommey, Jan 18, 2009
  16. 11/12 Use the new http API in http-push.c:fetch_index()Mike Hommey, Jan 18, 2009
  17. 12/12 Use the new http API in http-walker.c:fetch_pack()Mike Hommey, Jan 18, 2009
  18. Johannes SchindelinJan 18, 2009
  19. Mike HommeyJan 18, 2009
  20. Johannes SchindelinJan 18, 2009
  21. Johannes SchindelinJan 18, 2009
  22. Johannes SchindelinJan 18, 2009
  23. Mike HommeyJan 18, 2009
  24. Johannes SchindelinJan 18, 2009
  25. Johannes SchindelinJan 18, 2009
  26. Johannes SchindelinJan 18, 2009
  27. Mike HommeyJan 18, 2009
  28. Johannes SchindelinJan 18, 2009
  29. Mike HommeyJan 18, 2009
  30. Johannes SchindelinJan 18, 2009
  31. Junio C HamanoJan 18, 2009
  32. Mike HommeyJan 18, 2009
  33. Boyd Stephen Smith Jr.Jan 18, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.