rugged 0.24.6.1 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/ext/rugged/extconf.rb +9 -2
- data/ext/rugged/rugged.c +85 -21
- data/ext/rugged/rugged.h +7 -21
- data/ext/rugged/rugged_backend.c +3 -20
- data/ext/rugged/rugged_blame.c +7 -24
- data/ext/rugged/rugged_blob.c +136 -59
- data/ext/rugged/rugged_branch.c +3 -20
- data/ext/rugged/rugged_branch_collection.c +3 -20
- data/ext/rugged/rugged_commit.c +251 -101
- data/ext/rugged/rugged_config.c +3 -20
- data/ext/rugged/rugged_cred.c +3 -20
- data/ext/rugged/rugged_diff.c +3 -20
- data/ext/rugged/rugged_diff_delta.c +3 -20
- data/ext/rugged/rugged_diff_hunk.c +3 -20
- data/ext/rugged/rugged_diff_line.c +3 -20
- data/ext/rugged/rugged_index.c +46 -229
- data/ext/rugged/rugged_note.c +3 -20
- data/ext/rugged/rugged_object.c +3 -20
- data/ext/rugged/rugged_patch.c +192 -34
- data/ext/rugged/rugged_rebase.c +90 -48
- data/ext/rugged/rugged_reference.c +4 -21
- data/ext/rugged/rugged_reference_collection.c +3 -20
- data/ext/rugged/rugged_remote.c +70 -42
- data/ext/rugged/rugged_remote_collection.c +3 -20
- data/ext/rugged/rugged_repo.c +50 -59
- data/ext/rugged/rugged_revwalk.c +4 -21
- data/ext/rugged/rugged_settings.c +3 -20
- data/ext/rugged/rugged_signature.c +3 -20
- data/ext/rugged/rugged_submodule.c +4 -21
- data/ext/rugged/rugged_submodule_collection.c +3 -20
- data/ext/rugged/rugged_tag.c +3 -20
- data/ext/rugged/rugged_tag_collection.c +3 -20
- data/ext/rugged/rugged_tree.c +189 -184
- data/lib/rugged/attributes.rb +5 -0
- data/lib/rugged/blob.rb +5 -0
- data/lib/rugged/branch.rb +6 -1
- data/lib/rugged/commit.rb +5 -0
- data/lib/rugged/console.rb +5 -0
- data/lib/rugged/credentials.rb +5 -0
- data/lib/rugged/diff/delta.rb +5 -0
- data/lib/rugged/diff/hunk.rb +5 -0
- data/lib/rugged/diff/line.rb +5 -0
- data/lib/rugged/diff.rb +5 -0
- data/lib/rugged/index.rb +120 -0
- data/lib/rugged/object.rb +5 -0
- data/lib/rugged/patch.rb +5 -0
- data/lib/rugged/reference.rb +5 -0
- data/lib/rugged/remote.rb +5 -0
- data/lib/rugged/repository.rb +9 -4
- data/lib/rugged/submodule_collection.rb +5 -0
- data/lib/rugged/tag.rb +5 -0
- data/lib/rugged/tree.rb +156 -1
- data/lib/rugged/version.rb +6 -1
- data/lib/rugged/walker.rb +5 -0
- data/lib/rugged.rb +5 -0
- data/vendor/libgit2/CMakeLists.txt +12 -2
- data/vendor/libgit2/include/git2/blob.h +39 -28
- data/vendor/libgit2/include/git2/commit.h +76 -0
- data/vendor/libgit2/include/git2/common.h +21 -1
- data/vendor/libgit2/include/git2/describe.h +5 -2
- data/vendor/libgit2/include/git2/diff.h +62 -7
- data/vendor/libgit2/include/git2/errors.h +2 -1
- data/vendor/libgit2/include/git2/index.h +25 -0
- data/vendor/libgit2/include/git2/merge.h +10 -1
- data/vendor/libgit2/include/git2/odb.h +47 -1
- data/vendor/libgit2/include/git2/pack.h +4 -4
- data/vendor/libgit2/include/git2/patch.h +1 -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 +21 -8
- data/vendor/libgit2/include/git2/repository.h +20 -1
- data/vendor/libgit2/include/git2/revwalk.h +4 -6
- data/vendor/libgit2/include/git2/signature.h +13 -0
- data/vendor/libgit2/include/git2/submodule.h +11 -3
- data/vendor/libgit2/include/git2/sys/merge.h +177 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -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/time.h +31 -0
- data/vendor/libgit2/include/git2/sys/transport.h +3 -1
- data/vendor/libgit2/include/git2/tag.h +9 -0
- data/vendor/libgit2/include/git2/transaction.h +9 -0
- data/vendor/libgit2/include/git2/tree.h +55 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/annotated_commit.c +99 -80
- data/vendor/libgit2/src/annotated_commit.h +5 -2
- data/vendor/libgit2/src/apply.c +377 -0
- data/vendor/libgit2/src/apply.h +21 -0
- data/vendor/libgit2/src/array.h +0 -1
- data/vendor/libgit2/src/blob.c +71 -39
- data/vendor/libgit2/src/branch.c +7 -5
- data/vendor/libgit2/src/buffer.c +252 -20
- data/vendor/libgit2/src/buffer.h +8 -0
- data/vendor/libgit2/src/checkout.c +69 -42
- data/vendor/libgit2/src/clone.c +0 -8
- data/vendor/libgit2/src/commit.c +193 -49
- data/vendor/libgit2/src/commit_list.c +8 -3
- data/vendor/libgit2/src/commit_list.h +1 -0
- data/vendor/libgit2/src/common.h +2 -1
- data/vendor/libgit2/src/config.c +3 -3
- data/vendor/libgit2/src/config_file.c +20 -10
- data/vendor/libgit2/src/crlf.c +1 -0
- data/vendor/libgit2/src/curl_stream.c +106 -6
- data/vendor/libgit2/src/delta.c +238 -62
- data/vendor/libgit2/src/delta.h +79 -58
- data/vendor/libgit2/src/describe.c +1 -1
- data/vendor/libgit2/src/diff.c +32 -1554
- data/vendor/libgit2/src/diff.h +14 -122
- data/vendor/libgit2/src/diff_driver.c +4 -6
- data/vendor/libgit2/src/diff_file.c +3 -0
- data/vendor/libgit2/src/diff_generate.c +1613 -0
- data/vendor/libgit2/src/diff_generate.h +123 -0
- data/vendor/libgit2/src/diff_parse.c +101 -0
- data/vendor/libgit2/src/diff_parse.h +18 -0
- data/vendor/libgit2/src/diff_print.c +263 -144
- data/vendor/libgit2/src/diff_stats.c +21 -12
- data/vendor/libgit2/src/diff_tform.c +1 -0
- data/vendor/libgit2/src/diff_tform.h +22 -0
- data/vendor/libgit2/src/diff_xdiff.c +9 -9
- data/vendor/libgit2/src/diff_xdiff.h +5 -5
- data/vendor/libgit2/src/fetchhead.c +8 -8
- data/vendor/libgit2/src/filebuf.c +6 -1
- data/vendor/libgit2/src/filebuf.h +1 -0
- data/vendor/libgit2/src/fileops.c +22 -1
- data/vendor/libgit2/src/fileops.h +8 -2
- data/vendor/libgit2/src/fnmatch.c +18 -5
- data/vendor/libgit2/src/global.c +21 -4
- data/vendor/libgit2/src/global.h +6 -0
- data/vendor/libgit2/src/graph.c +1 -1
- data/vendor/libgit2/src/index.c +159 -46
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/iterator.c +1573 -1468
- data/vendor/libgit2/src/iterator.h +52 -69
- data/vendor/libgit2/src/merge.c +163 -64
- 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_api.c +19 -1
- data/vendor/libgit2/src/odb.c +228 -52
- data/vendor/libgit2/src/odb_loose.c +19 -1
- data/vendor/libgit2/src/odb_mempack.c +1 -1
- data/vendor/libgit2/src/odb_pack.c +27 -1
- data/vendor/libgit2/src/openssl_stream.c +4 -5
- data/vendor/libgit2/src/pack-objects.c +105 -76
- data/vendor/libgit2/src/pack-objects.h +13 -12
- data/vendor/libgit2/src/pack.c +16 -10
- data/vendor/libgit2/src/pack.h +2 -0
- data/vendor/libgit2/src/patch.c +216 -0
- data/vendor/libgit2/src/patch.h +66 -0
- data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +203 -376
- data/vendor/libgit2/src/patch_generate.h +68 -0
- data/vendor/libgit2/src/patch_parse.c +1159 -0
- data/vendor/libgit2/src/patch_parse.h +56 -0
- data/vendor/libgit2/src/path.c +38 -2
- data/vendor/libgit2/src/path.h +18 -0
- data/vendor/libgit2/src/pathspec.c +1 -1
- data/vendor/libgit2/src/pool.h +5 -0
- data/vendor/libgit2/src/pqueue.c +12 -5
- data/vendor/libgit2/src/pqueue.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 +1 -1
- data/vendor/libgit2/src/rebase.c +63 -36
- data/vendor/libgit2/src/refdb.c +4 -2
- data/vendor/libgit2/src/refdb_fs.c +82 -54
- data/vendor/libgit2/src/refs.c +13 -1
- data/vendor/libgit2/src/remote.c +20 -81
- data/vendor/libgit2/src/repository.c +212 -29
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/revparse.c +1 -1
- data/vendor/libgit2/src/revwalk.c +260 -184
- data/vendor/libgit2/src/settings.c +11 -3
- data/vendor/libgit2/src/signature.c +27 -2
- data/vendor/libgit2/src/sortedcache.c +14 -5
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +1 -0
- data/vendor/libgit2/src/stransport_stream.c +4 -2
- data/vendor/libgit2/src/stream.h +2 -2
- data/vendor/libgit2/src/submodule.c +16 -4
- data/vendor/libgit2/src/sysdir.c +1 -1
- data/vendor/libgit2/src/transport.c +3 -5
- data/vendor/libgit2/src/transports/http.c +38 -13
- 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_pkt.c +5 -13
- data/vendor/libgit2/src/transports/smart_protocol.c +22 -7
- data/vendor/libgit2/src/transports/winhttp.c +144 -11
- data/vendor/libgit2/src/tree.c +267 -2
- data/vendor/libgit2/src/unix/posix.h +10 -0
- data/vendor/libgit2/src/unix/pthread.h +2 -0
- data/vendor/libgit2/src/util.c +25 -2
- data/vendor/libgit2/src/util.h +10 -0
- data/vendor/libgit2/src/varint.c +44 -0
- data/vendor/libgit2/src/varint.h +15 -0
- data/vendor/libgit2/src/vector.c +58 -0
- data/vendor/libgit2/src/vector.h +8 -0
- data/vendor/libgit2/src/win32/posix.h +3 -0
- data/vendor/libgit2/src/win32/thread.c +18 -0
- data/vendor/libgit2/src/win32/thread.h +2 -0
- data/vendor/libgit2/src/win32/w32_util.h +1 -1
- data/vendor/libgit2/src/zstream.c +37 -8
- data/vendor/libgit2/src/zstream.h +8 -1
- metadata +100 -82
- data/vendor/libgit2/Makefile.embed +0 -60
- data/vendor/libgit2/src/delta-apply.c +0 -166
- data/vendor/libgit2/src/delta-apply.h +0 -62
- data/vendor/libgit2/src/diff_patch.h +0 -83
data/vendor/libgit2/src/status.c
CHANGED
@@ -120,11 +120,13 @@ static int stransport_certificate(git_cert **out, git_stream *stream)
|
|
120
120
|
return 0;
|
121
121
|
}
|
122
122
|
|
123
|
-
static int stransport_set_proxy(
|
123
|
+
static int stransport_set_proxy(
|
124
|
+
git_stream *stream,
|
125
|
+
const git_proxy_options *proxy_opts)
|
124
126
|
{
|
125
127
|
stransport_stream *st = (stransport_stream *) stream;
|
126
128
|
|
127
|
-
return git_stream_set_proxy(st->io,
|
129
|
+
return git_stream_set_proxy(st->io, proxy_opts);
|
128
130
|
}
|
129
131
|
|
130
132
|
/*
|
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)
|
@@ -93,6 +93,7 @@ static git_config_backend *open_gitmodules(git_repository *repo, int gitmod);
|
|
93
93
|
static git_config *gitmodules_snapshot(git_repository *repo);
|
94
94
|
static int get_url_base(git_buf *url, git_repository *repo);
|
95
95
|
static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
|
96
|
+
static int lookup_default_remote(git_remote **remote, git_repository *repo);
|
96
97
|
static int submodule_load_each(const git_config_entry *entry, void *payload);
|
97
98
|
static int submodule_read_config(git_submodule *sm, git_config *cfg);
|
98
99
|
static int submodule_load_from_wd_lite(git_submodule *);
|
@@ -1131,7 +1132,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio
|
|
1131
1132
|
if (error != GIT_ENOTFOUND)
|
1132
1133
|
goto done;
|
1133
1134
|
|
1134
|
-
if (
|
1135
|
+
if (!init) {
|
1135
1136
|
giterr_set(GITERR_SUBMODULE, "Submodule is not initialized.");
|
1136
1137
|
error = GIT_ERROR;
|
1137
1138
|
goto done;
|
@@ -1171,9 +1172,20 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio
|
|
1171
1172
|
* update the workdir contents of the subrepository, and set the subrepository's
|
1172
1173
|
* head to the new commit.
|
1173
1174
|
*/
|
1174
|
-
if ((error = git_submodule_open(&sub_repo, sm)) < 0
|
1175
|
-
|
1176
|
-
|
1175
|
+
if ((error = git_submodule_open(&sub_repo, sm)) < 0)
|
1176
|
+
goto done;
|
1177
|
+
|
1178
|
+
/* Look up the target commit in the submodule. */
|
1179
|
+
if ((error = git_object_lookup(&target_commit, sub_repo, git_submodule_index_id(sm), GIT_OBJ_COMMIT)) < 0) {
|
1180
|
+
/* If it isn't found then fetch and try again. */
|
1181
|
+
if (error != GIT_ENOTFOUND || !update_options.allow_fetch ||
|
1182
|
+
(error = lookup_default_remote(&remote, sub_repo)) < 0 ||
|
1183
|
+
(error = git_remote_fetch(remote, NULL, &update_options.fetch_opts, NULL)) < 0 ||
|
1184
|
+
(error = git_object_lookup(&target_commit, sub_repo, git_submodule_index_id(sm), GIT_OBJ_COMMIT)) < 0)
|
1185
|
+
goto done;
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
if ((error = git_checkout_tree(sub_repo, target_commit, &update_options.checkout_opts)) != 0 ||
|
1177
1189
|
(error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0)
|
1178
1190
|
goto done;
|
1179
1191
|
|
data/vendor/libgit2/src/sysdir.c
CHANGED
@@ -171,7 +171,7 @@ int git_sysdir_set(git_sysdir_t which, const char *search_path)
|
|
171
171
|
expand_path = strstr(search_path, PATH_MAGIC);
|
172
172
|
|
173
173
|
/* reset the default if this path has been cleared */
|
174
|
-
if (!search_path
|
174
|
+
if (!search_path)
|
175
175
|
git_sysdir__dirs[which].guess(&git_sysdir__dirs[which].buf);
|
176
176
|
|
177
177
|
/* if $PATH is not referenced, then just set the path */
|
@@ -29,9 +29,7 @@ static transport_definition local_transport_definition = { "file://", git_transp
|
|
29
29
|
static transport_definition transports[] = {
|
30
30
|
{ "git://", git_transport_smart, &git_subtransport_definition },
|
31
31
|
{ "http://", git_transport_smart, &http_subtransport_definition },
|
32
|
-
#if defined(GIT_OPENSSL) || defined(GIT_WINHTTP) || defined(GIT_SECURE_TRANSPORT)
|
33
32
|
{ "https://", git_transport_smart, &http_subtransport_definition },
|
34
|
-
#endif
|
35
33
|
{ "file://", git_transport_local, NULL },
|
36
34
|
#ifdef GIT_SSH
|
37
35
|
{ "ssh://", git_transport_smart, &ssh_subtransport_definition },
|
@@ -89,10 +87,10 @@ static int transport_find_fn(
|
|
89
87
|
/* For other systems, perform the SSH check first, to avoid going to the
|
90
88
|
* filesystem if it is not necessary */
|
91
89
|
|
92
|
-
/* It could be a SSH remote path. Check to see if there's a :
|
93
|
-
* SSH is an unsupported transport mechanism in this version of libgit2 */
|
90
|
+
/* It could be a SSH remote path. Check to see if there's a : */
|
94
91
|
if (!definition && strrchr(url, ':')) {
|
95
|
-
|
92
|
+
/* re-search transports again with ssh:// as url
|
93
|
+
* so that we can find a third party ssh transport */
|
96
94
|
definition = transport_find_by_url("ssh://");
|
97
95
|
}
|
98
96
|
|
@@ -208,7 +208,7 @@ static int gen_request(
|
|
208
208
|
|
209
209
|
git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url);
|
210
210
|
|
211
|
-
git_buf_printf(buf, "User-Agent: git/
|
211
|
+
git_buf_printf(buf, "User-Agent: git/2.0 (%s)\r\n", user_agent());
|
212
212
|
git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host);
|
213
213
|
|
214
214
|
if (s->chunked || content_length > 0) {
|
@@ -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) &&
|
@@ -587,27 +617,20 @@ static int http_connect(http_subtransport *t)
|
|
587
617
|
|
588
618
|
GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream");
|
589
619
|
|
590
|
-
|
591
|
-
!git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url)) {
|
592
|
-
error = git_stream_set_proxy(t->io, proxy_url);
|
593
|
-
git__free(proxy_url);
|
594
|
-
|
595
|
-
if (error < 0)
|
596
|
-
return error;
|
597
|
-
}
|
620
|
+
apply_proxy_config(t);
|
598
621
|
|
599
622
|
error = git_stream_connect(t->io);
|
600
623
|
|
601
|
-
#if defined(GIT_OPENSSL) || defined(GIT_SECURE_TRANSPORT) || defined(GIT_CURL)
|
602
624
|
if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL &&
|
603
625
|
git_stream_is_encrypted(t->io)) {
|
604
626
|
git_cert *cert;
|
605
|
-
int is_valid
|
627
|
+
int is_valid;
|
606
628
|
|
607
629
|
if ((error = git_stream_certificate(&cert, t->io)) < 0)
|
608
630
|
return error;
|
609
631
|
|
610
632
|
giterr_clear();
|
633
|
+
is_valid = error != GIT_ECERTIFICATE;
|
611
634
|
error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload);
|
612
635
|
|
613
636
|
if (error < 0) {
|
@@ -617,7 +640,7 @@ static int http_connect(http_subtransport *t)
|
|
617
640
|
return error;
|
618
641
|
}
|
619
642
|
}
|
620
|
-
|
643
|
+
|
621
644
|
if (error < 0)
|
622
645
|
return error;
|
623
646
|
|
@@ -1013,6 +1036,8 @@ static int http_close(git_smart_subtransport *subtransport)
|
|
1013
1036
|
|
1014
1037
|
clear_parser_state(t);
|
1015
1038
|
|
1039
|
+
t->connected = 0;
|
1040
|
+
|
1016
1041
|
if (t->io) {
|
1017
1042
|
git_stream_close(t->io);
|
1018
1043
|
git_stream_free(t->io);
|
@@ -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
|
|
@@ -427,23 +427,15 @@ int git_pkt_parse_line(
|
|
427
427
|
if (bufflen > 0 && bufflen < (size_t)len)
|
428
428
|
return GIT_EBUFS;
|
429
429
|
|
430
|
-
/*
|
431
|
-
* The length has to be exactly 0 in case of a flush
|
432
|
-
* packet or greater than PKT_LEN_SIZE, as the decoded
|
433
|
-
* length includes its own encoded length of four bytes.
|
434
|
-
*/
|
435
|
-
if (len != 0 && len < PKT_LEN_SIZE)
|
436
|
-
return GIT_ERROR;
|
437
|
-
|
438
430
|
line += PKT_LEN_SIZE;
|
439
431
|
/*
|
440
|
-
*
|
441
|
-
*
|
442
|
-
* line, we should return an error upon hitting one.
|
432
|
+
* TODO: How do we deal with empty lines? Try again? with the next
|
433
|
+
* line?
|
443
434
|
*/
|
444
435
|
if (len == PKT_LEN_SIZE) {
|
445
|
-
|
446
|
-
|
436
|
+
*head = NULL;
|
437
|
+
*out = line;
|
438
|
+
return 0;
|
447
439
|
}
|
448
440
|
|
449
441
|
if (len == 0) { /* Flush pkt */
|
@@ -50,7 +50,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
|
|
50
50
|
if ((recvd = gitno_recv(buf)) < 0)
|
51
51
|
return recvd;
|
52
52
|
|
53
|
-
if (recvd == 0
|
53
|
+
if (recvd == 0) {
|
54
54
|
giterr_set(GITERR_NET, "early EOF");
|
55
55
|
return GIT_EEOF;
|
56
56
|
}
|
@@ -222,8 +222,12 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf)
|
|
222
222
|
if (error < 0 && error != GIT_EBUFS)
|
223
223
|
return error;
|
224
224
|
|
225
|
-
if ((ret = gitno_recv(buf)) < 0)
|
225
|
+
if ((ret = gitno_recv(buf)) < 0) {
|
226
226
|
return ret;
|
227
|
+
} else if (ret == 0) {
|
228
|
+
giterr_set(GITERR_NET, "early EOF");
|
229
|
+
return GIT_EEOF;
|
230
|
+
}
|
227
231
|
} while (error);
|
228
232
|
|
229
233
|
gitno_consume(buf, line_end);
|
@@ -408,12 +412,12 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
|
|
408
412
|
|
409
413
|
if (i % 20 == 0 && t->rpc) {
|
410
414
|
git_pkt_ack *pkt;
|
411
|
-
unsigned int
|
415
|
+
unsigned int j;
|
412
416
|
|
413
417
|
if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
|
414
418
|
goto on_error;
|
415
419
|
|
416
|
-
git_vector_foreach(&t->common,
|
420
|
+
git_vector_foreach(&t->common, j, pkt) {
|
417
421
|
if ((error = git_pkt_buffer_have(&pkt->oid, &data)) < 0)
|
418
422
|
goto on_error;
|
419
423
|
}
|
@@ -428,12 +432,12 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
|
|
428
432
|
/* Tell the other end that we're done negotiating */
|
429
433
|
if (t->rpc && t->common.length > 0) {
|
430
434
|
git_pkt_ack *pkt;
|
431
|
-
unsigned int
|
435
|
+
unsigned int j;
|
432
436
|
|
433
437
|
if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
|
434
438
|
goto on_error;
|
435
439
|
|
436
|
-
git_vector_foreach(&t->common,
|
440
|
+
git_vector_foreach(&t->common, j, pkt) {
|
437
441
|
if ((error = git_pkt_buffer_have(&pkt->oid, &data)) < 0)
|
438
442
|
goto on_error;
|
439
443
|
}
|
@@ -724,7 +728,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
|
|
724
728
|
static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_buf *data_pkt_buf)
|
725
729
|
{
|
726
730
|
git_pkt *pkt;
|
727
|
-
const char *line, *line_end;
|
731
|
+
const char *line, *line_end = NULL;
|
728
732
|
size_t line_len;
|
729
733
|
int error;
|
730
734
|
int reading_from_buf = data_pkt_buf->size > 0;
|
@@ -759,6 +763,14 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt,
|
|
759
763
|
line_len -= (line_end - line);
|
760
764
|
line = line_end;
|
761
765
|
|
766
|
+
/* When a valid packet with no content has been
|
767
|
+
* read, git_pkt_parse_line does not report an
|
768
|
+
* error, but the pkt pointer has not been set.
|
769
|
+
* Handle this by skipping over empty packets.
|
770
|
+
*/
|
771
|
+
if (pkt == NULL)
|
772
|
+
continue;
|
773
|
+
|
762
774
|
error = add_push_report_pkt(push, pkt);
|
763
775
|
|
764
776
|
git_pkt_free(pkt);
|
@@ -813,6 +825,9 @@ static int parse_report(transport_smart *transport, git_push *push)
|
|
813
825
|
|
814
826
|
error = 0;
|
815
827
|
|
828
|
+
if (pkt == NULL)
|
829
|
+
continue;
|
830
|
+
|
816
831
|
switch (pkt->type) {
|
817
832
|
case GIT_PKT_DATA:
|
818
833
|
/* This is a sideband packet which contains other packets */
|
@@ -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,66 @@ 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
|
-
|
332
|
-
|
403
|
+
gitno_connection_data_free_ptrs(&t->proxy_connection_data);
|
404
|
+
|
405
|
+
if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL,
|
406
|
+
&t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0)
|
333
407
|
goto on_error;
|
408
|
+
|
409
|
+
if (t->proxy_connection_data.user && t->proxy_connection_data.pass) {
|
410
|
+
if (t->proxy_cred) {
|
411
|
+
t->proxy_cred->free(t->proxy_cred);
|
412
|
+
}
|
413
|
+
|
414
|
+
if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0)
|
415
|
+
goto on_error;
|
334
416
|
}
|
335
417
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
418
|
+
if (t->proxy_connection_data.use_ssl)
|
419
|
+
git_buf_PUTS(&processed_url, SCHEME_HTTPS);
|
420
|
+
else
|
421
|
+
git_buf_PUTS(&processed_url, SCHEME_HTTP);
|
422
|
+
|
423
|
+
git_buf_puts(&processed_url, t->proxy_connection_data.host);
|
424
|
+
if (t->proxy_connection_data.port)
|
425
|
+
git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port);
|
426
|
+
|
427
|
+
if (git_buf_oom(&processed_url)) {
|
428
|
+
giterr_set_oom();
|
429
|
+
error = -1;
|
430
|
+
goto on_error;
|
431
|
+
}
|
432
|
+
|
433
|
+
/* Convert URL to wide characters */
|
434
|
+
error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr);
|
435
|
+
git_buf_free(&processed_url);
|
436
|
+
if (error < 0)
|
437
|
+
goto on_error;
|
340
438
|
|
341
439
|
proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
342
440
|
proxy_info.lpszProxy = proxy_wide;
|
@@ -352,6 +450,14 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
352
450
|
}
|
353
451
|
|
354
452
|
git__free(proxy_wide);
|
453
|
+
|
454
|
+
if (t->proxy_cred) {
|
455
|
+
if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) {
|
456
|
+
if ((error = apply_basic_credential_proxy(s->request, t->proxy_cred)) < 0)
|
457
|
+
goto on_error;
|
458
|
+
}
|
459
|
+
}
|
460
|
+
|
355
461
|
}
|
356
462
|
|
357
463
|
/* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
|
@@ -919,6 +1025,26 @@ replay:
|
|
919
1025
|
goto replay;
|
920
1026
|
}
|
921
1027
|
|
1028
|
+
/* Handle proxy authentication failures */
|
1029
|
+
if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
|
1030
|
+
int allowed_types;
|
1031
|
+
|
1032
|
+
if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0)
|
1033
|
+
return -1;
|
1034
|
+
|
1035
|
+
/* TODO: extract the username from the url, no payload? */
|
1036
|
+
if (t->owner->proxy.credentials) {
|
1037
|
+
int cred_error = 1;
|
1038
|
+
cred_error = t->owner->proxy.credentials(&t->proxy_cred, t->owner->proxy.url, NULL, allowed_types, NULL);
|
1039
|
+
|
1040
|
+
if (cred_error < 0)
|
1041
|
+
return cred_error;
|
1042
|
+
}
|
1043
|
+
|
1044
|
+
winhttp_stream_close(s);
|
1045
|
+
goto replay;
|
1046
|
+
}
|
1047
|
+
|
922
1048
|
/* Handle authentication failures */
|
923
1049
|
if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
|
924
1050
|
int allowed_types;
|
@@ -1362,12 +1488,19 @@ static int winhttp_close(git_smart_subtransport *subtransport)
|
|
1362
1488
|
|
1363
1489
|
gitno_connection_data_free_ptrs(&t->connection_data);
|
1364
1490
|
memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
|
1491
|
+
gitno_connection_data_free_ptrs(&t->proxy_connection_data);
|
1492
|
+
memset(&t->proxy_connection_data, 0x0, sizeof(gitno_connection_data));
|
1365
1493
|
|
1366
1494
|
if (t->cred) {
|
1367
1495
|
t->cred->free(t->cred);
|
1368
1496
|
t->cred = NULL;
|
1369
1497
|
}
|
1370
1498
|
|
1499
|
+
if (t->proxy_cred) {
|
1500
|
+
t->proxy_cred->free(t->proxy_cred);
|
1501
|
+
t->proxy_cred = NULL;
|
1502
|
+
}
|
1503
|
+
|
1371
1504
|
if (t->url_cred) {
|
1372
1505
|
t->url_cred->free(t->url_cred);
|
1373
1506
|
t->url_cred = NULL;
|