rugged 0.25.0b2 → 0.25.0b3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/ext/rugged/extconf.rb +3 -1
- data/ext/rugged/rugged.c +1 -1
- data/ext/rugged/rugged.h +1 -1
- data/ext/rugged/rugged_blob.c +29 -38
- data/ext/rugged/rugged_commit.c +215 -78
- data/ext/rugged/rugged_rebase.c +18 -11
- data/ext/rugged/rugged_remote.c +2 -2
- data/ext/rugged/rugged_tree.c +132 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +11 -3
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/include/git2/blob.h +39 -28
- data/vendor/libgit2/include/git2/commit.h +30 -0
- data/vendor/libgit2/include/git2/common.h +16 -1
- data/vendor/libgit2/include/git2/merge.h +10 -1
- data/vendor/libgit2/include/git2/proxy.h +92 -0
- data/vendor/libgit2/include/git2/refs.h +11 -0
- data/vendor/libgit2/include/git2/remote.h +17 -4
- data/vendor/libgit2/include/git2/signature.h +13 -0
- data/vendor/libgit2/include/git2/sys/merge.h +177 -0
- data/vendor/libgit2/include/git2/sys/remote.h +16 -0
- data/vendor/libgit2/include/git2/sys/stream.h +2 -1
- data/vendor/libgit2/include/git2/sys/transport.h +3 -1
- data/vendor/libgit2/include/git2/tag.h +9 -0
- data/vendor/libgit2/include/git2/tree.h +55 -0
- data/vendor/libgit2/src/annotated_commit.c +99 -80
- data/vendor/libgit2/src/annotated_commit.h +5 -2
- data/vendor/libgit2/src/array.h +40 -0
- data/vendor/libgit2/src/blame.c +8 -3
- data/vendor/libgit2/src/blame_git.c +2 -1
- data/vendor/libgit2/src/blob.c +71 -39
- data/vendor/libgit2/src/branch.c +2 -1
- data/vendor/libgit2/src/checkout.c +66 -42
- data/vendor/libgit2/src/commit.c +67 -3
- data/vendor/libgit2/src/config_cache.c +2 -1
- data/vendor/libgit2/src/config_file.c +32 -27
- data/vendor/libgit2/src/curl_stream.c +89 -6
- data/vendor/libgit2/src/delta-apply.c +36 -5
- data/vendor/libgit2/src/delta-apply.h +12 -0
- data/vendor/libgit2/src/describe.c +3 -2
- data/vendor/libgit2/src/diff.c +13 -20
- data/vendor/libgit2/src/diff_tform.c +5 -3
- data/vendor/libgit2/src/filebuf.c +12 -2
- data/vendor/libgit2/src/filebuf.h +1 -0
- data/vendor/libgit2/src/fnmatch.c +18 -5
- data/vendor/libgit2/src/global.c +18 -0
- data/vendor/libgit2/src/global.h +1 -0
- data/vendor/libgit2/src/ignore.c +11 -3
- data/vendor/libgit2/src/index.c +11 -5
- data/vendor/libgit2/src/indexer.c +11 -7
- data/vendor/libgit2/src/iterator.c +1575 -1468
- data/vendor/libgit2/src/iterator.h +52 -69
- data/vendor/libgit2/src/merge.c +160 -63
- data/vendor/libgit2/src/merge.h +61 -2
- data/vendor/libgit2/src/merge_driver.c +397 -0
- data/vendor/libgit2/src/merge_driver.h +60 -0
- data/vendor/libgit2/src/merge_file.c +11 -49
- data/vendor/libgit2/src/netops.c +12 -10
- data/vendor/libgit2/src/object.c +3 -6
- data/vendor/libgit2/src/object_api.c +19 -1
- data/vendor/libgit2/src/odb_loose.c +1 -1
- data/vendor/libgit2/src/openssl_stream.c +16 -3
- data/vendor/libgit2/src/pack-objects.c +3 -1
- data/vendor/libgit2/src/pack.c +5 -9
- data/vendor/libgit2/src/path.c +14 -0
- data/vendor/libgit2/src/path.h +12 -0
- data/vendor/libgit2/src/pathspec.c +1 -1
- data/vendor/libgit2/src/posix.c +7 -0
- data/vendor/libgit2/src/posix.h +1 -0
- data/vendor/libgit2/src/proxy.c +32 -0
- data/vendor/libgit2/src/proxy.h +14 -0
- data/vendor/libgit2/src/push.c +7 -7
- data/vendor/libgit2/src/rebase.c +61 -31
- data/vendor/libgit2/src/refdb_fs.c +1 -0
- data/vendor/libgit2/src/refs.c +16 -1
- data/vendor/libgit2/src/remote.c +20 -6
- data/vendor/libgit2/src/repository.c +1 -1
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/settings.c +23 -1
- data/vendor/libgit2/src/signature.c +26 -1
- data/vendor/libgit2/src/stransport_stream.c +5 -2
- data/vendor/libgit2/src/stream.h +2 -2
- data/vendor/libgit2/src/submodule.c +3 -2
- data/vendor/libgit2/src/tag.c +8 -2
- data/vendor/libgit2/src/transports/http.c +32 -9
- data/vendor/libgit2/src/transports/local.c +4 -1
- data/vendor/libgit2/src/transports/smart.c +6 -0
- data/vendor/libgit2/src/transports/smart.h +1 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +61 -17
- data/vendor/libgit2/src/transports/winhttp.c +130 -11
- data/vendor/libgit2/src/tree.c +329 -98
- data/vendor/libgit2/src/tree.h +4 -5
- data/vendor/libgit2/src/unix/map.c +5 -0
- data/vendor/libgit2/src/win32/map.c +24 -5
- data/vendor/libgit2/src/xdiff/xprepare.c +2 -1
- metadata +10 -4
- data/vendor/libgit2/Makefile.embed +0 -60
|
@@ -200,7 +200,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
|
|
|
200
200
|
|
|
201
201
|
memset(sig, 0, sizeof(git_signature));
|
|
202
202
|
|
|
203
|
-
if (
|
|
203
|
+
if (ender &&
|
|
204
|
+
(buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL)
|
|
204
205
|
return signature_error("no newline given");
|
|
205
206
|
|
|
206
207
|
if (header) {
|
|
@@ -262,6 +263,30 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
|
|
|
262
263
|
return 0;
|
|
263
264
|
}
|
|
264
265
|
|
|
266
|
+
int git_signature_from_buffer(git_signature **out, const char *buf)
|
|
267
|
+
{
|
|
268
|
+
git_signature *sig;
|
|
269
|
+
const char *buf_end;
|
|
270
|
+
int error;
|
|
271
|
+
|
|
272
|
+
assert(out && buf);
|
|
273
|
+
|
|
274
|
+
*out = NULL;
|
|
275
|
+
|
|
276
|
+
sig = git__calloc(1, sizeof(git_signature));
|
|
277
|
+
GITERR_CHECK_ALLOC(sig);
|
|
278
|
+
|
|
279
|
+
buf_end = buf + strlen(buf);
|
|
280
|
+
error = git_signature__parse(sig, &buf, buf_end, NULL, '\0');
|
|
281
|
+
|
|
282
|
+
if (error)
|
|
283
|
+
git__free(sig);
|
|
284
|
+
else
|
|
285
|
+
*out = sig;
|
|
286
|
+
|
|
287
|
+
return error;
|
|
288
|
+
}
|
|
289
|
+
|
|
265
290
|
void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig)
|
|
266
291
|
{
|
|
267
292
|
int offset, hours, mins;
|
|
@@ -33,6 +33,7 @@ int stransport_error(OSStatus ret)
|
|
|
33
33
|
CFRelease(message);
|
|
34
34
|
#else
|
|
35
35
|
giterr_set(GITERR_NET, "SecureTransport error: OSStatus %d", (unsigned int)ret);
|
|
36
|
+
GIT_UNUSED(message);
|
|
36
37
|
#endif
|
|
37
38
|
|
|
38
39
|
return -1;
|
|
@@ -116,11 +117,13 @@ int stransport_certificate(git_cert **out, git_stream *stream)
|
|
|
116
117
|
return 0;
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
int stransport_set_proxy(
|
|
120
|
+
int stransport_set_proxy(
|
|
121
|
+
git_stream *stream,
|
|
122
|
+
const git_proxy_options *proxy_opts)
|
|
120
123
|
{
|
|
121
124
|
stransport_stream *st = (stransport_stream *) stream;
|
|
122
125
|
|
|
123
|
-
return git_stream_set_proxy(st->io,
|
|
126
|
+
return git_stream_set_proxy(st->io, proxy_opts);
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
/*
|
data/vendor/libgit2/src/stream.h
CHANGED
|
@@ -35,14 +35,14 @@ GIT_INLINE(int) git_stream_supports_proxy(git_stream *st)
|
|
|
35
35
|
return st->proxy_support;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
GIT_INLINE(int) git_stream_set_proxy(git_stream *st, const
|
|
38
|
+
GIT_INLINE(int) git_stream_set_proxy(git_stream *st, const git_proxy_options *proxy_opts)
|
|
39
39
|
{
|
|
40
40
|
if (!st->proxy_support) {
|
|
41
41
|
giterr_set(GITERR_INVALID, "proxy not supported on this stream");
|
|
42
42
|
return -1;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
return st->set_proxy(st,
|
|
45
|
+
return st->set_proxy(st, proxy_opts);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
GIT_INLINE(ssize_t) git_stream_read(git_stream *st, void *data, size_t len)
|
|
@@ -80,7 +80,8 @@ static kh_inline int str_equal_no_trailing_slash(const char *a, const char *b)
|
|
|
80
80
|
if (blen > 0 && b[blen - 1] == '/')
|
|
81
81
|
blen--;
|
|
82
82
|
|
|
83
|
-
return (alen ==
|
|
83
|
+
return (alen == 0 && blen == 0) ||
|
|
84
|
+
(alen == blen && strncmp(a, b, alen) == 0);
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
__KHASH_IMPL(
|
|
@@ -1416,7 +1417,7 @@ static int submodule_update_head(git_submodule *submodule)
|
|
|
1416
1417
|
git_tree_entry_bypath(&te, head, submodule->path) < 0)
|
|
1417
1418
|
giterr_clear();
|
|
1418
1419
|
else
|
|
1419
|
-
submodule_update_from_head_data(submodule, te->attr,
|
|
1420
|
+
submodule_update_from_head_data(submodule, te->attr, git_tree_entry_id(te));
|
|
1420
1421
|
|
|
1421
1422
|
git_tree_entry_free(te);
|
|
1422
1423
|
git_tree_free(head);
|
data/vendor/libgit2/src/tag.c
CHANGED
|
@@ -137,8 +137,14 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
|
|
|
137
137
|
|
|
138
138
|
tag->message = NULL;
|
|
139
139
|
if (buffer < buffer_end) {
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
/* If we're not at the end of the header, search for it */
|
|
141
|
+
if( *buffer != '\n' ) {
|
|
142
|
+
search = strstr(buffer, "\n\n");
|
|
143
|
+
if (search)
|
|
144
|
+
buffer = search + 1;
|
|
145
|
+
else
|
|
146
|
+
return tag_error("tag contains no message");
|
|
147
|
+
}
|
|
142
148
|
|
|
143
149
|
text_len = buffer_end - ++buffer;
|
|
144
150
|
|
|
@@ -555,10 +555,40 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
|
|
|
555
555
|
return 0;
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
+
static int apply_proxy_config(http_subtransport *t)
|
|
559
|
+
{
|
|
560
|
+
int error;
|
|
561
|
+
git_proxy_t proxy_type;
|
|
562
|
+
|
|
563
|
+
if (!git_stream_supports_proxy(t->io))
|
|
564
|
+
return 0;
|
|
565
|
+
|
|
566
|
+
proxy_type = t->owner->proxy.type;
|
|
567
|
+
|
|
568
|
+
if (proxy_type == GIT_PROXY_NONE)
|
|
569
|
+
return 0;
|
|
570
|
+
|
|
571
|
+
if (proxy_type == GIT_PROXY_AUTO) {
|
|
572
|
+
char *url;
|
|
573
|
+
git_proxy_options opts = GIT_PROXY_OPTIONS_INIT;
|
|
574
|
+
|
|
575
|
+
if ((error = git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &url)) < 0)
|
|
576
|
+
return error;
|
|
577
|
+
|
|
578
|
+
opts.type = GIT_PROXY_SPECIFIED;
|
|
579
|
+
opts.url = url;
|
|
580
|
+
error = git_stream_set_proxy(t->io, &opts);
|
|
581
|
+
git__free(url);
|
|
582
|
+
|
|
583
|
+
return error;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return git_stream_set_proxy(t->io, &t->owner->proxy);
|
|
587
|
+
}
|
|
588
|
+
|
|
558
589
|
static int http_connect(http_subtransport *t)
|
|
559
590
|
{
|
|
560
591
|
int error;
|
|
561
|
-
char *proxy_url;
|
|
562
592
|
|
|
563
593
|
if (t->connected &&
|
|
564
594
|
http_should_keep_alive(&t->parser) &&
|
|
@@ -586,14 +616,7 @@ static int http_connect(http_subtransport *t)
|
|
|
586
616
|
|
|
587
617
|
GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream");
|
|
588
618
|
|
|
589
|
-
|
|
590
|
-
!git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url)) {
|
|
591
|
-
error = git_stream_set_proxy(t->io, proxy_url);
|
|
592
|
-
git__free(proxy_url);
|
|
593
|
-
|
|
594
|
-
if (error < 0)
|
|
595
|
-
return error;
|
|
596
|
-
}
|
|
619
|
+
apply_proxy_config(t);
|
|
597
620
|
|
|
598
621
|
error = git_stream_connect(t->io);
|
|
599
622
|
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
#include "odb.h"
|
|
26
26
|
#include "push.h"
|
|
27
27
|
#include "remote.h"
|
|
28
|
+
#include "proxy.h"
|
|
28
29
|
|
|
29
30
|
typedef struct {
|
|
30
31
|
git_transport parent;
|
|
@@ -199,6 +200,7 @@ static int local_connect(
|
|
|
199
200
|
const char *url,
|
|
200
201
|
git_cred_acquire_cb cred_acquire_cb,
|
|
201
202
|
void *cred_acquire_payload,
|
|
203
|
+
const git_proxy_options *proxy,
|
|
202
204
|
int direction, int flags)
|
|
203
205
|
{
|
|
204
206
|
git_repository *repo;
|
|
@@ -209,6 +211,7 @@ static int local_connect(
|
|
|
209
211
|
|
|
210
212
|
GIT_UNUSED(cred_acquire_cb);
|
|
211
213
|
GIT_UNUSED(cred_acquire_payload);
|
|
214
|
+
GIT_UNUSED(proxy);
|
|
212
215
|
|
|
213
216
|
if (t->connected)
|
|
214
217
|
return 0;
|
|
@@ -439,7 +442,7 @@ static int local_push(
|
|
|
439
442
|
|
|
440
443
|
if (!url || t->parent.close(&t->parent) < 0 ||
|
|
441
444
|
t->parent.connect(&t->parent, url,
|
|
442
|
-
NULL, NULL, GIT_DIRECTION_PUSH, flags))
|
|
445
|
+
NULL, NULL, NULL, GIT_DIRECTION_PUSH, flags))
|
|
443
446
|
goto on_error;
|
|
444
447
|
}
|
|
445
448
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include "smart.h"
|
|
9
9
|
#include "refs.h"
|
|
10
10
|
#include "refspec.h"
|
|
11
|
+
#include "proxy.h"
|
|
11
12
|
|
|
12
13
|
static int git_smart__recv_cb(gitno_buffer *buf)
|
|
13
14
|
{
|
|
@@ -199,6 +200,7 @@ static int git_smart__connect(
|
|
|
199
200
|
const char *url,
|
|
200
201
|
git_cred_acquire_cb cred_acquire_cb,
|
|
201
202
|
void *cred_acquire_payload,
|
|
203
|
+
const git_proxy_options *proxy,
|
|
202
204
|
int direction,
|
|
203
205
|
int flags)
|
|
204
206
|
{
|
|
@@ -216,6 +218,9 @@ static int git_smart__connect(
|
|
|
216
218
|
t->url = git__strdup(url);
|
|
217
219
|
GITERR_CHECK_ALLOC(t->url);
|
|
218
220
|
|
|
221
|
+
if (git_proxy_options_dup(&t->proxy, proxy) < 0)
|
|
222
|
+
return -1;
|
|
223
|
+
|
|
219
224
|
t->direction = direction;
|
|
220
225
|
t->flags = flags;
|
|
221
226
|
t->cred_acquire_cb = cred_acquire_cb;
|
|
@@ -439,6 +444,7 @@ static void git_smart__free(git_transport *transport)
|
|
|
439
444
|
git_pkt_free(p);
|
|
440
445
|
|
|
441
446
|
git_vector_free(refs);
|
|
447
|
+
git__free((char *)t->proxy.url);
|
|
442
448
|
|
|
443
449
|
git_strarray_free(&t->custom_headers);
|
|
444
450
|
|
|
@@ -721,18 +721,39 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
|
|
|
721
721
|
return 0;
|
|
722
722
|
}
|
|
723
723
|
|
|
724
|
-
static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
|
|
724
|
+
static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_buf *data_pkt_buf)
|
|
725
725
|
{
|
|
726
726
|
git_pkt *pkt;
|
|
727
|
-
const char *line
|
|
728
|
-
size_t line_len
|
|
727
|
+
const char *line, *line_end;
|
|
728
|
+
size_t line_len;
|
|
729
729
|
int error;
|
|
730
|
+
int reading_from_buf = data_pkt_buf->size > 0;
|
|
731
|
+
|
|
732
|
+
if (reading_from_buf) {
|
|
733
|
+
/* We had an existing partial packet, so add the new
|
|
734
|
+
* packet to the buffer and parse the whole thing */
|
|
735
|
+
git_buf_put(data_pkt_buf, data_pkt->data, data_pkt->len);
|
|
736
|
+
line = data_pkt_buf->ptr;
|
|
737
|
+
line_len = data_pkt_buf->size;
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
line = data_pkt->data;
|
|
741
|
+
line_len = data_pkt->len;
|
|
742
|
+
}
|
|
730
743
|
|
|
731
744
|
while (line_len > 0) {
|
|
732
745
|
error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
|
|
733
746
|
|
|
734
|
-
if (error
|
|
735
|
-
|
|
747
|
+
if (error == GIT_EBUFS) {
|
|
748
|
+
/* Buffer the data when the inner packet is split
|
|
749
|
+
* across multiple sideband packets */
|
|
750
|
+
if (!reading_from_buf)
|
|
751
|
+
git_buf_put(data_pkt_buf, line, line_len);
|
|
752
|
+
error = 0;
|
|
753
|
+
goto done;
|
|
754
|
+
}
|
|
755
|
+
else if (error < 0)
|
|
756
|
+
goto done;
|
|
736
757
|
|
|
737
758
|
/* Advance in the buffer */
|
|
738
759
|
line_len -= (line_end - line);
|
|
@@ -743,10 +764,15 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
|
|
|
743
764
|
git_pkt_free(pkt);
|
|
744
765
|
|
|
745
766
|
if (error < 0 && error != GIT_ITEROVER)
|
|
746
|
-
|
|
767
|
+
goto done;
|
|
747
768
|
}
|
|
748
769
|
|
|
749
|
-
|
|
770
|
+
error = 0;
|
|
771
|
+
|
|
772
|
+
done:
|
|
773
|
+
if (reading_from_buf)
|
|
774
|
+
git_buf_consume(data_pkt_buf, line_end);
|
|
775
|
+
return error;
|
|
750
776
|
}
|
|
751
777
|
|
|
752
778
|
static int parse_report(transport_smart *transport, git_push *push)
|
|
@@ -755,6 +781,7 @@ static int parse_report(transport_smart *transport, git_push *push)
|
|
|
755
781
|
const char *line_end = NULL;
|
|
756
782
|
gitno_buffer *buf = &transport->buffer;
|
|
757
783
|
int error, recvd;
|
|
784
|
+
git_buf data_pkt_buf = GIT_BUF_INIT;
|
|
758
785
|
|
|
759
786
|
for (;;) {
|
|
760
787
|
if (buf->offset > 0)
|
|
@@ -763,16 +790,21 @@ static int parse_report(transport_smart *transport, git_push *push)
|
|
|
763
790
|
else
|
|
764
791
|
error = GIT_EBUFS;
|
|
765
792
|
|
|
766
|
-
if (error < 0 && error != GIT_EBUFS)
|
|
767
|
-
|
|
793
|
+
if (error < 0 && error != GIT_EBUFS) {
|
|
794
|
+
error = -1;
|
|
795
|
+
goto done;
|
|
796
|
+
}
|
|
768
797
|
|
|
769
798
|
if (error == GIT_EBUFS) {
|
|
770
|
-
if ((recvd = gitno_recv(buf)) < 0)
|
|
771
|
-
|
|
799
|
+
if ((recvd = gitno_recv(buf)) < 0) {
|
|
800
|
+
error = recvd;
|
|
801
|
+
goto done;
|
|
802
|
+
}
|
|
772
803
|
|
|
773
804
|
if (recvd == 0) {
|
|
774
805
|
giterr_set(GITERR_NET, "early EOF");
|
|
775
|
-
|
|
806
|
+
error = GIT_EEOF;
|
|
807
|
+
goto done;
|
|
776
808
|
}
|
|
777
809
|
continue;
|
|
778
810
|
}
|
|
@@ -784,7 +816,7 @@ static int parse_report(transport_smart *transport, git_push *push)
|
|
|
784
816
|
switch (pkt->type) {
|
|
785
817
|
case GIT_PKT_DATA:
|
|
786
818
|
/* This is a sideband packet which contains other packets */
|
|
787
|
-
error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt);
|
|
819
|
+
error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt, &data_pkt_buf);
|
|
788
820
|
break;
|
|
789
821
|
case GIT_PKT_ERR:
|
|
790
822
|
giterr_set(GITERR_NET, "report-status: Error reported: %s",
|
|
@@ -805,12 +837,24 @@ static int parse_report(transport_smart *transport, git_push *push)
|
|
|
805
837
|
git_pkt_free(pkt);
|
|
806
838
|
|
|
807
839
|
/* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */
|
|
808
|
-
if (error == GIT_ITEROVER)
|
|
809
|
-
|
|
840
|
+
if (error == GIT_ITEROVER) {
|
|
841
|
+
error = 0;
|
|
842
|
+
if (data_pkt_buf.size > 0) {
|
|
843
|
+
/* If there was data remaining in the pack data buffer,
|
|
844
|
+
* then the server sent a partial pkt-line */
|
|
845
|
+
giterr_set(GITERR_NET, "Incomplete pack data pkt-line");
|
|
846
|
+
error = GIT_ERROR;
|
|
847
|
+
}
|
|
848
|
+
goto done;
|
|
849
|
+
}
|
|
810
850
|
|
|
811
|
-
if (error < 0)
|
|
812
|
-
|
|
851
|
+
if (error < 0) {
|
|
852
|
+
goto done;
|
|
853
|
+
}
|
|
813
854
|
}
|
|
855
|
+
done:
|
|
856
|
+
git_buf_free(&data_pkt_buf);
|
|
857
|
+
return error;
|
|
814
858
|
}
|
|
815
859
|
|
|
816
860
|
static int add_ref_from_push_spec(git_vector *refs, push_spec *push_spec)
|
|
@@ -91,13 +91,39 @@ typedef struct {
|
|
|
91
91
|
git_smart_subtransport parent;
|
|
92
92
|
transport_smart *owner;
|
|
93
93
|
gitno_connection_data connection_data;
|
|
94
|
+
gitno_connection_data proxy_connection_data;
|
|
94
95
|
git_cred *cred;
|
|
95
96
|
git_cred *url_cred;
|
|
97
|
+
git_cred *proxy_cred;
|
|
96
98
|
int auth_mechanism;
|
|
97
99
|
HINTERNET session;
|
|
98
100
|
HINTERNET connection;
|
|
99
101
|
} winhttp_subtransport;
|
|
100
102
|
|
|
103
|
+
static int apply_basic_credential_proxy(HINTERNET request, git_cred *cred)
|
|
104
|
+
{
|
|
105
|
+
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
|
|
106
|
+
wchar_t *user, *pass;
|
|
107
|
+
int error;
|
|
108
|
+
|
|
109
|
+
if ((error = git__utf8_to_16_alloc(&user, c->username)) < 0)
|
|
110
|
+
return error;
|
|
111
|
+
|
|
112
|
+
if ((error = git__utf8_to_16_alloc(&pass, c->password)) < 0)
|
|
113
|
+
return error;
|
|
114
|
+
|
|
115
|
+
if (!WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC,
|
|
116
|
+
user, pass, NULL)) {
|
|
117
|
+
giterr_set(GITERR_OS, "failed to set proxy auth");
|
|
118
|
+
error = -1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
git__free(user);
|
|
122
|
+
git__free(pass);
|
|
123
|
+
|
|
124
|
+
return error;
|
|
125
|
+
}
|
|
126
|
+
|
|
101
127
|
static int apply_basic_credential(HINTERNET request, git_cred *cred)
|
|
102
128
|
{
|
|
103
129
|
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
|
|
@@ -271,6 +297,37 @@ static void winhttp_stream_close(winhttp_stream *s)
|
|
|
271
297
|
s->sent_request = 0;
|
|
272
298
|
}
|
|
273
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Extract the url and password from a URL. The outputs are pointers
|
|
302
|
+
* into the input.
|
|
303
|
+
*/
|
|
304
|
+
static int userpass_from_url(wchar_t **user, int *user_len,
|
|
305
|
+
wchar_t **pass, int *pass_len,
|
|
306
|
+
const wchar_t *url, int url_len)
|
|
307
|
+
{
|
|
308
|
+
URL_COMPONENTS components = { 0 };
|
|
309
|
+
|
|
310
|
+
components.dwStructSize = sizeof(components);
|
|
311
|
+
/* These tell WinHttpCrackUrl that we're interested in the fields */
|
|
312
|
+
components.dwUserNameLength = 1;
|
|
313
|
+
components.dwPasswordLength = 1;
|
|
314
|
+
|
|
315
|
+
if (!WinHttpCrackUrl(url, url_len, 0, &components)) {
|
|
316
|
+
giterr_set(GITERR_OS, "failed to extract user/pass from url");
|
|
317
|
+
return -1;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
*user = components.lpszUserName;
|
|
321
|
+
*user_len = components.dwUserNameLength;
|
|
322
|
+
*pass = components.lpszPassword;
|
|
323
|
+
*pass_len = components.dwPasswordLength;
|
|
324
|
+
|
|
325
|
+
return 0;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
#define SCHEME_HTTP "http://"
|
|
329
|
+
#define SCHEME_HTTPS "https://"
|
|
330
|
+
|
|
274
331
|
static int winhttp_stream_connect(winhttp_stream *s)
|
|
275
332
|
{
|
|
276
333
|
winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
|
|
@@ -284,6 +341,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
|
284
341
|
int default_timeout = TIMEOUT_INFINITE;
|
|
285
342
|
int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
|
|
286
343
|
size_t i;
|
|
344
|
+
const git_proxy_options *proxy_opts;
|
|
287
345
|
|
|
288
346
|
/* Prepare URL */
|
|
289
347
|
git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url);
|
|
@@ -317,26 +375,59 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
|
317
375
|
goto on_error;
|
|
318
376
|
}
|
|
319
377
|
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
|
|
378
|
+
proxy_opts = &t->owner->proxy;
|
|
379
|
+
if (proxy_opts->type == GIT_PROXY_AUTO) {
|
|
380
|
+
/* Set proxy if necessary */
|
|
381
|
+
if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0)
|
|
382
|
+
goto on_error;
|
|
383
|
+
}
|
|
384
|
+
else if (proxy_opts->type == GIT_PROXY_SPECIFIED) {
|
|
385
|
+
proxy_url = git__strdup(proxy_opts->url);
|
|
386
|
+
GITERR_CHECK_ALLOC(proxy_url);
|
|
387
|
+
}
|
|
323
388
|
|
|
324
389
|
if (proxy_url) {
|
|
390
|
+
git_buf processed_url = GIT_BUF_INIT;
|
|
325
391
|
WINHTTP_PROXY_INFO proxy_info;
|
|
326
392
|
wchar_t *proxy_wide;
|
|
327
393
|
|
|
328
|
-
|
|
329
|
-
|
|
394
|
+
if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) {
|
|
395
|
+
t->proxy_connection_data.use_ssl = false;
|
|
396
|
+
} else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) {
|
|
397
|
+
t->proxy_connection_data.use_ssl = true;
|
|
398
|
+
} else {
|
|
399
|
+
giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url);
|
|
400
|
+
return -1;
|
|
401
|
+
}
|
|
330
402
|
|
|
331
|
-
if (
|
|
332
|
-
|
|
403
|
+
if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL,
|
|
404
|
+
&t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0)
|
|
405
|
+
goto on_error;
|
|
406
|
+
|
|
407
|
+
if (t->proxy_connection_data.user && t->proxy_connection_data.pass) {
|
|
408
|
+
if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0)
|
|
409
|
+
goto on_error;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (t->proxy_connection_data.use_ssl)
|
|
413
|
+
git_buf_PUTS(&processed_url, SCHEME_HTTPS);
|
|
414
|
+
else
|
|
415
|
+
git_buf_PUTS(&processed_url, SCHEME_HTTP);
|
|
416
|
+
|
|
417
|
+
git_buf_puts(&processed_url, t->proxy_connection_data.host);
|
|
418
|
+
if (t->proxy_connection_data.port)
|
|
419
|
+
git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port);
|
|
420
|
+
|
|
421
|
+
if (git_buf_oom(&processed_url)) {
|
|
422
|
+
giterr_set_oom();
|
|
423
|
+
error = -1;
|
|
333
424
|
goto on_error;
|
|
334
425
|
}
|
|
335
426
|
|
|
336
|
-
/*
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
427
|
+
/* Convert URL to wide characters */
|
|
428
|
+
if ((error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr)) < 0)
|
|
429
|
+
goto on_error;
|
|
430
|
+
|
|
340
431
|
|
|
341
432
|
proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
|
342
433
|
proxy_info.lpszProxy = proxy_wide;
|
|
@@ -352,6 +443,14 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
|
352
443
|
}
|
|
353
444
|
|
|
354
445
|
git__free(proxy_wide);
|
|
446
|
+
|
|
447
|
+
if (t->proxy_cred) {
|
|
448
|
+
if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) {
|
|
449
|
+
if ((error = apply_basic_credential_proxy(s->request, t->proxy_cred)) < 0)
|
|
450
|
+
goto on_error;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
355
454
|
}
|
|
356
455
|
|
|
357
456
|
/* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
|
|
@@ -919,6 +1018,26 @@ replay:
|
|
|
919
1018
|
goto replay;
|
|
920
1019
|
}
|
|
921
1020
|
|
|
1021
|
+
/* Handle proxy authentication failures */
|
|
1022
|
+
if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
|
|
1023
|
+
int allowed_types;
|
|
1024
|
+
|
|
1025
|
+
if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0)
|
|
1026
|
+
return -1;
|
|
1027
|
+
|
|
1028
|
+
/* TODO: extract the username from the url, no payload? */
|
|
1029
|
+
if (t->owner->proxy.credentials) {
|
|
1030
|
+
int cred_error = 1;
|
|
1031
|
+
cred_error = t->owner->proxy.credentials(&t->proxy_cred, t->owner->proxy.url, NULL, allowed_types, NULL);
|
|
1032
|
+
|
|
1033
|
+
if (cred_error < 0)
|
|
1034
|
+
return cred_error;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
winhttp_stream_close(s);
|
|
1038
|
+
goto replay;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
922
1041
|
/* Handle authentication failures */
|
|
923
1042
|
if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
|
|
924
1043
|
int allowed_types;
|