static int filter_check( git_filter *self, void **payload, /* points to NULL ptr on entry, may be set */ const git_filter_source *src, const char **attr_values) { GIT_UNUSED(self); GIT_UNUSED(src); if (GIT_ATTR_UNSPECIFIED(attr_values[0])) return GIT_PASSTHROUGH; if (GIT_ATTR_FALSE(attr_values[0])) return GIT_PASSTHROUGH; if (GIT_ATTR_TRUE(attr_values[0])) return GIT_PASSTHROUGH; *payload = git__strdup(attr_values[0]); if (!*payload) { giterr_set_oom(); return -1; } return 0; }
int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field) { const char *eol, *buf = commit->raw_header; git_buf_clear(out); while ((eol = strchr(buf, '\n'))) { /* We can skip continuations here */ if (buf[0] == ' ') { buf = eol + 1; continue; } /* Skip until we find the field we're after */ if (git__prefixcmp(buf, field)) { buf = eol + 1; continue; } buf += strlen(field); /* Check that we're not matching a prefix but the field itself */ if (buf[0] != ' ') { buf = eol + 1; continue; } buf++; /* skip the SP */ git_buf_put(out, buf, eol - buf); if (git_buf_oom(out)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { git_buf_putc(out, '\n'); buf = eol + 2; eol = strchr(buf, '\n'); if (!eol) goto malformed; git_buf_put(out, buf, eol - buf); } if (git_buf_oom(out)) goto oom; return 0; } giterr_set(GITERR_OBJECT, "no such field '%s'", field); return GIT_ENOTFOUND; malformed: giterr_set(GITERR_OBJECT, "malformed header"); return -1; oom: giterr_set_oom(); return -1; }
static int ssh_stream_alloc( ssh_subtransport *t, const char *url, const char *cmd, git_smart_subtransport_stream **stream) { ssh_stream *s; git_buf *errBuf; assert(stream); s = git__calloc(sizeof(ssh_stream), 1); if (!s) { giterr_set_oom(); return -1; } errBuf = git__calloc(sizeof(git_buf), 1); if (!errBuf) { git__free(s); giterr_set_oom(); return -1; } s->parent.subtransport = &t->parent; s->parent.read = ssh_stream_read; s->parent.write = ssh_stream_write; s->parent.free = ssh_stream_free; s->cmd = cmd; s->url = git__strdup(url); if (!s->url) { git__free(errBuf); git__free(s); giterr_set_oom(); return -1; } command_init(&s->commandHandle); s->commandHandle.errBuf = errBuf; *stream = &s->parent; return 0; }
int git_strmap_alloc(git_strmap **map) { if ((*map = kh_init(str)) == NULL) { giterr_set_oom(); return -1; } return 0; }
int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field) { const char *buf = commit->raw_header; const char *h, *eol; git_buf_sanitize(out); while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') { h++; if (git__prefixcmp(h, field)) { buf = h; continue; } h += strlen(field); eol = strchr(h, '\n'); if (h[0] != ' ') { buf = h; continue; } if (!eol) goto malformed; h++; /* skip the SP */ git_buf_put(out, h, eol - h); if (git_buf_oom(out)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { git_buf_putc(out, '\n'); h = eol + 2; eol = strchr(h, '\n'); if (!eol) goto malformed; git_buf_put(out, h, eol - h); } if (git_buf_oom(out)) goto oom; return 0; } return GIT_ENOTFOUND; malformed: giterr_set(GITERR_OBJECT, "malformed header"); return -1; oom: giterr_set_oom(); return -1; }
static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, int from_glob) { git_oid commit_id; int error; git_object *obj, *oobj; git_commit_list_node *commit; git_commit_list *list; if ((error = git_object_lookup(&oobj, walk->repo, oid, GIT_OBJ_ANY)) < 0) return error; error = git_object_peel(&obj, oobj, GIT_OBJ_COMMIT); git_object_free(oobj); if (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC || error == GIT_EPEEL) { /* If this comes from e.g. push_glob("tags"), ignore this */ if (from_glob) return 0; giterr_set(GITERR_INVALID, "Object is not a committish"); return -1; } if (error < 0) return error; git_oid_cpy(&commit_id, git_object_id(obj)); git_object_free(obj); commit = git_revwalk__commit_lookup(walk, &commit_id); if (commit == NULL) return -1; /* error already reported by failed lookup */ /* A previous hide already told us we don't want this commit */ if (commit->uninteresting) return 0; if (uninteresting) walk->did_hide = 1; else walk->did_push = 1; commit->uninteresting = uninteresting; list = walk->user_input; if (git_commit_list_insert(commit, &list) == NULL) { giterr_set_oom(); return -1; } walk->user_input = list; return 0; }
static int zstream_seterr(git_zstream *zs) { if (zs->zerr == Z_OK || zs->zerr == Z_STREAM_END) return 0; if (zs->zerr == Z_MEM_ERROR) giterr_set_oom(); else if (zs->z.msg) giterr_set(GITERR_ZLIB, zs->z.msg); else giterr_set(GITERR_ZLIB, "Unknown compression error"); return -1; }
static int git_ssh_extract_url_parts( char **host, char **username, const char *url) { const char *colon, *at; const char *start; colon = strchr(url, ':'); at = strchr(url, '@'); if (at) { start = at + 1; *username = git__substrdup(url, at - url); if (!*username) { giterr_set_oom(); return -1; } } else { start = url; *username = NULL; } if (colon == NULL || (colon < start)) { giterr_set(GITERR_NET, "Malformed URL"); return -1; } *host = git__substrdup(start, colon - start); if (!*host) { giterr_set_oom(); return -1; } return 0; }
static HANDLE commmand_start_reading_thread(HANDLE *handle, git_buf *dest) { struct ASYNCREADINGTHREADARGS *threadArguments = git__calloc(1, sizeof(struct ASYNCREADINGTHREADARGS)); HANDLE thread; if (!threadArguments) { giterr_set_oom(); return NULL; } threadArguments->handle = handle; threadArguments->dest = dest; thread = CreateThread(NULL, 0, AsyncReadingThread, threadArguments, 0, NULL); if (!thread) { git__free(threadArguments); giterr_set(GITERR_OS, "Could not create thread"); } return thread; }
static int verify_last_error(git_filebuf *file) { switch (file->last_error) { case BUFERR_WRITE: giterr_set(GITERR_OS, "Failed to write out file"); return -1; case BUFERR_MEM: giterr_set_oom(); return -1; case BUFERR_ZLIB: giterr_set(GITERR_ZLIB, "Buffer error when writing out ZLib data"); return -1; default: return 0; } }
static int expandPerCentF(git_buf *buf, const char *replaceWith) { ssize_t foundPercentage = git_buf_find(buf, '%'); if (foundPercentage) { git_buf expanded = GIT_BUF_INIT; const char *end = buf->ptr + buf->size; const char *lastPercentage = buf->ptr; const char *idx = buf->ptr + foundPercentage; while (idx < end) { if (*idx == '%') { if (idx + 1 == end || (idx + 1 < end && *(idx + 1) == '%')) { // one '%' is at the end of the string OR "%%" is in the string git_buf_putc(&expanded, '%'); ++idx; ++idx; lastPercentage = idx; continue; } // now we know, that we're not at the end of the string and that the next char is not '%' git_buf_put(&expanded, lastPercentage, idx - lastPercentage); ++idx; if (*idx == 'f') git_buf_printf(&expanded, "\"%s\"", replaceWith); ++idx; lastPercentage = idx; continue; } ++idx; } if (lastPercentage) git_buf_put(&expanded, lastPercentage, idx - lastPercentage); if (git_buf_oom(&expanded)) { giterr_set_oom(); return -1; } git_buf_swap(buf, &expanded); git_buf_free(&expanded); } return 0; }
int git_smart_subtransport_ssh_wintunnel( git_smart_subtransport **out, git_transport *owner, LPCWSTR sshtoolpath, LPWSTR* pEnv) { ssh_subtransport *t; assert(out); t = git__calloc(sizeof(ssh_subtransport), 1); if (!t) { giterr_set_oom(); return -1; } t->sshtoolpath = wcsdup(sshtoolpath); t->pEnv = pEnv; t->owner = (transport_smart *)owner; t->parent.action = _ssh_action; t->parent.close = _ssh_close; t->parent.free = _ssh_free; *out = (git_smart_subtransport *) t; return 0; }
/* * Create a git protocol request. * * For example: git-upload-pack '/libgit2/libgit2' */ static int gen_proto(git_buf *request, const char *cmd, const char *url) { const char *repo; size_t i; for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { const char *p = ssh_prefixes[i]; if (!git__prefixcmp(url, p)) { url = url + strlen(p); repo = strchr(url, '/'); if (repo && repo[1] == '~') ++repo; goto done; } } repo = strchr(url, ':'); if (repo) repo++; done: if (!repo) { giterr_set(GITERR_NET, "Malformed git protocol URL"); return -1; } git_buf_printf(request, "\"%s '%s'\"", cmd, repo); if (git_buf_oom(request)) { giterr_set_oom(); return -1; } return 0; }
int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field) { git_odb_object *obj; git_odb *odb; const char *buf; const char *h, *eol; int error; git_buf_clear(signature); git_buf_clear(signed_data); if (!field) field = "gpgsig"; if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) return error; if ((error = git_odb_read(&obj, odb, commit_id)) < 0) return error; if (obj->cached.type != GIT_OBJECT_COMMIT) { giterr_set(GITERR_INVALID, "the requested type does not match the type in ODB"); error = GIT_ENOTFOUND; goto cleanup; } buf = git_odb_object_data(obj); while ((h = strchr(buf, '\n')) && h[1] != '\0') { h++; if (git__prefixcmp(buf, field)) { if (git_buf_put(signed_data, buf, h - buf) < 0) return -1; buf = h; continue; } h = buf; h += strlen(field); eol = strchr(h, '\n'); if (h[0] != ' ') { buf = h; continue; } if (!eol) goto malformed; h++; /* skip the SP */ git_buf_put(signature, h, eol - h); if (git_buf_oom(signature)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { git_buf_putc(signature, '\n'); h = eol + 2; eol = strchr(h, '\n'); if (!eol) goto malformed; git_buf_put(signature, h, eol - h); } if (git_buf_oom(signature)) goto oom; error = git_buf_puts(signed_data, eol+1); git_odb_object_free(obj); return error; } giterr_set(GITERR_OBJECT, "this commit is not signed"); error = GIT_ENOTFOUND; goto cleanup; malformed: giterr_set(GITERR_OBJECT, "malformed header"); error = -1; goto cleanup; oom: giterr_set_oom(); error = -1; goto cleanup; cleanup: git_odb_object_free(obj); git_buf_clear(signature); git_buf_clear(signed_data); return error; }
static int _git_ssh_setup_tunnel( ssh_subtransport *t, const char *url, const char *gitCmd, git_smart_subtransport_stream **stream) { char *host = NULL, *port = NULL, *path = NULL, *user = NULL, *pass = NULL; size_t i; ssh_stream *s; wchar_t *ssh = t->sshtoolpath; wchar_t *wideParams = NULL; wchar_t *cmd = NULL; git_buf params = GIT_BUF_INIT; int isPutty; size_t length; *stream = NULL; if (ssh_stream_alloc(t, url, gitCmd, stream) < 0) { giterr_set_oom(); return -1; } s = (ssh_stream *)*stream; for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { const char *p = ssh_prefixes[i]; if (!git__prefixcmp(url, p)) { if (extract_url_parts(&host, &port, &path, &user, &pass, url, NULL) < 0) goto on_error; goto post_extract; } } if (git_ssh_extract_url_parts(&host, &user, url) < 0) goto on_error; post_extract: if (!ssh) { giterr_set(GITERR_SSH, "No GIT_SSH tool configured"); goto on_error; } isPutty = wcstristr(ssh, L"plink"); if (port) { if (isPutty) git_buf_printf(¶ms, " -P %s", port); else git_buf_printf(¶ms, " -p %s", port); } if (isPutty && !wcstristr(ssh, L"tortoiseplink")) { git_buf_puts(¶ms, " -batch"); } if (user) git_buf_printf(¶ms, " %s@%s ", user, host); else git_buf_printf(¶ms, " %s ", host); if (gen_proto(¶ms, s->cmd, s->url)) goto on_error; if (git_buf_oom(¶ms)) { giterr_set_oom(); goto on_error; } if (git__utf8_to_16_alloc(&wideParams, params.ptr) < 0) { giterr_set_oom(); goto on_error; } git_buf_free(¶ms); length = wcslen(ssh) + wcslen(wideParams) + 3; cmd = git__calloc(length, sizeof(wchar_t)); if (!cmd) { giterr_set_oom(); goto on_error; } wcscat_s(cmd, length, L"\""); wcscat_s(cmd, length, ssh); wcscat_s(cmd, length, L"\""); wcscat_s(cmd, length, wideParams); if (command_start(cmd, &s->commandHandle, t->pEnv, isPutty ? CREATE_NEW_CONSOLE : DETACHED_PROCESS)) goto on_error; git__free(wideParams); git__free(cmd); t->current_stream = s; git__free(host); git__free(port); git__free(path); git__free(user); git__free(pass); return 0; on_error: t->current_stream = NULL; if (*stream) ssh_stream_free(*stream); git_buf_free(¶ms); if (wideParams) git__free(wideParams); if (cmd) git__free(cmd); git__free(host); git__free(port); git__free(user); git__free(pass); return -1; }
static int filter_apply( git_filter *self, void **payload, /* may be read and/or set */ git_buf *to, const git_buf *from, const git_filter_source *src) { struct filter_filter *ffs = (struct filter_filter *)self; git_config *config; git_buf configKey = GIT_BUF_INIT; int isRequired = FALSE; int error; const char *cmd = NULL; git_buf cmdBuf = GIT_BUF_INIT; wchar_t *wide_cmd; COMMAND_HANDLE commandHandle = COMMAND_HANDLE_INIT; git_buf errBuf = GIT_BUF_INIT; DWORD exitCode; if (!*payload) return GIT_PASSTHROUGH; if (git_repository_config__weakptr(&config, git_filter_source_repo(src))) return -1; git_buf_join3(&configKey, '.', "filter", *payload, "required"); if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_bool(&isRequired, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; git_buf_join(&configKey, '.', "filter", *payload); if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) { git_buf_puts(&configKey, ".smudge"); } else { git_buf_puts(&configKey, ".clean"); } if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_string(&cmd, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; if (error == GIT_ENOTFOUND) { if (isRequired) return -1; return GIT_PASSTHROUGH; } git_buf_puts(&cmdBuf, cmd); if (git_buf_oom(&cmdBuf)) { giterr_set_oom(); return -1; } if (expandPerCentF(&cmdBuf, git_filter_source_path(src))) return -1; if (ffs->shexepath) { // build params for sh.exe git_buf shParams = GIT_BUF_INIT; git_buf_puts(&shParams, " -c \""); git_buf_text_puts_escaped(&shParams, cmdBuf.ptr, "\"\\", "\\"); git_buf_puts(&shParams, "\""); if (git_buf_oom(&shParams)) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_swap(&shParams, &cmdBuf); git_buf_free(&shParams); } if (git__utf8_to_16_alloc(&wide_cmd, cmdBuf.ptr) < 0) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_free(&cmdBuf); if (ffs->shexepath) { // build cmd, i.e. shexepath + params size_t len = wcslen(ffs->shexepath) + wcslen(wide_cmd) + 1; wchar_t *tmp = git__calloc(len, sizeof(wchar_t)); if (!tmp) { git__free(wide_cmd); giterr_set_oom(); return -1; } wcscat_s(tmp, len, ffs->shexepath); wcscat_s(tmp, len, wide_cmd); git__free(wide_cmd); wide_cmd = tmp; } commandHandle.errBuf = &errBuf; if (command_start(wide_cmd, &commandHandle, ffs->pEnv)) { git__free(wide_cmd); if (isRequired) return -1; return GIT_PASSTHROUGH; } git__free(wide_cmd); if (commmand_start_stdout_reading_thread(&commandHandle, to)) { command_close(&commandHandle); return -1; } if (command_write_gitbuf(&commandHandle, from)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } command_close_stdin(&commandHandle); if (command_wait_stdout_reading_thread(&commandHandle)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } exitCode = command_close(&commandHandle); if (exitCode) { if (isRequired) { setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); return -1; } git_buf_free(&errBuf); return GIT_PASSTHROUGH; } git_buf_free(&errBuf); return 0; }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; size_t i; const git_proxy_options *proxy_opts; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP"); goto on_error; } proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { proxy_url = git__strdup(proxy_opts->url); GITERR_CHECK_ALLOC(proxy_url); } if (proxy_url) { git_buf processed_url = GIT_BUF_INIT; WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) { t->proxy_connection_data.use_ssl = false; } else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) { t->proxy_connection_data.use_ssl = true; } else { giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url); return -1; } gitno_connection_data_free_ptrs(&t->proxy_connection_data); if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL, &t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0) goto on_error; if (t->proxy_connection_data.user && t->proxy_connection_data.pass) { if (t->proxy_cred) { t->proxy_cred->free(t->proxy_cred); } if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0) goto on_error; } if (t->proxy_connection_data.use_ssl) git_buf_PUTS(&processed_url, SCHEME_HTTPS); else git_buf_PUTS(&processed_url, SCHEME_HTTP); git_buf_puts(&processed_url, t->proxy_connection_data.host); if (t->proxy_connection_data.port) git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port); if (git_buf_oom(&processed_url)) { giterr_set_oom(); error = -1; goto on_error; } /* Convert URL to wide characters */ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr); git_buf_free(&processed_url); if (error < 0) goto on_error; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); if (t->proxy_cred) { if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) { if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred)) < 0) goto on_error; } } } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } for (i = 0; i < t->owner->custom_headers.count; i++) { if (t->owner->custom_headers.strings[i]) { git_buf_clear(&buf); git_buf_puts(&buf, t->owner->custom_headers.strings[i]); if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert custom header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && apply_default_credentials(s->request, t->auth_mechanisms) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }