Git fork
at reftables-rust 265 lines 7.7 kB view raw
1#ifndef HTTP_H 2#define HTTP_H 3 4struct packed_git; 5 6#include "git-zlib.h" 7 8#include <curl/curl.h> 9#include <curl/easy.h> 10 11#include "gettext.h" 12#include "strbuf.h" 13#include "remote.h" 14 15#define DEFAULT_MAX_REQUESTS 5 16 17struct slot_results { 18 CURLcode curl_result; 19 long http_code; 20 long auth_avail; 21 long http_connectcode; 22}; 23 24struct active_request_slot { 25 CURL *curl; 26 int in_use; 27 CURLcode curl_result; 28 long http_code; 29 int *finished; 30 struct slot_results *results; 31 void *callback_data; 32 void (*callback_func)(void *data); 33 struct active_request_slot *next; 34}; 35 36struct buffer { 37 struct strbuf buf; 38 size_t posn; 39}; 40 41/* Curl request read/write callbacks */ 42size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); 43size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); 44size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf); 45int seek_buffer(void *clientp, curl_off_t offset, int origin); 46 47/* Slot lifecycle functions */ 48struct active_request_slot *get_active_slot(void); 49int start_active_slot(struct active_request_slot *slot); 50void run_active_slot(struct active_request_slot *slot); 51void finish_all_active_slots(void); 52 53/* 54 * This will run one slot to completion in a blocking manner, similar to how 55 * curl_easy_perform would work (but we don't want to use that, because 56 * we do not want to intermingle calls to curl_multi and curl_easy). 57 * 58 */ 59int run_one_slot(struct active_request_slot *slot, 60 struct slot_results *results); 61 62void fill_active_slots(void); 63void add_fill_function(void *data, int (*fill)(void *)); 64void step_active_slots(void); 65 66void http_init(struct remote *remote, const char *url, 67 int proactive_auth); 68void http_cleanup(void); 69struct curl_slist *http_copy_default_headers(void); 70 71extern long int git_curl_ipresolve; 72extern int active_requests; 73extern int http_is_verbose; 74extern ssize_t http_post_buffer; 75extern struct credential http_auth; 76 77extern char curl_errorstr[CURL_ERROR_SIZE]; 78 79enum http_follow_config { 80 HTTP_FOLLOW_NONE, 81 HTTP_FOLLOW_ALWAYS, 82 HTTP_FOLLOW_INITIAL 83}; 84extern enum http_follow_config http_follow_config; 85 86static inline int missing__target(int code, int result) 87{ 88 return /* file:// URL -- do we ever use one??? */ 89 (result == CURLE_FILE_COULDNT_READ_FILE) || 90 /* http:// and https:// URL */ 91 (code == 404 && result == CURLE_HTTP_RETURNED_ERROR) || 92 /* ftp:// URL */ 93 (code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE) 94 ; 95} 96 97#define missing_target(a) missing__target((a)->http_code, (a)->curl_result) 98 99static inline curl_off_t cast_size_t_to_curl_off_t(size_t a) 100{ 101 uintmax_t size = a; 102 if (size > maximum_signed_value_of_type(curl_off_t)) 103 die(_("number too large to represent as curl_off_t " 104 "on this platform: %"PRIuMAX), (uintmax_t)a); 105 return (curl_off_t)a; 106} 107 108/* 109 * Normalize curl results to handle CURL_FAILONERROR (or lack thereof). Failing 110 * http codes have their "result" converted to CURLE_HTTP_RETURNED_ERROR, and 111 * an appropriate string placed in the errorstr buffer (pass curl_errorstr if 112 * you don't have a custom buffer). 113 */ 114void normalize_curl_result(CURLcode *result, long http_code, char *errorstr, 115 size_t errorlen); 116 117/* Helpers for modifying and creating URLs */ 118void append_remote_object_url(struct strbuf *buf, const char *url, 119 const char *hex, 120 int only_two_digit_prefix); 121char *get_remote_object_url(const char *url, const char *hex, 122 int only_two_digit_prefix); 123 124/* Options for http_get_*() */ 125struct http_get_options { 126 unsigned no_cache:1, 127 initial_request:1; 128 129 /* If non-NULL, returns the content-type of the response. */ 130 struct strbuf *content_type; 131 132 /* 133 * If non-NULL, and content_type above is non-NULL, returns 134 * the charset parameter from the content-type. If none is 135 * present, returns an empty string. 136 */ 137 struct strbuf *charset; 138 139 /* 140 * If non-NULL, returns the URL we ended up at, including any 141 * redirects we followed. 142 */ 143 struct strbuf *effective_url; 144 145 /* 146 * If both base_url and effective_url are non-NULL, the base URL will 147 * be munged to reflect any redirections going from the requested url 148 * to effective_url. See the definition of update_url_from_redirect 149 * for details. 150 */ 151 struct strbuf *base_url; 152 153 /* 154 * If not NULL, contains additional HTTP headers to be sent with the 155 * request. The strings in the list must not be freed until after the 156 * request has completed. 157 */ 158 struct string_list *extra_headers; 159}; 160 161/* Return values for http_get_*() */ 162#define HTTP_OK 0 163#define HTTP_MISSING_TARGET 1 164#define HTTP_ERROR 2 165#define HTTP_START_FAILED 3 166#define HTTP_REAUTH 4 167#define HTTP_NOAUTH 5 168#define HTTP_NOMATCHPUBLICKEY 6 169 170/* 171 * Requests a URL and stores the result in a strbuf. 172 * 173 * If the result pointer is NULL, a HTTP HEAD request is made instead of GET. 174 */ 175int http_get_strbuf(const char *url, struct strbuf *result, struct http_get_options *options); 176 177/* 178 * Downloads a URL and stores the result in the given file. 179 * 180 * If a previous interrupted download is detected (i.e. a previous temporary 181 * file is still around) the download is resumed. 182 */ 183int http_get_file(const char *url, const char *filename, 184 struct http_get_options *options); 185 186int http_fetch_ref(const char *base, struct ref *ref); 187 188struct curl_slist *http_append_auth_header(const struct credential *c, 189 struct curl_slist *headers); 190 191/* Helpers for fetching packs */ 192int http_get_info_packs(const char *base_url, 193 struct packed_git **packs_head); 194 195/* Helper for getting Accept-Language header */ 196const char *http_get_accept_language_header(void); 197 198struct http_pack_request { 199 char *url; 200 201 /* 202 * index-pack command to run. Must be terminated by NULL. 203 * 204 * If NULL, defaults to {"index-pack", "--stdin", NULL}. 205 */ 206 const char **index_pack_args; 207 unsigned preserve_index_pack_stdout : 1; 208 209 FILE *packfile; 210 struct strbuf tmpfile; 211 struct active_request_slot *slot; 212 struct curl_slist *headers; 213}; 214 215struct http_pack_request *new_http_pack_request( 216 const unsigned char *packed_git_hash, const char *base_url); 217struct http_pack_request *new_direct_http_pack_request( 218 const unsigned char *packed_git_hash, char *url); 219int finish_http_pack_request(struct http_pack_request *preq); 220void release_http_pack_request(struct http_pack_request *preq); 221 222/* 223 * Remove p from the given list, and invoke packfile_store_add_pack() on it. 224 * 225 * This is a convenience function for users that have obtained a list of packs 226 * from http_get_info_packs() and have chosen a specific pack to fetch. 227 */ 228void http_install_packfile(struct packed_git *p, 229 struct packed_git **list_to_remove_from); 230 231/* Helpers for fetching object */ 232struct http_object_request { 233 char *url; 234 struct strbuf tmpfile; 235 int localfile; 236 CURLcode curl_result; 237 char errorstr[CURL_ERROR_SIZE]; 238 long http_code; 239 struct object_id oid; 240 struct object_id real_oid; 241 struct git_hash_ctx c; 242 git_zstream stream; 243 int zret; 244 int rename; 245 struct active_request_slot *slot; 246 struct curl_slist *headers; 247}; 248 249struct http_object_request *new_http_object_request( 250 const char *base_url, const struct object_id *oid); 251void process_http_object_request(struct http_object_request *freq); 252int finish_http_object_request(struct http_object_request *freq); 253void abort_http_object_request(struct http_object_request **freq); 254void release_http_object_request(struct http_object_request **freq); 255 256/* 257 * Instead of using environment variables to determine if curl tracing happens, 258 * behave as if GIT_TRACE_CURL=1 and GIT_TRACE_CURL_NO_DATA=1 is set. Call this 259 * before calling setup_curl_trace(). 260 */ 261void http_trace_curl_no_data(void); 262 263/* setup routine for curl_easy_setopt CURLOPT_DEBUGFUNCTION */ 264void setup_curl_trace(CURL *handle); 265#endif /* HTTP_H */