Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 1 | #ifndef HTTP_H |
| 2 | #define HTTP_H |
| 3 | |
| 4 | #include "cache.h" |
| 5 | |
| 6 | #include <curl/curl.h> |
| 7 | #include <curl/easy.h> |
| 8 | |
Mike Hommey | 028c297 | 2007-12-09 20:30:59 +0100 | [diff] [blame] | 9 | #include "strbuf.h" |
Mike Hommey | 9fc6440 | 2008-02-27 21:35:50 +0100 | [diff] [blame] | 10 | #include "remote.h" |
Tay Ray Chuan | 1966d9f | 2010-11-25 16:21:04 +0800 | [diff] [blame] | 11 | #include "url.h" |
Mike Hommey | 028c297 | 2007-12-09 20:30:59 +0100 | [diff] [blame] | 12 | |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 13 | #define DEFAULT_MAX_REQUESTS 5 |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 14 | |
Jonathan Nieder | 9cba13c | 2011-03-16 02:08:34 -0500 | [diff] [blame] | 15 | struct slot_results { |
Nick Hengeveld | c8568e1 | 2006-01-31 11:06:55 -0800 | [diff] [blame] | 16 | CURLcode curl_result; |
| 17 | long http_code; |
Jeff King | 0972ccd | 2013-10-31 02:35:31 -0400 | [diff] [blame] | 18 | long auth_avail; |
Knut Franke | 372370f | 2016-01-26 13:02:48 +0000 | [diff] [blame] | 19 | long http_connectcode; |
Nick Hengeveld | c8568e1 | 2006-01-31 11:06:55 -0800 | [diff] [blame] | 20 | }; |
| 21 | |
Jonathan Nieder | 9cba13c | 2011-03-16 02:08:34 -0500 | [diff] [blame] | 22 | struct active_request_slot { |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 23 | CURL *curl; |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 24 | int in_use; |
| 25 | CURLcode curl_result; |
| 26 | long http_code; |
Nick Hengeveld | baa7b67 | 2006-03-10 20:18:01 -0800 | [diff] [blame] | 27 | int *finished; |
Nick Hengeveld | c8568e1 | 2006-01-31 11:06:55 -0800 | [diff] [blame] | 28 | struct slot_results *results; |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 29 | void *callback_data; |
| 30 | void (*callback_func)(void *data); |
| 31 | struct active_request_slot *next; |
| 32 | }; |
| 33 | |
Jonathan Nieder | 9cba13c | 2011-03-16 02:08:34 -0500 | [diff] [blame] | 34 | struct buffer { |
Mike Hommey | 028c297 | 2007-12-09 20:30:59 +0100 | [diff] [blame] | 35 | struct strbuf buf; |
| 36 | size_t posn; |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 37 | }; |
| 38 | |
| 39 | /* Curl request read/write callbacks */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 40 | size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); |
| 41 | size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); |
| 42 | size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); |
Jeff King | fe7e44e | 2023-01-16 22:04:44 -0500 | [diff] [blame] | 43 | int seek_buffer(void *clientp, curl_off_t offset, int origin); |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 44 | |
| 45 | /* Slot lifecycle functions */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 46 | struct active_request_slot *get_active_slot(void); |
| 47 | int start_active_slot(struct active_request_slot *slot); |
| 48 | void run_active_slot(struct active_request_slot *slot); |
| 49 | void finish_all_active_slots(void); |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 50 | |
Jeff King | beed336 | 2014-02-18 05:34:20 -0500 | [diff] [blame] | 51 | /* |
| 52 | * This will run one slot to completion in a blocking manner, similar to how |
| 53 | * curl_easy_perform would work (but we don't want to use that, because |
| 54 | * we do not want to intermingle calls to curl_multi and curl_easy). |
| 55 | * |
| 56 | */ |
| 57 | int run_one_slot(struct active_request_slot *slot, |
| 58 | struct slot_results *results); |
| 59 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 60 | void fill_active_slots(void); |
| 61 | void add_fill_function(void *data, int (*fill)(void *)); |
| 62 | void step_active_slots(void); |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 63 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 64 | void http_init(struct remote *remote, const char *url, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 65 | int proactive_auth); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 66 | void http_cleanup(void); |
| 67 | struct curl_slist *http_copy_default_headers(void); |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 68 | |
Eric Wong | c915f11 | 2016-02-03 04:09:14 +0000 | [diff] [blame] | 69 | extern long int git_curl_ipresolve; |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 70 | extern int active_requests; |
Tay Ray Chuan | e917674 | 2009-06-06 16:43:41 +0800 | [diff] [blame] | 71 | extern int http_is_verbose; |
David Turner | 37ee680 | 2017-04-11 14:13:57 -0400 | [diff] [blame] | 72 | extern ssize_t http_post_buffer; |
Jeff King | 2501aff | 2013-09-28 04:31:45 -0400 | [diff] [blame] | 73 | extern struct credential http_auth; |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 74 | |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 75 | extern char curl_errorstr[CURL_ERROR_SIZE]; |
| 76 | |
Jeff King | 50d3413 | 2016-12-06 13:24:41 -0500 | [diff] [blame] | 77 | enum http_follow_config { |
| 78 | HTTP_FOLLOW_NONE, |
| 79 | HTTP_FOLLOW_ALWAYS, |
| 80 | HTTP_FOLLOW_INITIAL |
| 81 | }; |
| 82 | extern enum http_follow_config http_follow_config; |
| 83 | |
Mike Hommey | e8dc37e | 2007-12-10 22:36:09 +0100 | [diff] [blame] | 84 | static inline int missing__target(int code, int result) |
| 85 | { |
| 86 | return /* file:// URL -- do we ever use one??? */ |
| 87 | (result == CURLE_FILE_COULDNT_READ_FILE) || |
| 88 | /* http:// and https:// URL */ |
| 89 | (code == 404 && result == CURLE_HTTP_RETURNED_ERROR) || |
| 90 | /* ftp:// URL */ |
| 91 | (code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE) |
| 92 | ; |
| 93 | } |
| 94 | |
| 95 | #define missing_target(a) missing__target((a)->http_code, (a)->curl_result) |
| 96 | |
Jeff King | a3722bc | 2019-03-24 08:08:38 -0400 | [diff] [blame] | 97 | /* |
| 98 | * Normalize curl results to handle CURL_FAILONERROR (or lack thereof). Failing |
| 99 | * http codes have their "result" converted to CURLE_HTTP_RETURNED_ERROR, and |
| 100 | * an appropriate string placed in the errorstr buffer (pass curl_errorstr if |
| 101 | * you don't have a custom buffer). |
| 102 | */ |
| 103 | void normalize_curl_result(CURLcode *result, long http_code, char *errorstr, |
| 104 | size_t errorlen); |
| 105 | |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 106 | /* Helpers for modifying and creating URLs */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 107 | void append_remote_object_url(struct strbuf *buf, const char *url, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 108 | const char *hex, |
| 109 | int only_two_digit_prefix); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 110 | char *get_remote_object_url(const char *url, const char *hex, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 111 | int only_two_digit_prefix); |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 112 | |
Jeff King | 1bbcc22 | 2013-09-28 04:31:23 -0400 | [diff] [blame] | 113 | /* Options for http_get_*() */ |
| 114 | struct http_get_options { |
| 115 | unsigned no_cache:1, |
Jeff King | 50d3413 | 2016-12-06 13:24:41 -0500 | [diff] [blame] | 116 | initial_request:1; |
Mike Hommey | e929cd2 | 2009-06-06 16:43:53 +0800 | [diff] [blame] | 117 | |
Jeff King | 1bbcc22 | 2013-09-28 04:31:23 -0400 | [diff] [blame] | 118 | /* If non-NULL, returns the content-type of the response. */ |
| 119 | struct strbuf *content_type; |
Jeff King | 7886896 | 2013-09-28 04:32:02 -0400 | [diff] [blame] | 120 | |
| 121 | /* |
Jeff King | e313162 | 2014-05-22 05:30:05 -0400 | [diff] [blame] | 122 | * If non-NULL, and content_type above is non-NULL, returns |
| 123 | * the charset parameter from the content-type. If none is |
| 124 | * present, returns an empty string. |
| 125 | */ |
| 126 | struct strbuf *charset; |
| 127 | |
| 128 | /* |
Jeff King | 7886896 | 2013-09-28 04:32:02 -0400 | [diff] [blame] | 129 | * If non-NULL, returns the URL we ended up at, including any |
| 130 | * redirects we followed. |
| 131 | */ |
| 132 | struct strbuf *effective_url; |
Jeff King | c93c92f | 2013-09-28 04:34:05 -0400 | [diff] [blame] | 133 | |
| 134 | /* |
| 135 | * If both base_url and effective_url are non-NULL, the base URL will |
| 136 | * be munged to reflect any redirections going from the requested url |
| 137 | * to effective_url. See the definition of update_url_from_redirect |
| 138 | * for details. |
| 139 | */ |
| 140 | struct strbuf *base_url; |
Brandon Williams | 8ff14ed | 2018-03-15 10:31:38 -0700 | [diff] [blame] | 141 | |
| 142 | /* |
| 143 | * If not NULL, contains additional HTTP headers to be sent with the |
| 144 | * request. The strings in the list must not be freed until after the |
| 145 | * request has completed. |
| 146 | */ |
| 147 | struct string_list *extra_headers; |
Jeff King | 1bbcc22 | 2013-09-28 04:31:23 -0400 | [diff] [blame] | 148 | }; |
| 149 | |
| 150 | /* Return values for http_get_*() */ |
Mike Hommey | e929cd2 | 2009-06-06 16:43:53 +0800 | [diff] [blame] | 151 | #define HTTP_OK 0 |
| 152 | #define HTTP_MISSING_TARGET 1 |
| 153 | #define HTTP_ERROR 2 |
| 154 | #define HTTP_START_FAILED 3 |
Scott Chacon | 42653c0 | 2010-04-01 15:14:35 -0700 | [diff] [blame] | 155 | #define HTTP_REAUTH 4 |
| 156 | #define HTTP_NOAUTH 5 |
Ævar Arnfjörð Bjarmason | 3e8084f | 2021-09-24 12:08:20 +0200 | [diff] [blame] | 157 | #define HTTP_NOMATCHPUBLICKEY 6 |
Mike Hommey | e929cd2 | 2009-06-06 16:43:53 +0800 | [diff] [blame] | 158 | |
| 159 | /* |
Jim Meyering | a7793a7 | 2012-03-28 10:41:54 +0200 | [diff] [blame] | 160 | * Requests a URL and stores the result in a strbuf. |
Mike Hommey | e929cd2 | 2009-06-06 16:43:53 +0800 | [diff] [blame] | 161 | * |
| 162 | * If the result pointer is NULL, a HTTP HEAD request is made instead of GET. |
| 163 | */ |
Jeff King | 1bbcc22 | 2013-09-28 04:31:23 -0400 | [diff] [blame] | 164 | int http_get_strbuf(const char *url, struct strbuf *result, struct http_get_options *options); |
Mike Hommey | e929cd2 | 2009-06-06 16:43:53 +0800 | [diff] [blame] | 165 | |
Derrick Stolee | c1d024b | 2022-05-16 20:11:02 +0000 | [diff] [blame] | 166 | /* |
| 167 | * Downloads a URL and stores the result in the given file. |
| 168 | * |
| 169 | * If a previous interrupted download is detected (i.e. a previous temporary |
| 170 | * file is still around) the download is resumed. |
| 171 | */ |
| 172 | int http_get_file(const char *url, const char *filename, |
| 173 | struct http_get_options *options); |
| 174 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 175 | int http_fetch_ref(const char *base, struct ref *ref); |
Mike Hommey | d7e9280 | 2007-12-11 00:08:25 +0100 | [diff] [blame] | 176 | |
Tay Ray Chuan | b8caac2 | 2009-06-06 16:43:59 +0800 | [diff] [blame] | 177 | /* Helpers for fetching packs */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 178 | int http_get_info_packs(const char *base_url, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 179 | struct packed_git **packs_head); |
Tay Ray Chuan | b8caac2 | 2009-06-06 16:43:59 +0800 | [diff] [blame] | 180 | |
Li Linchao | b0c4adc | 2022-07-11 05:58:54 +0000 | [diff] [blame] | 181 | /* Helper for getting Accept-Language header */ |
| 182 | const char *http_get_accept_language_header(void); |
| 183 | |
Jonathan Nieder | 9cba13c | 2011-03-16 02:08:34 -0500 | [diff] [blame] | 184 | struct http_pack_request { |
Tay Ray Chuan | 2264dfa | 2009-06-06 16:44:01 +0800 | [diff] [blame] | 185 | char *url; |
Jonathan Tan | 8d5d2a3 | 2020-06-10 13:57:18 -0700 | [diff] [blame] | 186 | |
| 187 | /* |
Jonathan Tan | 726b25a | 2021-02-22 11:20:06 -0800 | [diff] [blame] | 188 | * index-pack command to run. Must be terminated by NULL. |
| 189 | * |
| 190 | * If NULL, defaults to {"index-pack", "--stdin", NULL}. |
Jonathan Tan | 8d5d2a3 | 2020-06-10 13:57:18 -0700 | [diff] [blame] | 191 | */ |
Jonathan Tan | 726b25a | 2021-02-22 11:20:06 -0800 | [diff] [blame] | 192 | const char **index_pack_args; |
| 193 | unsigned preserve_index_pack_stdout : 1; |
Jonathan Tan | 8d5d2a3 | 2020-06-10 13:57:18 -0700 | [diff] [blame] | 194 | |
Tay Ray Chuan | 2264dfa | 2009-06-06 16:44:01 +0800 | [diff] [blame] | 195 | FILE *packfile; |
Jeff King | 390c6cb | 2018-05-18 18:56:37 -0700 | [diff] [blame] | 196 | struct strbuf tmpfile; |
Tay Ray Chuan | 2264dfa | 2009-06-06 16:44:01 +0800 | [diff] [blame] | 197 | struct active_request_slot *slot; |
| 198 | }; |
| 199 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 200 | struct http_pack_request *new_http_pack_request( |
Jonathan Tan | eb05349 | 2020-06-10 13:57:16 -0700 | [diff] [blame] | 201 | const unsigned char *packed_git_hash, const char *base_url); |
Jonathan Tan | 8d5d2a3 | 2020-06-10 13:57:18 -0700 | [diff] [blame] | 202 | struct http_pack_request *new_direct_http_pack_request( |
| 203 | const unsigned char *packed_git_hash, char *url); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 204 | int finish_http_pack_request(struct http_pack_request *preq); |
| 205 | void release_http_pack_request(struct http_pack_request *preq); |
Tay Ray Chuan | 2264dfa | 2009-06-06 16:44:01 +0800 | [diff] [blame] | 206 | |
Jonathan Tan | eb05349 | 2020-06-10 13:57:16 -0700 | [diff] [blame] | 207 | /* |
| 208 | * Remove p from the given list, and invoke install_packed_git() on it. |
| 209 | * |
| 210 | * This is a convenience function for users that have obtained a list of packs |
| 211 | * from http_get_info_packs() and have chosen a specific pack to fetch. |
| 212 | */ |
| 213 | void http_install_packfile(struct packed_git *p, |
| 214 | struct packed_git **list_to_remove_from); |
| 215 | |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 216 | /* Helpers for fetching object */ |
Jonathan Nieder | 9cba13c | 2011-03-16 02:08:34 -0500 | [diff] [blame] | 217 | struct http_object_request { |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 218 | char *url; |
Jeff King | 390c6cb | 2018-05-18 18:56:37 -0700 | [diff] [blame] | 219 | struct strbuf tmpfile; |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 220 | int localfile; |
| 221 | CURLcode curl_result; |
| 222 | char errorstr[CURL_ERROR_SIZE]; |
| 223 | long http_code; |
Jeff King | f0be0db | 2019-01-07 03:34:40 -0500 | [diff] [blame] | 224 | struct object_id oid; |
| 225 | struct object_id real_oid; |
brian m. carlson | eed0e60 | 2019-02-19 00:05:14 +0000 | [diff] [blame] | 226 | git_hash_ctx c; |
Junio C Hamano | ef49a7a | 2011-06-10 11:52:15 -0700 | [diff] [blame] | 227 | git_zstream stream; |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 228 | int zret; |
| 229 | int rename; |
| 230 | struct active_request_slot *slot; |
| 231 | }; |
| 232 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 233 | struct http_object_request *new_http_object_request( |
Jeff King | f0be0db | 2019-01-07 03:34:40 -0500 | [diff] [blame] | 234 | const char *base_url, const struct object_id *oid); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 235 | void process_http_object_request(struct http_object_request *freq); |
| 236 | int finish_http_object_request(struct http_object_request *freq); |
| 237 | void abort_http_object_request(struct http_object_request *freq); |
| 238 | void release_http_object_request(struct http_object_request *freq); |
Tay Ray Chuan | 5424bc5 | 2009-06-06 16:44:02 +0800 | [diff] [blame] | 239 | |
Jonathan Tan | 7167a62 | 2020-05-11 10:43:10 -0700 | [diff] [blame] | 240 | /* |
| 241 | * Instead of using environment variables to determine if curl tracing happens, |
| 242 | * behave as if GIT_TRACE_CURL=1 and GIT_TRACE_CURL_NO_DATA=1 is set. Call this |
| 243 | * before calling setup_curl_trace(). |
| 244 | */ |
| 245 | void http_trace_curl_no_data(void); |
| 246 | |
Elia Pinto | 74c682d | 2016-05-23 13:44:02 +0000 | [diff] [blame] | 247 | /* setup routine for curl_easy_setopt CURLOPT_DEBUGFUNCTION */ |
| 248 | void setup_curl_trace(CURL *handle); |
Nick Hengeveld | 29508e1 | 2005-11-18 11:02:58 -0800 | [diff] [blame] | 249 | #endif /* HTTP_H */ |