Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2
3 #include "git-compat-util.h"
4 #include "environment.h"
5 #include "hex.h"
6 #include "repository.h"
7 #include "commit.h"
8 #include "tag.h"
9 #include "blob.h"
10 #include "http.h"
11 #include "diff.h"
12 #include "revision.h"
13 #include "remote.h"
14 #include "list-objects.h"
15 #include "setup.h"
16 #include "sigchain.h"
17 #include "strvec.h"
18 #include "tree.h"
19 #include "tree-walk.h"
20 #include "url.h"
21 #include "packfile.h"
22 #include "object-file.h"
23 #include "odb.h"
24 #include "commit-reach.h"
25
26 #ifdef EXPAT_NEEDS_XMLPARSE_H
27 #include <xmlparse.h>
28 #else
29 #include <expat.h>
30 #endif
31
32 static const char http_push_usage[] =
33 "git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n";
34
35 #ifndef XML_STATUS_OK
36 enum XML_Status {
37 XML_STATUS_OK = 1,
38 XML_STATUS_ERROR = 0
39 };
40 #define XML_STATUS_OK 1
41 #define XML_STATUS_ERROR 0
42 #endif
43
44 #define PREV_BUF_SIZE 4096
45
46 /* DAV methods */
47 #define DAV_LOCK "LOCK"
48 #define DAV_MKCOL "MKCOL"
49 #define DAV_MOVE "MOVE"
50 #define DAV_PROPFIND "PROPFIND"
51 #define DAV_PUT "PUT"
52 #define DAV_UNLOCK "UNLOCK"
53 #define DAV_DELETE "DELETE"
54
55 /* DAV lock flags */
56 #define DAV_PROP_LOCKWR (1u << 0)
57 #define DAV_PROP_LOCKEX (1u << 1)
58 #define DAV_LOCK_OK (1u << 2)
59
60 /* DAV XML properties */
61 #define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
62 #define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
63 #define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
64 #define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
65 #define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
66 #define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
67 #define DAV_PROPFIND_RESP ".multistatus.response"
68 #define DAV_PROPFIND_NAME ".multistatus.response.href"
69 #define DAV_PROPFIND_COLLECTION ".multistatus.response.propstat.prop.resourcetype.collection"
70
71 /* DAV request body templates */
72 #define PROPFIND_SUPPORTEDLOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock/>\n</D:prop>\n</D:propfind>"
73 #define PROPFIND_ALL_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:allprop/>\n</D:propfind>"
74 #define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>\n<D:owner>\n<D:href>mailto:%s</D:href>\n</D:owner>\n</D:lockinfo>"
75
76 #define LOCK_TIME 600
77 #define LOCK_REFRESH 30
78
79 /* Remember to update object flag allocation in object.h */
80 #define LOCAL (1u<<11)
81 #define REMOTE (1u<<12)
82 #define FETCHING (1u<<13)
83 #define PUSHING (1u<<14)
84
85 /* We allow "recursive" symbolic refs. Only within reason, though */
86 #define MAXDEPTH 5
87
88 static int pushing;
89 static int aborted;
90 static signed char remote_dir_exists[256];
91
92 static int push_verbosely;
93 static int push_all = MATCH_REFS_NONE;
94 static int force_all;
95 static int dry_run;
96 static int helper_status;
97
98 static struct object_list *objects;
99
100 struct repo {
101 char *url;
102 const char *path;
103 int path_len;
104 int has_info_refs;
105 int can_update_info_refs;
106 int has_info_packs;
107 struct packfile_list packs;
108 struct remote_lock *locks;
109 };
110
111 static struct repo *repo;
112
113 enum transfer_state {
114 NEED_FETCH,
115 RUN_FETCH_LOOSE,
116 RUN_FETCH_PACKED,
117 NEED_PUSH,
118 RUN_MKCOL,
119 RUN_PUT,
120 RUN_MOVE,
121 ABORTED,
122 COMPLETE
123 };
124
125 struct transfer_request {
126 struct object *obj;
127 struct packed_git *target;
128 char *url;
129 char *dest;
130 struct remote_lock *lock;
131 struct curl_slist *headers;
132 struct buffer buffer;
133 enum transfer_state state;
134 CURLcode curl_result;
135 char errorstr[CURL_ERROR_SIZE];
136 long http_code;
137 void *userData;
138 struct active_request_slot *slot;
139 struct transfer_request *next;
140 };
141
142 static struct transfer_request *request_queue_head;
143
144 struct xml_ctx {
145 char *name;
146 int len;
147 char *cdata;
148 void (*userFunc)(struct xml_ctx *ctx, int tag_closed);
149 void *userData;
150 };
151
152 struct remote_lock {
153 char *url;
154 char *owner;
155 char *token;
156 char tmpfile_suffix[GIT_MAX_HEXSZ + 1];
157 time_t start_time;
158 long timeout;
159 int refreshing;
160 struct remote_lock *next;
161 };
162
163 /* Flags that control remote_ls processing */
164 #define PROCESS_FILES (1u << 0)
165 #define PROCESS_DIRS (1u << 1)
166 #define RECURSIVE (1u << 2)
167
168 /* Flags that remote_ls passes to callback functions */
169 #define IS_DIR (1u << 0)
170
171 struct remote_ls_ctx {
172 char *path;
173 void (*userFunc)(struct remote_ls_ctx *ls);
174 void *userData;
175 int flags;
176 char *dentry_name;
177 int dentry_flags;
178 struct remote_ls_ctx *parent;
179 };
180
181 /* get_dav_token_headers options */
182 enum dav_header_flag {
183 DAV_HEADER_IF = (1u << 0),
184 DAV_HEADER_LOCK = (1u << 1),
185 DAV_HEADER_TIMEOUT = (1u << 2)
186 };
187
188 static char *xml_entities(const char *s)
189 {
190 struct strbuf buf = STRBUF_INIT;
191 strbuf_addstr_xml_quoted(&buf, s);
192 return strbuf_detach(&buf, NULL);
193 }
194
195 static void curl_setup_http_get(CURL *curl, const char *url,
196 const char *custom_req)
197 {
198 curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
199 curl_easy_setopt(curl, CURLOPT_URL, url);
200 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);
201 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_null);
202 }
203
204 static void curl_setup_http(CURL *curl, const char *url,
205 const char *custom_req, struct buffer *buffer,
206 curl_write_callback write_fn)
207 {
208 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
209 curl_easy_setopt(curl, CURLOPT_URL, url);
210 curl_easy_setopt(curl, CURLOPT_INFILE, buffer);
211 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
212 cast_size_t_to_curl_off_t(buffer->buf.len));
213 curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
214 curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);
215 curl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);
216 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
217 curl_easy_setopt(curl, CURLOPT_NOBODY, 0L);
218 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);
219 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
220 }
221
222 static struct curl_slist *get_dav_token_headers(struct remote_lock *lock, enum dav_header_flag options)
223 {
224 struct strbuf buf = STRBUF_INIT;
225 struct curl_slist *dav_headers = http_copy_default_headers();
226
227 if (options & DAV_HEADER_IF) {
228 strbuf_addf(&buf, "If: (<%s>)", lock->token);
229 dav_headers = curl_slist_append(dav_headers, buf.buf);
230 strbuf_reset(&buf);
231 }
232 if (options & DAV_HEADER_LOCK) {
233 strbuf_addf(&buf, "Lock-Token: <%s>", lock->token);
234 dav_headers = curl_slist_append(dav_headers, buf.buf);
235 strbuf_reset(&buf);
236 }
237 if (options & DAV_HEADER_TIMEOUT) {
238 strbuf_addf(&buf, "Timeout: Second-%ld", lock->timeout);
239 dav_headers = curl_slist_append(dav_headers, buf.buf);
240 strbuf_reset(&buf);
241 }
242 strbuf_release(&buf);
243
244 return dav_headers;
245 }
246
247 static void finish_request(struct transfer_request *request);
248 static void release_request(struct transfer_request *request);
249
250 static void process_response(void *callback_data)
251 {
252 struct transfer_request *request =
253 (struct transfer_request *)callback_data;
254
255 finish_request(request);
256 }
257
258 static void start_fetch_loose(struct transfer_request *request)
259 {
260 struct active_request_slot *slot;
261 struct http_object_request *obj_req;
262
263 obj_req = new_http_object_request(repo->url, &request->obj->oid);
264 if (!obj_req) {
265 request->state = ABORTED;
266 return;
267 }
268
269 slot = obj_req->slot;
270 slot->callback_func = process_response;
271 slot->callback_data = request;
272 request->slot = slot;
273 request->userData = obj_req;
274
275 /* Try to get the request started, abort the request on error */
276 request->state = RUN_FETCH_LOOSE;
277 if (!start_active_slot(slot)) {
278 fprintf(stderr, "Unable to start GET request\n");
279 repo->can_update_info_refs = 0;
280 release_http_object_request(&obj_req);
281 release_request(request);
282 }
283 }
284
285 static void start_mkcol(struct transfer_request *request)
286 {
287 char *hex = oid_to_hex(&request->obj->oid);
288 struct active_request_slot *slot;
289
290 request->url = get_remote_object_url(repo->url, hex, 1);
291
292 slot = get_active_slot();
293 slot->callback_func = process_response;
294 slot->callback_data = request;
295 curl_setup_http_get(slot->curl, request->url, DAV_MKCOL);
296 curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
297
298 if (start_active_slot(slot)) {
299 request->slot = slot;
300 request->state = RUN_MKCOL;
301 } else {
302 request->state = ABORTED;
303 FREE_AND_NULL(request->url);
304 }
305 }
306
307 static void start_fetch_packed(struct transfer_request *request)
308 {
309 struct packed_git *target;
310
311 struct transfer_request *check_request = request_queue_head;
312 struct http_pack_request *preq;
313
314 target = packfile_list_find_oid(repo->packs.head, &request->obj->oid);
315 if (!target) {
316 fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", oid_to_hex(&request->obj->oid));
317 repo->can_update_info_refs = 0;
318 release_request(request);
319 return;
320 }
321 close_pack_index(target);
322 request->target = target;
323
324 fprintf(stderr, "Fetching pack %s\n",
325 hash_to_hex(target->hash));
326 fprintf(stderr, " which contains %s\n", oid_to_hex(&request->obj->oid));
327
328 preq = new_http_pack_request(target->hash, repo->url);
329 if (!preq) {
330 repo->can_update_info_refs = 0;
331 return;
332 }
333
334 /* Make sure there isn't another open request for this pack */
335 while (check_request) {
336 if (check_request->state == RUN_FETCH_PACKED &&
337 !strcmp(check_request->url, preq->url)) {
338 release_http_pack_request(preq);
339 release_request(request);
340 return;
341 }
342 check_request = check_request->next;
343 }
344
345 preq->slot->callback_func = process_response;
346 preq->slot->callback_data = request;
347 request->slot = preq->slot;
348 request->userData = preq;
349
350 /* Try to get the request started, abort the request on error */
351 request->state = RUN_FETCH_PACKED;
352 if (!start_active_slot(preq->slot)) {
353 fprintf(stderr, "Unable to start GET request\n");
354 release_http_pack_request(preq);
355 repo->can_update_info_refs = 0;
356 release_request(request);
357 }
358 }
359
360 static void start_put(struct transfer_request *request)
361 {
362 char *hex = oid_to_hex(&request->obj->oid);
363 struct active_request_slot *slot;
364 struct strbuf buf = STRBUF_INIT;
365 enum object_type type;
366 char hdr[50];
367 void *unpacked;
368 size_t len;
369 int hdrlen;
370 ssize_t size;
371 git_zstream stream;
372 struct repo_config_values *cfg = repo_config_values(the_repository);
373
374 unpacked = odb_read_object(the_repository->objects, &request->obj->oid,
375 &type, &len);
376 hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
377
378 /* Set it up */
379 git_deflate_init(&stream, cfg->zlib_compression_level);
380 size = git_deflate_bound(&stream, len + hdrlen);
381 strbuf_grow(&request->buffer.buf, size);
382 request->buffer.posn = 0;
383
384 /* Compress it */
385 stream.next_out = (unsigned char *)request->buffer.buf.buf;
386 stream.avail_out = size;
387
388 /* First header.. */
389 stream.next_in = (void *)hdr;
390 stream.avail_in = hdrlen;
391 while (git_deflate(&stream, 0) == Z_OK)
392 ; /* nothing */
393
394 /* Then the data itself.. */
395 stream.next_in = unpacked;
396 stream.avail_in = len;
397 while (git_deflate(&stream, Z_FINISH) == Z_OK)
398 ; /* nothing */
399 git_deflate_end(&stream);
400 free(unpacked);
401
402 request->buffer.buf.len = stream.total_out;
403
404 strbuf_addstr(&buf, "Destination: ");
405 append_remote_object_url(&buf, repo->url, hex, 0);
406 request->dest = strbuf_detach(&buf, NULL);
407
408 append_remote_object_url(&buf, repo->url, hex, 0);
409 strbuf_add(&buf, request->lock->tmpfile_suffix, the_hash_algo->hexsz + 1);
410 request->url = strbuf_detach(&buf, NULL);
411
412 slot = get_active_slot();
413 slot->callback_func = process_response;
414 slot->callback_data = request;
415 curl_setup_http(slot->curl, request->url, DAV_PUT,
416 &request->buffer, fwrite_null);
417
418 if (start_active_slot(slot)) {
419 request->slot = slot;
420 request->state = RUN_PUT;
421 } else {
422 request->state = ABORTED;
423 FREE_AND_NULL(request->url);
424 }
425 }
426
427 static void start_move(struct transfer_request *request)
428 {
429 struct active_request_slot *slot;
430 struct curl_slist *dav_headers = http_copy_default_headers();
431
432 slot = get_active_slot();
433 slot->callback_func = process_response;
434 slot->callback_data = request;
435 curl_setup_http_get(slot->curl, request->url, DAV_MOVE);
436 dav_headers = curl_slist_append(dav_headers, request->dest);
437 dav_headers = curl_slist_append(dav_headers, "Overwrite: T");
438 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
439
440 if (start_active_slot(slot)) {
441 request->slot = slot;
442 request->state = RUN_MOVE;
443 request->headers = dav_headers;
444 } else {
445 request->state = ABORTED;
446 FREE_AND_NULL(request->url);
447 curl_slist_free_all(dav_headers);
448 }
449 }
450
451 static int refresh_lock(struct remote_lock *lock)
452 {
453 struct active_request_slot *slot;
454 struct slot_results results;
455 struct curl_slist *dav_headers;
456 int rc = 0;
457
458 lock->refreshing = 1;
459
460 dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF | DAV_HEADER_TIMEOUT);
461
462 slot = get_active_slot();
463 slot->results = &results;
464 curl_setup_http_get(slot->curl, lock->url, DAV_LOCK);
465 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
466
467 if (start_active_slot(slot)) {
468 run_active_slot(slot);
469 if (results.curl_result != CURLE_OK) {
470 fprintf(stderr, "LOCK HTTP error %ld\n",
471 results.http_code);
472 } else {
473 lock->start_time = time(NULL);
474 rc = 1;
475 }
476 }
477
478 lock->refreshing = 0;
479 curl_slist_free_all(dav_headers);
480
481 return rc;
482 }
483
484 static void check_locks(void)
485 {
486 struct remote_lock *lock = repo->locks;
487 time_t current_time = time(NULL);
488 int time_remaining;
489
490 while (lock) {
491 time_remaining = lock->start_time + lock->timeout -
492 current_time;
493 if (!lock->refreshing && time_remaining < LOCK_REFRESH) {
494 if (!refresh_lock(lock)) {
495 fprintf(stderr,
496 "Unable to refresh lock for %s\n",
497 lock->url);
498 aborted = 1;
499 return;
500 }
501 }
502 lock = lock->next;
503 }
504 }
505
506 static void release_request(struct transfer_request *request)
507 {
508 struct transfer_request *entry = request_queue_head;
509
510 if (request == request_queue_head) {
511 request_queue_head = request->next;
512 } else {
513 while (entry && entry->next != request)
514 entry = entry->next;
515 if (entry)
516 entry->next = request->next;
517 }
518
519 free(request->url);
520 free(request->dest);
521 strbuf_release(&request->buffer.buf);
522 free(request);
523 }
524
525 static void finish_request(struct transfer_request *request)
526 {
527 struct http_pack_request *preq;
528 struct http_object_request *obj_req;
529
530 request->curl_result = request->slot->curl_result;
531 request->http_code = request->slot->http_code;
532 request->slot = NULL;
533
534 /* Keep locks active */
535 check_locks();
536
537 if (request->headers)
538 curl_slist_free_all(request->headers);
539
540 /* URL is reused for MOVE after PUT and used during FETCH */
541 if (request->state != RUN_PUT && request->state != RUN_FETCH_PACKED) {
542 FREE_AND_NULL(request->url);
543 }
544
545 if (request->state == RUN_MKCOL) {
546 if (request->curl_result == CURLE_OK ||
547 request->http_code == 405) {
548 remote_dir_exists[request->obj->oid.hash[0]] = 1;
549 start_put(request);
550 } else {
551 fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
552 oid_to_hex(&request->obj->oid),
553 request->curl_result, request->http_code);
554 request->state = ABORTED;
555 aborted = 1;
556 }
557 } else if (request->state == RUN_PUT) {
558 if (request->curl_result == CURLE_OK) {
559 start_move(request);
560 } else {
561 fprintf(stderr, "PUT %s failed, aborting (%d/%ld)\n",
562 oid_to_hex(&request->obj->oid),
563 request->curl_result, request->http_code);
564 request->state = ABORTED;
565 aborted = 1;
566 }
567 } else if (request->state == RUN_MOVE) {
568 if (request->curl_result == CURLE_OK) {
569 if (push_verbosely)
570 fprintf(stderr, " sent %s\n",
571 oid_to_hex(&request->obj->oid));
572 request->obj->flags |= REMOTE;
573 release_request(request);
574 } else {
575 fprintf(stderr, "MOVE %s failed, aborting (%d/%ld)\n",
576 oid_to_hex(&request->obj->oid),
577 request->curl_result, request->http_code);
578 request->state = ABORTED;
579 aborted = 1;
580 }
581 } else if (request->state == RUN_FETCH_LOOSE) {
582 obj_req = (struct http_object_request *)request->userData;
583
584 if (finish_http_object_request(obj_req) == 0)
585 if (obj_req->rename == 0)
586 request->obj->flags |= (LOCAL | REMOTE);
587
588 release_http_object_request(&obj_req);
589
590 /* Try fetching packed if necessary */
591 if (request->obj->flags & LOCAL) {
592 release_request(request);
593 } else
594 start_fetch_packed(request);
595
596 } else if (request->state == RUN_FETCH_PACKED) {
597 int fail = 1;
598 if (request->curl_result != CURLE_OK &&
599 request->http_code != 416) {
600 fprintf(stderr, "Unable to get pack file %s\n%s",
601 request->url, curl_errorstr);
602 } else {
603 preq = (struct http_pack_request *)request->userData;
604
605 if (preq) {
606 if (finish_http_pack_request(preq) == 0)
607 fail = 0;
608 release_http_pack_request(preq);
609 }
610 }
611 if (fail)
612 repo->can_update_info_refs = 0;
613 else
614 http_install_packfile(request->target, &repo->packs);
615 release_request(request);
616 }
617 }
618
619 static int is_running_queue;
620 static int fill_active_slot(void *data UNUSED)
621 {
622 struct transfer_request *request;
623
624 if (aborted || !is_running_queue)
625 return 0;
626
627 for (request = request_queue_head; request; request = request->next) {
628 if (request->state == NEED_FETCH) {
629 start_fetch_loose(request);
630 return 1;
631 } else if (pushing && request->state == NEED_PUSH) {
632 if (remote_dir_exists[request->obj->oid.hash[0]] == 1) {
633 start_put(request);
634 } else {
635 start_mkcol(request);
636 }
637 return 1;
638 }
639 }
640 return 0;
641 }
642
643 static void get_remote_object_list(unsigned char parent);
644
645 static void add_fetch_request(struct object *obj)
646 {
647 struct transfer_request *request;
648
649 check_locks();
650
651 /*
652 * Don't fetch the object if it's known to exist locally
653 * or is already in the request queue
654 */
655 if (remote_dir_exists[obj->oid.hash[0]] == -1)
656 get_remote_object_list(obj->oid.hash[0]);
657 if (obj->flags & (LOCAL | FETCHING))
658 return;
659
660 obj->flags |= FETCHING;
661 CALLOC_ARRAY(request, 1);
662 request->obj = obj;
663 request->state = NEED_FETCH;
664 strbuf_init(&request->buffer.buf, 0);
665 request->next = request_queue_head;
666 request_queue_head = request;
667
668 fill_active_slots();
669 step_active_slots();
670 }
671
672 static int add_send_request(struct object *obj, struct remote_lock *lock)
673 {
674 struct transfer_request *request;
675 struct packed_git *target;
676
677 /* Keep locks active */
678 check_locks();
679
680 /*
681 * Don't push the object if it's known to exist on the remote
682 * or is already in the request queue
683 */
684 if (remote_dir_exists[obj->oid.hash[0]] == -1)
685 get_remote_object_list(obj->oid.hash[0]);
686 if (obj->flags & (REMOTE | PUSHING))
687 return 0;
688 target = packfile_list_find_oid(repo->packs.head, &obj->oid);
689 if (target) {
690 obj->flags |= REMOTE;
691 return 0;
692 }
693
694 obj->flags |= PUSHING;
695 CALLOC_ARRAY(request, 1);
696 request->obj = obj;
697 request->lock = lock;
698 request->state = NEED_PUSH;
699 strbuf_init(&request->buffer.buf, 0);
700 request->next = request_queue_head;
701 request_queue_head = request;
702
703 fill_active_slots();
704 step_active_slots();
705
706 return 1;
707 }
708
709 static int fetch_indices(void)
710 {
711 int ret;
712
713 if (push_verbosely)
714 fprintf(stderr, "Getting pack list\n");
715
716 switch (http_get_info_packs(repo->url, &repo->packs)) {
717 case HTTP_OK:
718 case HTTP_MISSING_TARGET:
719 ret = 0;
720 break;
721 default:
722 ret = -1;
723 }
724
725 return ret;
726 }
727
728 static void one_remote_object(const struct object_id *oid)
729 {
730 struct object *obj;
731
732 obj = lookup_object(the_repository, oid);
733 if (!obj)
734 obj = parse_object(the_repository, oid);
735
736 /* Ignore remote objects that don't exist locally */
737 if (!obj)
738 return;
739
740 obj->flags |= REMOTE;
741 if (!object_list_contains(objects, obj))
742 object_list_insert(obj, &objects);
743 }
744
745 static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed)
746 {
747 int *lock_flags = (int *)ctx->userData;
748
749 if (tag_closed) {
750 if (!strcmp(ctx->name, DAV_CTX_LOCKENTRY)) {
751 if ((*lock_flags & DAV_PROP_LOCKEX) &&
752 (*lock_flags & DAV_PROP_LOCKWR)) {
753 *lock_flags |= DAV_LOCK_OK;
754 }
755 *lock_flags &= DAV_LOCK_OK;
756 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_WRITE)) {
757 *lock_flags |= DAV_PROP_LOCKWR;
758 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_EXCLUSIVE)) {
759 *lock_flags |= DAV_PROP_LOCKEX;
760 }
761 }
762 }
763
764 static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
765 {
766 struct remote_lock *lock = (struct remote_lock *)ctx->userData;
767 struct git_hash_ctx hash_ctx;
768 unsigned char lock_token_hash[GIT_MAX_RAWSZ];
769
770 if (tag_closed && ctx->cdata) {
771 if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
772 lock->owner = xstrdup(ctx->cdata);
773 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
774 const char *arg;
775 if (skip_prefix(ctx->cdata, "Second-", &arg))
776 lock->timeout = strtol(arg, NULL, 10);
777 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
778 lock->token = xstrdup(ctx->cdata);
779
780 git_hash_init(&hash_ctx, the_hash_algo);
781 git_hash_update(&hash_ctx, lock->token, strlen(lock->token));
782 git_hash_final(lock_token_hash, &hash_ctx);
783
784 lock->tmpfile_suffix[0] = '_';
785 memcpy(lock->tmpfile_suffix + 1, hash_to_hex(lock_token_hash), the_hash_algo->hexsz);
786 }
787 }
788 }
789
790 static void one_remote_ref(const char *refname);
791
792 static void
793 xml_start_tag(void *userData, const char *name, const char **atts UNUSED)
794 {
795 struct xml_ctx *ctx = (struct xml_ctx *)userData;
796 const char *c = strchr(name, ':');
797 int old_namelen, new_len;
798
799 if (!c)
800 c = name;
801 else
802 c++;
803
804 old_namelen = strlen(ctx->name);
805 new_len = old_namelen + strlen(c) + 2;
806
807 if (new_len > ctx->len) {
808 ctx->name = xrealloc(ctx->name, new_len);
809 ctx->len = new_len;
810 }
811 xsnprintf(ctx->name + old_namelen, ctx->len - old_namelen, ".%s", c);
812
813 FREE_AND_NULL(ctx->cdata);
814
815 ctx->userFunc(ctx, 0);
816 }
817
818 static void
819 xml_end_tag(void *userData, const char *name)
820 {
821 struct xml_ctx *ctx = (struct xml_ctx *)userData;
822 const char *c = strchr(name, ':');
823 char *ep;
824
825 ctx->userFunc(ctx, 1);
826
827 if (!c)
828 c = name;
829 else
830 c++;
831
832 ep = ctx->name + strlen(ctx->name) - strlen(c) - 1;
833 *ep = 0;
834 }
835
836 static void
837 xml_cdata(void *userData, const XML_Char *s, int len)
838 {
839 struct xml_ctx *ctx = (struct xml_ctx *)userData;
840 free(ctx->cdata);
841 ctx->cdata = xmemdupz(s, len);
842 }
843
844 static struct remote_lock *lock_remote(const char *path, long timeout)
845 {
846 struct active_request_slot *slot;
847 struct slot_results results;
848 struct buffer out_buffer = { STRBUF_INIT, 0 };
849 struct strbuf in_buffer = STRBUF_INIT;
850 char *url;
851 char *ep;
852 char timeout_header[25];
853 struct remote_lock *lock = NULL;
854 struct curl_slist *dav_headers = http_copy_default_headers();
855 struct xml_ctx ctx;
856 char *escaped;
857
858 url = xstrfmt("%s%s", repo->url, path);
859
860 /* Make sure leading directories exist for the remote ref */
861 ep = strchr(url + strlen(repo->url) + 1, '/');
862 while (ep) {
863 char saved_character = ep[1];
864 ep[1] = '\0';
865 slot = get_active_slot();
866 slot->results = &results;
867 curl_setup_http_get(slot->curl, url, DAV_MKCOL);
868 if (start_active_slot(slot)) {
869 run_active_slot(slot);
870 if (results.curl_result != CURLE_OK &&
871 results.http_code != 405) {
872 fprintf(stderr,
873 "Unable to create branch path %s\n",
874 url);
875 free(url);
876 return NULL;
877 }
878 } else {
879 fprintf(stderr, "Unable to start MKCOL request\n");
880 free(url);
881 return NULL;
882 }
883 ep[1] = saved_character;
884 ep = strchr(ep + 1, '/');
885 }
886
887 escaped = xml_entities(ident_default_email());
888 strbuf_addf(&out_buffer.buf, LOCK_REQUEST, escaped);
889 free(escaped);
890
891 xsnprintf(timeout_header, sizeof(timeout_header), "Timeout: Second-%ld", timeout);
892 dav_headers = curl_slist_append(dav_headers, timeout_header);
893 dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
894
895 slot = get_active_slot();
896 slot->results = &results;
897 curl_setup_http(slot->curl, url, DAV_LOCK, &out_buffer, fwrite_buffer);
898 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
899 curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &in_buffer);
900
901 CALLOC_ARRAY(lock, 1);
902 lock->timeout = -1;
903
904 if (start_active_slot(slot)) {
905 run_active_slot(slot);
906 if (results.curl_result == CURLE_OK) {
907 XML_Parser parser = XML_ParserCreate(NULL);
908 enum XML_Status result;
909 ctx.name = xcalloc(10, 1);
910 ctx.len = 0;
911 ctx.cdata = NULL;
912 ctx.userFunc = handle_new_lock_ctx;
913 ctx.userData = lock;
914 XML_SetUserData(parser, &ctx);
915 XML_SetElementHandler(parser, xml_start_tag,
916 xml_end_tag);
917 XML_SetCharacterDataHandler(parser, xml_cdata);
918 result = XML_Parse(parser, in_buffer.buf,
919 in_buffer.len, 1);
920 free(ctx.name);
921 free(ctx.cdata);
922 if (result != XML_STATUS_OK) {
923 fprintf(stderr, "XML error: %s\n",
924 XML_ErrorString(
925 XML_GetErrorCode(parser)));
926 lock->timeout = -1;
927 }
928 XML_ParserFree(parser);
929 } else {
930 fprintf(stderr,
931 "error: curl result=%d, HTTP code=%ld\n",
932 results.curl_result, results.http_code);
933 }
934 } else {
935 fprintf(stderr, "Unable to start LOCK request\n");
936 }
937
938 curl_slist_free_all(dav_headers);
939 strbuf_release(&out_buffer.buf);
940 strbuf_release(&in_buffer);
941
942 if (lock->token == NULL || lock->timeout <= 0) {
943 free(lock->token);
944 free(lock->owner);
945 free(url);
946 FREE_AND_NULL(lock);
947 } else {
948 lock->url = url;
949 lock->start_time = time(NULL);
950 lock->next = repo->locks;
951 repo->locks = lock;
952 }
953
954 return lock;
955 }
956
957 static int unlock_remote(struct remote_lock *lock)
958 {
959 struct active_request_slot *slot;
960 struct slot_results results;
961 struct remote_lock *prev = repo->locks;
962 struct curl_slist *dav_headers;
963 int rc = 0;
964
965 dav_headers = get_dav_token_headers(lock, DAV_HEADER_LOCK);
966
967 slot = get_active_slot();
968 slot->results = &results;
969 curl_setup_http_get(slot->curl, lock->url, DAV_UNLOCK);
970 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
971
972 if (start_active_slot(slot)) {
973 run_active_slot(slot);
974 if (results.curl_result == CURLE_OK)
975 rc = 1;
976 else
977 fprintf(stderr, "UNLOCK HTTP error %ld\n",
978 results.http_code);
979 } else {
980 fprintf(stderr, "Unable to start UNLOCK request\n");
981 }
982
983 curl_slist_free_all(dav_headers);
984
985 if (repo->locks == lock) {
986 repo->locks = lock->next;
987 } else {
988 while (prev && prev->next != lock)
989 prev = prev->next;
990 if (prev)
991 prev->next = lock->next;
992 }
993
994 free(lock->owner);
995 free(lock->url);
996 free(lock->token);
997 free(lock);
998
999 return rc;
1000 }
1001
1002 static void remove_locks(void)
1003 {
1004 struct remote_lock *lock = repo->locks;
1005
1006 fprintf(stderr, "Removing remote locks...\n");
1007 while (lock) {
1008 struct remote_lock *next = lock->next;
1009 unlock_remote(lock);
1010 lock = next;
1011 }
1012 }
1013
1014 static void remove_locks_on_signal(int signo)
1015 {
1016 remove_locks();
1017 sigchain_pop(signo);
1018 raise(signo);
1019 }
1020
1021 static void remote_ls(const char *path, int flags,
1022 void (*userFunc)(struct remote_ls_ctx *ls),
1023 void *userData);
1024
1025 /* extract hex from sharded "xx/x{38}" filename */
1026 static int get_oid_hex_from_objpath(const char *path, struct object_id *oid)
1027 {
1028 memset(oid->hash, 0, GIT_MAX_RAWSZ);
1029 oid->algo = hash_algo_by_ptr(the_hash_algo);
1030
1031 if (strlen(path) != the_hash_algo->hexsz + 1)
1032 return -1;
1033
1034 if (hex_to_bytes(oid->hash, path, 1))
1035 return -1;
1036 path += 2;
1037 path++; /* skip '/' */
1038
1039 return hex_to_bytes(oid->hash + 1, path, the_hash_algo->rawsz - 1);
1040 }
1041
1042 static void process_ls_object(struct remote_ls_ctx *ls)
1043 {
1044 unsigned int *parent = (unsigned int *)ls->userData;
1045 const char *path = ls->dentry_name;
1046 struct object_id oid;
1047
1048 if (!strcmp(ls->path, ls->dentry_name) && (ls->flags & IS_DIR)) {
1049 remote_dir_exists[*parent] = 1;
1050 return;
1051 }
1052
1053 if (!skip_prefix(path, "objects/", &path) ||
1054 get_oid_hex_from_objpath(path, &oid))
1055 return;
1056
1057 one_remote_object(&oid);
1058 }
1059
1060 static void process_ls_ref(struct remote_ls_ctx *ls)
1061 {
1062 if (!strcmp(ls->path, ls->dentry_name) && (ls->dentry_flags & IS_DIR)) {
1063 fprintf(stderr, " %s\n", ls->dentry_name);
1064 return;
1065 }
1066
1067 if (!(ls->dentry_flags & IS_DIR))
1068 one_remote_ref(ls->dentry_name);
1069 }
1070
1071 static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
1072 {
1073 struct remote_ls_ctx *ls = (struct remote_ls_ctx *)ctx->userData;
1074
1075 if (tag_closed) {
1076 if (!strcmp(ctx->name, DAV_PROPFIND_RESP) && ls->dentry_name) {
1077 if (ls->dentry_flags & IS_DIR) {
1078
1079 /* ensure collection names end with slash */
1080 str_end_url_with_slash(ls->dentry_name, &ls->dentry_name);
1081
1082 if (ls->flags & PROCESS_DIRS) {
1083 ls->userFunc(ls);
1084 }
1085 if (strcmp(ls->dentry_name, ls->path) &&
1086 ls->flags & RECURSIVE) {
1087 remote_ls(ls->dentry_name,
1088 ls->flags,
1089 ls->userFunc,
1090 ls->userData);
1091 }
1092 } else if (ls->flags & PROCESS_FILES) {
1093 ls->userFunc(ls);
1094 }
1095 } else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
1096 char *path = ctx->cdata;
1097 if (*ctx->cdata == 'h') {
1098 path = strstr(path, "//");
1099 if (path) {
1100 path = strchr(path+2, '/');
1101 }
1102 }
1103 if (path) {
1104 const char *url = repo->url;
1105 if (repo->path)
1106 url = repo->path;
1107 if (strncmp(path, url, repo->path_len))
1108 error("Parsed path '%s' does not match url: '%s'",
1109 path, url);
1110 else {
1111 path += repo->path_len;
1112 ls->dentry_name = xstrdup(path);
1113 }
1114 }
1115 } else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
1116 ls->dentry_flags |= IS_DIR;
1117 }
1118 } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) {
1119 FREE_AND_NULL(ls->dentry_name);
1120 ls->dentry_flags = 0;
1121 }
1122 }
1123
1124 /*
1125 * NEEDSWORK: remote_ls() ignores info/refs on the remote side. But it
1126 * should _only_ heed the information from that file, instead of trying to
1127 * determine the refs from the remote file system (badly: it does not even
1128 * know about packed-refs).
1129 */
1130 static void remote_ls(const char *path, int flags,
1131 void (*userFunc)(struct remote_ls_ctx *ls),
1132 void *userData)
1133 {
1134 char *url = xstrfmt("%s%s", repo->url, path);
1135 struct active_request_slot *slot;
1136 struct slot_results results;
1137 struct strbuf in_buffer = STRBUF_INIT;
1138 struct buffer out_buffer = { STRBUF_INIT, 0 };
1139 struct curl_slist *dav_headers = http_copy_default_headers();
1140 struct xml_ctx ctx;
1141 struct remote_ls_ctx ls;
1142
1143 ls.flags = flags;
1144 ls.path = xstrdup(path);
1145 ls.dentry_name = NULL;
1146 ls.dentry_flags = 0;
1147 ls.userData = userData;
1148 ls.userFunc = userFunc;
1149
1150 strbuf_addstr(&out_buffer.buf, PROPFIND_ALL_REQUEST);
1151
1152 dav_headers = curl_slist_append(dav_headers, "Depth: 1");
1153 dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1154
1155 slot = get_active_slot();
1156 slot->results = &results;
1157 curl_setup_http(slot->curl, url, DAV_PROPFIND,
1158 &out_buffer, fwrite_buffer);
1159 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1160 curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &in_buffer);
1161
1162 if (start_active_slot(slot)) {
1163 run_active_slot(slot);
1164 if (results.curl_result == CURLE_OK) {
1165 XML_Parser parser = XML_ParserCreate(NULL);
1166 enum XML_Status result;
1167 ctx.name = xcalloc(10, 1);
1168 ctx.len = 0;
1169 ctx.cdata = NULL;
1170 ctx.userFunc = handle_remote_ls_ctx;
1171 ctx.userData = &ls;
1172 XML_SetUserData(parser, &ctx);
1173 XML_SetElementHandler(parser, xml_start_tag,
1174 xml_end_tag);
1175 XML_SetCharacterDataHandler(parser, xml_cdata);
1176 result = XML_Parse(parser, in_buffer.buf,
1177 in_buffer.len, 1);
1178 free(ctx.name);
1179 free(ctx.cdata);
1180
1181 if (result != XML_STATUS_OK) {
1182 fprintf(stderr, "XML error: %s\n",
1183 XML_ErrorString(
1184 XML_GetErrorCode(parser)));
1185 }
1186 XML_ParserFree(parser);
1187 }
1188 } else {
1189 fprintf(stderr, "Unable to start PROPFIND request\n");
1190 }
1191
1192 free(ls.path);
1193 free(ls.dentry_name);
1194 free(url);
1195 strbuf_release(&out_buffer.buf);
1196 strbuf_release(&in_buffer);
1197 curl_slist_free_all(dav_headers);
1198 }
1199
1200 static void get_remote_object_list(unsigned char parent)
1201 {
1202 char path[] = "objects/XX/";
1203 static const char hex[] = "0123456789abcdef";
1204 unsigned int val = parent;
1205
1206 path[8] = hex[val >> 4];
1207 path[9] = hex[val & 0xf];
1208 remote_dir_exists[val] = 0;
1209 remote_ls(path, (PROCESS_FILES | PROCESS_DIRS),
1210 process_ls_object, &val);
1211 }
1212
1213 static int locking_available(void)
1214 {
1215 struct active_request_slot *slot;
1216 struct slot_results results;
1217 struct strbuf in_buffer = STRBUF_INIT;
1218 struct buffer out_buffer = { STRBUF_INIT, 0 };
1219 struct curl_slist *dav_headers = http_copy_default_headers();
1220 struct xml_ctx ctx;
1221 int lock_flags = 0;
1222 char *escaped;
1223
1224 escaped = xml_entities(repo->url);
1225 strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, escaped);
1226 free(escaped);
1227
1228 dav_headers = curl_slist_append(dav_headers, "Depth: 0");
1229 dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1230
1231 slot = get_active_slot();
1232 slot->results = &results;
1233 curl_setup_http(slot->curl, repo->url, DAV_PROPFIND,
1234 &out_buffer, fwrite_buffer);
1235 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1236 curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &in_buffer);
1237
1238 if (start_active_slot(slot)) {
1239 run_active_slot(slot);
1240 if (results.curl_result == CURLE_OK) {
1241 XML_Parser parser = XML_ParserCreate(NULL);
1242 enum XML_Status result;
1243 ctx.name = xcalloc(10, 1);
1244 ctx.len = 0;
1245 ctx.cdata = NULL;
1246 ctx.userFunc = handle_lockprop_ctx;
1247 ctx.userData = &lock_flags;
1248 XML_SetUserData(parser, &ctx);
1249 XML_SetElementHandler(parser, xml_start_tag,
1250 xml_end_tag);
1251 result = XML_Parse(parser, in_buffer.buf,
1252 in_buffer.len, 1);
1253 free(ctx.name);
1254
1255 if (result != XML_STATUS_OK) {
1256 fprintf(stderr, "XML error: %s\n",
1257 XML_ErrorString(
1258 XML_GetErrorCode(parser)));
1259 lock_flags = 0;
1260 }
1261 XML_ParserFree(parser);
1262 if (!lock_flags)
1263 error("no DAV locking support on %s",
1264 repo->url);
1265
1266 } else {
1267 error("Cannot access URL %s, return code %d",
1268 repo->url, results.curl_result);
1269 lock_flags = 0;
1270 }
1271 } else {
1272 error("Unable to start PROPFIND request on %s", repo->url);
1273 }
1274
1275 strbuf_release(&out_buffer.buf);
1276 strbuf_release(&in_buffer);
1277 curl_slist_free_all(dav_headers);
1278
1279 return lock_flags;
1280 }
1281
1282 static struct object_list **add_one_object(struct object *obj, struct object_list **p)
1283 {
1284 struct object_list *entry = xmalloc(sizeof(struct object_list));
1285 entry->item = obj;
1286 entry->next = *p;
1287 *p = entry;
1288 return &entry->next;
1289 }
1290
1291 static struct object_list **process_blob(struct blob *blob,
1292 struct object_list **p)
1293 {
1294 struct object *obj = &blob->object;
1295
1296 obj->flags |= LOCAL;
1297
1298 if (obj->flags & (UNINTERESTING | SEEN))
1299 return p;
1300
1301 obj->flags |= SEEN;
1302 return add_one_object(obj, p);
1303 }
1304
1305 static struct object_list **process_tree(struct tree *tree,
1306 struct object_list **p)
1307 {
1308 struct object *obj = &tree->object;
1309 struct tree_desc desc;
1310 struct name_entry entry;
1311
1312 obj->flags |= LOCAL;
1313
1314 if (obj->flags & (UNINTERESTING | SEEN))
1315 return p;
1316 if (repo_parse_tree(the_repository, tree) < 0)
1317 die("bad tree object %s", oid_to_hex(&obj->oid));
1318
1319 obj->flags |= SEEN;
1320 p = add_one_object(obj, p);
1321
1322 init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
1323
1324 while (tree_entry(&desc, &entry))
1325 switch (object_type(entry.mode)) {
1326 case OBJ_TREE:
1327 p = process_tree(lookup_tree(the_repository, &entry.oid),
1328 p);
1329 break;
1330 case OBJ_BLOB:
1331 p = process_blob(lookup_blob(the_repository, &entry.oid),
1332 p);
1333 break;
1334 default:
1335 /* Subproject commit - not in this repository */
1336 break;
1337 }
1338
1339 free_tree_buffer(tree);
1340 return p;
1341 }
1342
1343 static int get_delta(struct rev_info *revs, struct remote_lock *lock)
1344 {
1345 struct commit *commit;
1346 struct object_list **p = &objects;
1347 int count = 0;
1348
1349 while ((commit = get_revision(revs)) != NULL) {
1350 p = process_tree(repo_get_commit_tree(the_repository, commit),
1351 p);
1352 commit->object.flags |= LOCAL;
1353 if (!(commit->object.flags & UNINTERESTING))
1354 count += add_send_request(&commit->object, lock);
1355 }
1356
1357 for (size_t i = 0; i < revs->pending.nr; i++) {
1358 struct object_array_entry *entry = revs->pending.objects + i;
1359 struct object *obj = entry->item;
1360 const char *name = entry->name;
1361
1362 if (obj->flags & (UNINTERESTING | SEEN))
1363 continue;
1364 if (obj->type == OBJ_TAG) {
1365 obj->flags |= SEEN;
1366 p = add_one_object(obj, p);
1367 continue;
1368 }
1369 if (obj->type == OBJ_TREE) {
1370 p = process_tree((struct tree *)obj, p);
1371 continue;
1372 }
1373 if (obj->type == OBJ_BLOB) {
1374 p = process_blob((struct blob *)obj, p);
1375 continue;
1376 }
1377 die("unknown pending object %s (%s)", oid_to_hex(&obj->oid), name);
1378 }
1379
1380 while (objects) {
1381 struct object_list *next = objects->next;
1382
1383 if (!(objects->item->flags & UNINTERESTING))
1384 count += add_send_request(objects->item, lock);
1385
1386 free(objects);
1387 objects = next;
1388 }
1389
1390 return count;
1391 }
1392
1393 static int update_remote(const struct object_id *oid, struct remote_lock *lock)
1394 {
1395 struct active_request_slot *slot;
1396 struct slot_results results;
1397 struct buffer out_buffer = { STRBUF_INIT, 0 };
1398 struct curl_slist *dav_headers;
1399
1400 dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF);
1401
1402 strbuf_addf(&out_buffer.buf, "%s\n", oid_to_hex(oid));
1403
1404 slot = get_active_slot();
1405 slot->results = &results;
1406 curl_setup_http(slot->curl, lock->url, DAV_PUT,
1407 &out_buffer, fwrite_null);
1408 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1409
1410 if (start_active_slot(slot)) {
1411 run_active_slot(slot);
1412 strbuf_release(&out_buffer.buf);
1413 curl_slist_free_all(dav_headers);
1414 if (results.curl_result != CURLE_OK) {
1415 fprintf(stderr,
1416 "PUT error: curl result=%d, HTTP code=%ld\n",
1417 results.curl_result, results.http_code);
1418 /* We should attempt recovery? */
1419 return 0;
1420 }
1421 } else {
1422 strbuf_release(&out_buffer.buf);
1423 curl_slist_free_all(dav_headers);
1424 fprintf(stderr, "Unable to start PUT request\n");
1425 return 0;
1426 }
1427
1428 return 1;
1429 }
1430
1431 static struct ref *remote_refs;
1432
1433 static void one_remote_ref(const char *refname)
1434 {
1435 struct ref *ref;
1436 struct object *obj;
1437
1438 ref = alloc_ref(refname);
1439
1440 if (http_fetch_ref(repo->url, ref) != 0) {
1441 fprintf(stderr,
1442 "Unable to fetch ref %s from %s\n",
1443 refname, repo->url);
1444 free(ref);
1445 return;
1446 }
1447
1448 /*
1449 * Fetch a copy of the object if it doesn't exist locally - it
1450 * may be required for updating server info later.
1451 */
1452 if (repo->can_update_info_refs &&
1453 !odb_has_object(the_repository->objects, &ref->old_oid,
1454 ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR)) {
1455 obj = lookup_unknown_object(the_repository, &ref->old_oid);
1456 fprintf(stderr, " fetch %s for %s\n",
1457 oid_to_hex(&ref->old_oid), refname);
1458 add_fetch_request(obj);
1459 }
1460
1461 ref->next = remote_refs;
1462 remote_refs = ref;
1463 }
1464
1465 static void get_dav_remote_heads(void)
1466 {
1467 remote_ls("refs/", (PROCESS_FILES | PROCESS_DIRS | RECURSIVE), process_ls_ref, NULL);
1468 }
1469
1470 static void add_remote_info_ref(struct remote_ls_ctx *ls)
1471 {
1472 struct strbuf *buf = (struct strbuf *)ls->userData;
1473 struct object *o;
1474 struct ref *ref;
1475
1476 ref = alloc_ref(ls->dentry_name);
1477
1478 if (http_fetch_ref(repo->url, ref) != 0) {
1479 fprintf(stderr,
1480 "Unable to fetch ref %s from %s\n",
1481 ls->dentry_name, repo->url);
1482 aborted = 1;
1483 free(ref);
1484 return;
1485 }
1486
1487 o = parse_object(the_repository, &ref->old_oid);
1488 if (!o) {
1489 fprintf(stderr,
1490 "Unable to parse object %s for remote ref %s\n",
1491 oid_to_hex(&ref->old_oid), ls->dentry_name);
1492 aborted = 1;
1493 free(ref);
1494 return;
1495 }
1496
1497 strbuf_addf(buf, "%s\t%s\n",
1498 oid_to_hex(&ref->old_oid), ls->dentry_name);
1499
1500 if (o->type == OBJ_TAG) {
1501 o = deref_tag(the_repository, o, ls->dentry_name, 0);
1502 if (o)
1503 strbuf_addf(buf, "%s\t%s^{}\n",
1504 oid_to_hex(&o->oid), ls->dentry_name);
1505 }
1506 free(ref);
1507 }
1508
1509 static void update_remote_info_refs(struct remote_lock *lock)
1510 {
1511 struct buffer buffer = { STRBUF_INIT, 0 };
1512 struct active_request_slot *slot;
1513 struct slot_results results;
1514 struct curl_slist *dav_headers;
1515
1516 remote_ls("refs/", (PROCESS_FILES | RECURSIVE),
1517 add_remote_info_ref, &buffer.buf);
1518 if (!aborted) {
1519 dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF);
1520
1521 slot = get_active_slot();
1522 slot->results = &results;
1523 curl_setup_http(slot->curl, lock->url, DAV_PUT,
1524 &buffer, fwrite_null);
1525 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1526
1527 if (start_active_slot(slot)) {
1528 run_active_slot(slot);
1529 if (results.curl_result != CURLE_OK) {
1530 fprintf(stderr,
1531 "PUT error: curl result=%d, HTTP code=%ld\n",
1532 results.curl_result, results.http_code);
1533 }
1534 }
1535 curl_slist_free_all(dav_headers);
1536 }
1537 strbuf_release(&buffer.buf);
1538 }
1539
1540 static int remote_exists(const char *path)
1541 {
1542 char *url = xstrfmt("%s%s", repo->url, path);
1543 int ret;
1544
1545
1546 switch (http_get_strbuf(url, NULL, NULL)) {
1547 case HTTP_OK:
1548 ret = 1;
1549 break;
1550 case HTTP_MISSING_TARGET:
1551 ret = 0;
1552 break;
1553 case HTTP_ERROR:
1554 error("unable to access '%s': %s", url, curl_errorstr);
1555 /* fallthrough */
1556 default:
1557 ret = -1;
1558 }
1559 free(url);
1560 return ret;
1561 }
1562
1563 static void fetch_symref(const char *path, char **symref, struct object_id *oid)
1564 {
1565 char *url = xstrfmt("%s%s", repo->url, path);
1566 struct strbuf buffer = STRBUF_INIT;
1567 const char *name;
1568
1569 if (http_get_strbuf(url, &buffer, NULL) != HTTP_OK)
1570 die("Couldn't get %s for remote symref\n%s", url,
1571 curl_errorstr);
1572 free(url);
1573
1574 FREE_AND_NULL(*symref);
1575 oidclr(oid, the_repository->hash_algo);
1576
1577 if (buffer.len == 0)
1578 return;
1579
1580 /* Cut off trailing newline. */
1581 strbuf_rtrim(&buffer);
1582
1583 /* If it's a symref, set the refname; otherwise try for a sha1 */
1584 if (skip_prefix(buffer.buf, "ref: ", &name)) {
1585 *symref = xmemdupz(name, buffer.len - (name - buffer.buf));
1586 } else {
1587 get_oid_hex(buffer.buf, oid);
1588 }
1589
1590 strbuf_release(&buffer);
1591 }
1592
1593 static int verify_merge_base(struct object_id *head_oid, struct ref *remote)
1594 {
1595 struct commit *head = lookup_commit_or_die(head_oid, "HEAD");
1596 struct commit *branch = lookup_commit_or_die(&remote->old_oid,
1597 remote->name);
1598 int ret = repo_in_merge_bases(the_repository, branch, head);
1599
1600 if (ret < 0)
1601 exit(128);
1602 return ret;
1603 }
1604
1605 static int delete_remote_branch(const char *pattern, int force)
1606 {
1607 struct ref *refs = remote_refs;
1608 struct ref *remote_ref = NULL;
1609 struct object_id head_oid;
1610 char *symref = NULL;
1611 int match;
1612 int patlen = strlen(pattern);
1613 int i;
1614 struct active_request_slot *slot;
1615 struct slot_results results;
1616 char *url;
1617
1618 /* Find the remote branch(es) matching the specified branch name */
1619 for (match = 0; refs; refs = refs->next) {
1620 char *name = refs->name;
1621 int namelen = strlen(name);
1622 if (namelen < patlen ||
1623 memcmp(name + namelen - patlen, pattern, patlen))
1624 continue;
1625 if (namelen != patlen && name[namelen - patlen - 1] != '/')
1626 continue;
1627 match++;
1628 remote_ref = refs;
1629 }
1630 if (match == 0)
1631 return error("No remote branch matches %s", pattern);
1632 if (match != 1)
1633 return error("More than one remote branch matches %s",
1634 pattern);
1635
1636 /*
1637 * Remote HEAD must be a symref (not exactly foolproof; a remote
1638 * symlink to a symref will look like a symref)
1639 */
1640 fetch_symref("HEAD", &symref, &head_oid);
1641 if (!symref)
1642 return error("Remote HEAD is not a symref");
1643
1644 /* Remote branch must not be the remote HEAD */
1645 for (i = 0; symref && i < MAXDEPTH; i++) {
1646 if (!strcmp(remote_ref->name, symref))
1647 return error("Remote branch %s is the current HEAD",
1648 remote_ref->name);
1649 fetch_symref(symref, &symref, &head_oid);
1650 }
1651
1652 /* Run extra sanity checks if delete is not forced */
1653 if (!force) {
1654 /* Remote HEAD must resolve to a known object */
1655 if (symref)
1656 return error("Remote HEAD symrefs too deep");
1657 if (is_null_oid(&head_oid))
1658 return error("Unable to resolve remote HEAD");
1659 if (!odb_has_object(the_repository->objects, &head_oid,
1660 ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))
1661 return error("Remote HEAD resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", oid_to_hex(&head_oid));
1662
1663 /* Remote branch must resolve to a known object */
1664 if (is_null_oid(&remote_ref->old_oid))
1665 return error("Unable to resolve remote branch %s",
1666 remote_ref->name);
1667 if (!odb_has_object(the_repository->objects, &remote_ref->old_oid,
1668 ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))
1669 return error("Remote branch %s resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", remote_ref->name, oid_to_hex(&remote_ref->old_oid));
1670
1671 /* Remote branch must be an ancestor of remote HEAD */
1672 if (!verify_merge_base(&head_oid, remote_ref)) {
1673 return error("The branch '%s' is not an ancestor "
1674 "of your current HEAD.\n"
1675 "If you are sure you want to delete it,"
1676 " run:\n\t'git http-push -D %s %s'",
1677 remote_ref->name, repo->url, pattern);
1678 }
1679 }
1680
1681 /* Send delete request */
1682 fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
1683 if (dry_run)
1684 return 0;
1685 url = xstrfmt("%s%s", repo->url, remote_ref->name);
1686 slot = get_active_slot();
1687 slot->results = &results;
1688 curl_setup_http_get(slot->curl, url, DAV_DELETE);
1689 if (start_active_slot(slot)) {
1690 run_active_slot(slot);
1691 free(url);
1692 if (results.curl_result != CURLE_OK)
1693 return error("DELETE request failed (%d/%ld)",
1694 results.curl_result, results.http_code);
1695 } else {
1696 free(url);
1697 return error("Unable to start DELETE request");
1698 }
1699
1700 return 0;
1701 }
1702
1703 static void run_request_queue(void)
1704 {
1705 is_running_queue = 1;
1706 fill_active_slots();
1707 add_fill_function(NULL, fill_active_slot);
1708 do {
1709 finish_all_active_slots();
1710 fill_active_slots();
1711 } while (request_queue_head && !aborted);
1712
1713 is_running_queue = 0;
1714 }
1715
1716 int cmd_main(int argc, const char **argv)
1717 {
1718 struct transfer_request *request;
1719 struct transfer_request *next_request;
1720 struct refspec rs = REFSPEC_INIT_PUSH(the_hash_algo);
1721 struct remote_lock *ref_lock = NULL;
1722 struct remote_lock *info_ref_lock = NULL;
1723 int delete_branch = 0;
1724 int force_delete = 0;
1725 int objects_to_send;
1726 int rc = 0;
1727 int i;
1728 int new_refs;
1729 struct ref *ref, *local_refs = NULL;
1730 const char *gitdir;
1731
1732 CALLOC_ARRAY(repo, 1);
1733
1734 argv++;
1735 for (i = 1; i < argc; i++, argv++) {
1736 const char *arg = *argv;
1737
1738 if (*arg == '-') {
1739 if (!strcmp(arg, "--all")) {
1740 push_all = MATCH_REFS_ALL;
1741 continue;
1742 }
1743 if (!strcmp(arg, "--force")) {
1744 force_all = 1;
1745 continue;
1746 }
1747 if (!strcmp(arg, "--dry-run")) {
1748 dry_run = 1;
1749 continue;
1750 }
1751 if (!strcmp(arg, "--helper-status")) {
1752 helper_status = 1;
1753 continue;
1754 }
1755 if (!strcmp(arg, "--verbose")) {
1756 push_verbosely = 1;
1757 http_is_verbose = 1;
1758 continue;
1759 }
1760 if (!strcmp(arg, "-d")) {
1761 delete_branch = 1;
1762 continue;
1763 }
1764 if (!strcmp(arg, "-D")) {
1765 delete_branch = 1;
1766 force_delete = 1;
1767 continue;
1768 }
1769 if (!strcmp(arg, "-h"))
1770 usage(http_push_usage);
1771 }
1772 if (!repo->url) {
1773 const char *path = strstr(arg, "//");
1774 str_end_url_with_slash(arg, &repo->url);
1775 repo->path_len = strlen(repo->url);
1776 if (path) {
1777 repo->path = strchr(path+2, '/');
1778 if (repo->path)
1779 repo->path_len = strlen(repo->path);
1780 }
1781 continue;
1782 }
1783 refspec_appendn(&rs, argv, argc - i);
1784 break;
1785 }
1786
1787 if (!repo->url)
1788 usage(http_push_usage);
1789
1790 if (delete_branch && rs.nr != 1)
1791 die("You must specify only one branch name when deleting a remote branch");
1792
1793 gitdir = setup_git_directory(the_repository);
1794
1795 memset(remote_dir_exists, -1, 256);
1796
1797 http_init(NULL, repo->url, 1);
1798
1799 is_running_queue = 0;
1800
1801 /* Verify DAV compliance/lock support */
1802 if (!locking_available()) {
1803 rc = 1;
1804 goto cleanup;
1805 }
1806
1807 sigchain_push_common(remove_locks_on_signal);
1808
1809 /* Check whether the remote has server info files */
1810 repo->can_update_info_refs = 0;
1811 repo->has_info_refs = remote_exists("info/refs");
1812 repo->has_info_packs = remote_exists("objects/info/packs");
1813 if (repo->has_info_refs) {
1814 info_ref_lock = lock_remote("info/refs", LOCK_TIME);
1815 if (info_ref_lock)
1816 repo->can_update_info_refs = 1;
1817 else {
1818 error("cannot lock existing info/refs");
1819 rc = 1;
1820 goto cleanup;
1821 }
1822 }
1823 if (repo->has_info_packs)
1824 fetch_indices();
1825
1826 /* Get a list of all local and remote heads to validate refspecs */
1827 local_refs = get_local_heads();
1828 fprintf(stderr, "Fetching remote heads...\n");
1829 get_dav_remote_heads();
1830 run_request_queue();
1831
1832 /* Remove a remote branch if -d or -D was specified */
1833 if (delete_branch) {
1834 const char *branch = rs.items[i].src;
1835 if (delete_remote_branch(branch, force_delete) == -1) {
1836 fprintf(stderr, "Unable to delete remote branch %s\n",
1837 branch);
1838 if (helper_status)
1839 printf("error %s cannot remove\n", branch);
1840 }
1841 goto cleanup;
1842 }
1843
1844 /* match them up */
1845 if (match_push_refs(local_refs, &remote_refs, &rs, push_all)) {
1846 rc = -1;
1847 goto cleanup;
1848 }
1849 if (!remote_refs) {
1850 fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
1851 if (helper_status)
1852 printf("error null no match\n");
1853 rc = 0;
1854 goto cleanup;
1855 }
1856
1857 new_refs = 0;
1858 for (ref = remote_refs; ref; ref = ref->next) {
1859 struct rev_info revs;
1860 struct strvec commit_argv = STRVEC_INIT;
1861
1862 if (!ref->peer_ref)
1863 continue;
1864
1865 if (is_null_oid(&ref->peer_ref->new_oid)) {
1866 if (delete_remote_branch(ref->name, 1) == -1) {
1867 error("Could not remove %s", ref->name);
1868 if (helper_status)
1869 printf("error %s cannot remove\n", ref->name);
1870 rc = -4;
1871 }
1872 else if (helper_status)
1873 printf("ok %s\n", ref->name);
1874 new_refs++;
1875 continue;
1876 }
1877
1878 if (oideq(&ref->old_oid, &ref->peer_ref->new_oid)) {
1879 if (push_verbosely)
1880 /* stable plumbing output; do not modify or localize */
1881 fprintf(stderr, "'%s': up-to-date\n", ref->name);
1882 if (helper_status)
1883 printf("ok %s up to date\n", ref->name);
1884 continue;
1885 }
1886
1887 if (!force_all &&
1888 !is_null_oid(&ref->old_oid) &&
1889 !ref->force) {
1890 if (!odb_has_object(the_repository->objects, &ref->old_oid,
1891 ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR) ||
1892 !ref_newer(&ref->peer_ref->new_oid,
1893 &ref->old_oid)) {
1894 /*
1895 * We do not have the remote ref, or
1896 * we know that the remote ref is not
1897 * an ancestor of what we are trying to
1898 * push. Either way this can be losing
1899 * commits at the remote end and likely
1900 * we were not up to date to begin with.
1901 */
1902 /* stable plumbing output; do not modify or localize */
1903 error("remote '%s' is not an ancestor of\n"
1904 "local '%s'.\n"
1905 "Maybe you are not up-to-date and "
1906 "need to pull first?",
1907 ref->name,
1908 ref->peer_ref->name);
1909 if (helper_status)
1910 printf("error %s non-fast forward\n", ref->name);
1911 rc = -2;
1912 continue;
1913 }
1914 }
1915 oidcpy(&ref->new_oid, &ref->peer_ref->new_oid);
1916 new_refs++;
1917
1918 fprintf(stderr, "updating '%s'", ref->name);
1919 if (strcmp(ref->name, ref->peer_ref->name))
1920 fprintf(stderr, " using '%s'", ref->peer_ref->name);
1921 fprintf(stderr, "\n from %s\n to %s\n",
1922 oid_to_hex(&ref->old_oid), oid_to_hex(&ref->new_oid));
1923 if (dry_run) {
1924 if (helper_status)
1925 printf("ok %s\n", ref->name);
1926 continue;
1927 }
1928
1929 /* Lock remote branch ref */
1930 ref_lock = lock_remote(ref->name, LOCK_TIME);
1931 if (!ref_lock) {
1932 fprintf(stderr, "Unable to lock remote branch %s\n",
1933 ref->name);
1934 if (helper_status)
1935 printf("error %s lock error\n", ref->name);
1936 rc = 1;
1937 continue;
1938 }
1939
1940 /* Set up revision info for this refspec */
1941 strvec_push(&commit_argv, ""); /* ignored */
1942 strvec_push(&commit_argv, "--objects");
1943 strvec_push(&commit_argv, oid_to_hex(&ref->new_oid));
1944 if (!push_all && !is_null_oid(&ref->old_oid))
1945 strvec_pushf(&commit_argv, "^%s",
1946 oid_to_hex(&ref->old_oid));
1947 repo_init_revisions(the_repository, &revs, gitdir);
1948 setup_revisions_from_strvec(&commit_argv, &revs, NULL);
1949 revs.edge_hint = 0; /* just in case */
1950
1951 /* Generate a list of objects that need to be pushed */
1952 pushing = 0;
1953 if (prepare_revision_walk(&revs))
1954 die("revision walk setup failed");
1955 mark_edges_uninteresting(&revs, NULL, 0);
1956 objects_to_send = get_delta(&revs, ref_lock);
1957 finish_all_active_slots();
1958
1959 /* Push missing objects to remote, this would be a
1960 convenient time to pack them first if appropriate. */
1961 pushing = 1;
1962 if (objects_to_send)
1963 fprintf(stderr, " sending %d objects\n",
1964 objects_to_send);
1965
1966 run_request_queue();
1967
1968 /* Update the remote branch if all went well */
1969 if (aborted || !update_remote(&ref->new_oid, ref_lock))
1970 rc = 1;
1971
1972 if (!rc)
1973 fprintf(stderr, " done\n");
1974 if (helper_status)
1975 printf("%s %s\n", !rc ? "ok" : "error", ref->name);
1976 unlock_remote(ref_lock);
1977 check_locks();
1978 strvec_clear(&commit_argv);
1979 release_revisions(&revs);
1980 }
1981
1982 /* Update remote server info if appropriate */
1983 if (repo->has_info_refs && new_refs) {
1984 if (info_ref_lock && repo->can_update_info_refs) {
1985 fprintf(stderr, "Updating remote server info\n");
1986 if (!dry_run)
1987 update_remote_info_refs(info_ref_lock);
1988 } else {
1989 fprintf(stderr, "Unable to update server info\n");
1990 }
1991 }
1992
1993 cleanup:
1994 if (info_ref_lock)
1995 unlock_remote(info_ref_lock);
1996 free(repo->url);
1997 free(repo);
1998
1999 http_cleanup();
2000
2001 request = request_queue_head;
2002 while (request != NULL) {
2003 next_request = request->next;
2004 release_request(request);
2005 request = next_request;
2006 }
2007
2008 refspec_clear(&rs);
2009 free_refs(local_refs);
2010
2011 return rc;
2012 }