#ifndef GIT_WINHTTP
-#include "git2.h"
#include "http_parser.h"
-#include "buffer.h"
#include "net.h"
#include "netops.h"
#include "remote.h"
-#include "git2/sys/credential.h"
#include "smart.h"
#include "auth.h"
#include "http.h"
#include "streams/tls.h"
#include "streams/socket.h"
#include "httpclient.h"
+#include "git2/sys/credential.h"
bool git_http__expect_continue = false;
const char *url;
const char *request_type;
const char *response_type;
- unsigned chunked : 1;
+ unsigned int initial : 1,
+ chunked : 1;
} http_service;
typedef struct {
GIT_HTTP_METHOD_GET, "/info/refs?service=git-upload-pack",
NULL,
"application/x-git-upload-pack-advertisement",
+ 1,
0
};
static const http_service upload_pack_service = {
GIT_HTTP_METHOD_POST, "/git-upload-pack",
"application/x-git-upload-pack-request",
"application/x-git-upload-pack-result",
+ 0,
0
};
static const http_service receive_pack_ls_service = {
GIT_HTTP_METHOD_GET, "/info/refs?service=git-receive-pack",
NULL,
"application/x-git-receive-pack-advertisement",
+ 1,
0
};
static const http_service receive_pack_service = {
GIT_HTTP_METHOD_POST, "/git-receive-pack",
"application/x-git-receive-pack-request",
"application/x-git-receive-pack-result",
+ 0,
1
};
git_http_response *response)
{
http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
+ git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
if (response->server_auth_credtypes == 0) {
git_error_set(GIT_ERROR_HTTP, "server requires authentication that we do not support");
transport->owner->url,
response->server_auth_schemetypes,
response->server_auth_credtypes,
- transport->owner->cred_acquire_cb,
- transport->owner->cred_acquire_payload);
+ connect_opts->callbacks.credentials,
+ connect_opts->callbacks.payload);
}
GIT_INLINE(int) handle_proxy_auth(
git_http_response *response)
{
http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
+ git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
if (response->proxy_auth_credtypes == 0) {
git_error_set(GIT_ERROR_HTTP, "proxy requires authentication that we do not support");
return handle_auth(
&transport->proxy,
SERVER_TYPE_PROXY,
- transport->owner->proxy.url,
+ connect_opts->proxy_opts.url,
response->server_auth_schemetypes,
response->proxy_auth_credtypes,
- transport->owner->proxy.credentials,
- transport->owner->proxy.payload);
+ connect_opts->proxy_opts.credentials,
+ connect_opts->proxy_opts.payload);
}
+static bool allow_redirect(http_stream *stream)
+{
+ http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
+
+ switch (transport->owner->connect_opts.follow_redirects) {
+ case GIT_REMOTE_REDIRECT_INITIAL:
+ return (stream->service->initial == 1);
+ case GIT_REMOTE_REDIRECT_ALL:
+ return true;
+ default:
+ return false;
+ }
+}
static int handle_response(
bool *complete,
return -1;
}
- if (git_net_url_apply_redirect(&transport->server.url, response->location, stream->service->url) < 0) {
+ if (git_net_url_apply_redirect(&transport->server.url, response->location, allow_redirect(stream), stream->service->url) < 0) {
return -1;
}
bool *out_use,
http_subtransport *transport)
{
+ git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
const char *proxy;
git_remote *remote;
char *config = NULL;
*out_use = false;
git_net_url_dispose(&transport->proxy.url);
- switch (transport->owner->proxy.type) {
+ switch (connect_opts->proxy_opts.type) {
case GIT_PROXY_SPECIFIED:
- proxy = transport->owner->proxy.url;
+ proxy = connect_opts->proxy_opts.url;
break;
case GIT_PROXY_AUTO:
request->credentials = transport->server.cred;
request->proxy = use_proxy ? &transport->proxy.url : NULL;
request->proxy_credentials = transport->proxy.cred;
- request->custom_headers = &transport->owner->custom_headers;
+ request->custom_headers = &transport->owner->connect_opts.custom_headers;
if (stream->service->method == GIT_HTTP_METHOD_POST) {
request->chunked = stream->service->chunked;
git_smart_service_t action)
{
http_subtransport *transport = GIT_CONTAINER_OF(t, http_subtransport, parent);
+ git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
http_stream *stream;
const http_service *service;
int error;
if (!transport->http_client) {
git_http_client_options opts = {0};
- opts.server_certificate_check_cb = transport->owner->certificate_check_cb;
- opts.server_certificate_check_payload = transport->owner->message_cb_payload;
- opts.proxy_certificate_check_cb = transport->owner->proxy.certificate_check;
- opts.proxy_certificate_check_payload = transport->owner->proxy.payload;
+ opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check;
+ opts.server_certificate_check_payload = connect_opts->callbacks.payload;
+ opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check;
+ opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload;
if (git_http_client_new(&transport->http_client, &opts) < 0)
return -1;