Git fork
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 */