Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
4a88eb20
Commit
4a88eb20
authored
Sep 25, 2013
by
Ben Straub
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Win32: handle http->https redirects
parent
4dbdbf64
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
159 additions
and
91 deletions
+159
-91
src/transports/winhttp.c
+159
-91
No files found.
src/transports/winhttp.c
View file @
4a88eb20
...
@@ -73,7 +73,7 @@ typedef struct {
...
@@ -73,7 +73,7 @@ typedef struct {
typedef
struct
{
typedef
struct
{
git_smart_subtransport
parent
;
git_smart_subtransport
parent
;
transport_smart
*
owner
;
transport_smart
*
owner
;
c
onst
c
har
*
path
;
char
*
path
;
char
*
host
;
char
*
host
;
char
*
port
;
char
*
port
;
char
*
user_from_url
;
char
*
user_from_url
;
...
@@ -152,6 +152,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
...
@@ -152,6 +152,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
wchar_t
*
types
[]
=
{
L"*/*"
,
NULL
};
wchar_t
*
types
[]
=
{
L"*/*"
,
NULL
};
BOOL
peerdist
=
FALSE
;
BOOL
peerdist
=
FALSE
;
int
error
=
-
1
,
wide_len
;
int
error
=
-
1
,
wide_len
;
unsigned
long
disable_redirects
=
WINHTTP_DISABLE_REDIRECTS
;
/* Prepare URL */
/* Prepare URL */
git_buf_printf
(
&
buf
,
"%s%s"
,
t
->
path
,
s
->
service_url
);
git_buf_printf
(
&
buf
,
"%s%s"
,
t
->
path
,
s
->
service_url
);
...
@@ -244,6 +245,14 @@ static int winhttp_stream_connect(winhttp_stream *s)
...
@@ -244,6 +245,14 @@ static int winhttp_stream_connect(winhttp_stream *s)
git__free
(
proxy_wide
);
git__free
(
proxy_wide
);
}
}
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
/* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP
* adds itself. This option may not be supported by the underlying
* adds itself. This option may not be supported by the underlying
* platform, so we do not error-check it */
* platform, so we do not error-check it */
...
@@ -380,6 +389,142 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
...
@@ -380,6 +389,142 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
return
0
;
return
0
;
}
}
static
void
free_connection_data
(
winhttp_subtransport
*
t
)
{
if
(
t
->
host
)
{
git__free
(
t
->
host
);
t
->
host
=
NULL
;
}
if
(
t
->
port
)
{
git__free
(
t
->
port
);
t
->
port
=
NULL
;
}
if
(
t
->
user_from_url
)
{
git__free
(
t
->
user_from_url
);
t
->
user_from_url
=
NULL
;
}
if
(
t
->
pass_from_url
)
{
git__free
(
t
->
pass_from_url
);
t
->
pass_from_url
=
NULL
;
}
if
(
t
->
path
)
{
git__free
(
t
->
path
);
t
->
path
=
NULL
;
}
}
static
int
set_connection_data_from_url
(
winhttp_subtransport
*
t
,
const
char
*
url
,
const
char
*
service_suffix
)
{
int
error
=
0
;
const
char
*
default_port
=
NULL
;
char
*
original_host
=
NULL
;
const
char
*
original_url
=
url
;
if
(
!
git__prefixcmp
(
url
,
prefix_http
))
{
url
+=
strlen
(
prefix_http
);
default_port
=
"80"
;
if
(
t
->
use_ssl
)
{
giterr_set
(
GITERR_NET
,
"Redirect from HTTPS to HTTP not allowed"
);
return
-
1
;
}
}
if
(
!
git__prefixcmp
(
url
,
prefix_https
))
{
url
+=
strlen
(
prefix_https
);
default_port
=
"443"
;
t
->
use_ssl
=
1
;
}
if
(
!
default_port
)
{
giterr_set
(
GITERR_NET
,
"Unrecognized URL prefix"
);
return
-
1
;
}
/* preserve original host name for checking */
original_host
=
t
->
host
;
t
->
host
=
NULL
;
free_connection_data
(
t
);
error
=
gitno_extract_url_parts
(
&
t
->
host
,
&
t
->
port
,
&
t
->
user_from_url
,
&
t
->
pass_from_url
,
url
,
default_port
);
if
(
!
error
)
{
const
char
*
path
=
strchr
(
url
,
'/'
);
size_t
pathlen
=
strlen
(
path
);
size_t
suffixlen
=
service_suffix
?
strlen
(
service_suffix
)
:
0
;
if
(
suffixlen
&&
!
memcmp
(
path
+
pathlen
-
suffixlen
,
service_suffix
,
suffixlen
))
t
->
path
=
git__strndup
(
path
,
pathlen
-
suffixlen
);
else
t
->
path
=
git__strdup
(
path
);
/* Allow '/'-led urls, or a change of protocol */
if
(
original_host
!=
NULL
)
{
if
(
strcmp
(
original_host
,
t
->
host
)
&&
original_url
[
0
]
!=
'/'
)
{
giterr_set
(
GITERR_NET
,
"Cross host redirect not allowed"
);
error
=
-
1
;
}
git__free
(
original_host
);
}
}
return
error
;
}
static
int
winhttp_connect
(
winhttp_subtransport
*
t
,
const
char
*
url
)
{
wchar_t
*
ua
=
L"git/1.0 (libgit2 "
WIDEN
(
LIBGIT2_VERSION
)
L")"
;
git_win32_path
host
;
int32_t
port
;
const
char
*
default_port
=
"80"
;
/* Prepare port */
if
(
git__strtol32
(
&
port
,
t
->
port
,
NULL
,
10
)
<
0
)
return
-
1
;
/* Prepare host */
git_win32_path_from_c
(
host
,
t
->
host
);
/* Establish session */
t
->
session
=
WinHttpOpen
(
ua
,
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
WINHTTP_NO_PROXY_NAME
,
WINHTTP_NO_PROXY_BYPASS
,
0
);
if
(
!
t
->
session
)
{
giterr_set
(
GITERR_OS
,
"Failed to init WinHTTP"
);
return
-
1
;
}
/* Establish connection */
t
->
connection
=
WinHttpConnect
(
t
->
session
,
host
,
(
INTERNET_PORT
)
port
,
0
);
if
(
!
t
->
connection
)
{
giterr_set
(
GITERR_OS
,
"Failed to connect to host"
);
return
-
1
;
}
return
0
;
}
static
int
winhttp_stream_read
(
static
int
winhttp_stream_read
(
git_smart_subtransport_stream
*
stream
,
git_smart_subtransport_stream
*
stream
,
char
*
buffer
,
char
*
buffer
,
...
@@ -511,10 +656,9 @@ replay:
...
@@ -511,10 +656,9 @@ replay:
/* Check for Windows 7. This workaround is only necessary on
/* Check for Windows 7. This workaround is only necessary on
* Windows Vista and earlier. Windows 7 is version 6.1. */
* Windows Vista and earlier. Windows 7 is version 6.1. */
if
(
!
git_has_win32_version
(
6
,
1
,
0
))
{
wchar_t
*
location
;
wchar_t
*
location
;
DWORD
location_length
;
DWORD
location_length
;
int
redirect_cmp
;
char
*
location8
;
/* OK, fetch the Location header from the redirect. */
/* OK, fetch the Location header from the redirect. */
if
(
WinHttpQueryHeaders
(
s
->
request
,
if
(
WinHttpQueryHeaders
(
s
->
request
,
...
@@ -529,6 +673,7 @@ replay:
...
@@ -529,6 +673,7 @@ replay:
}
}
location
=
git__malloc
(
location_length
);
location
=
git__malloc
(
location_length
);
location8
=
git__malloc
(
location_length
);
GITERR_CHECK_ALLOC
(
location
);
GITERR_CHECK_ALLOC
(
location
);
if
(
!
WinHttpQueryHeaders
(
s
->
request
,
if
(
!
WinHttpQueryHeaders
(
s
->
request
,
...
@@ -541,20 +686,22 @@ replay:
...
@@ -541,20 +686,22 @@ replay:
git__free
(
location
);
git__free
(
location
);
return
-
1
;
return
-
1
;
}
}
git__utf16_to_8
(
location8
,
location_length
,
location
);
/* Compare the Location header with the request URI */
redirect_cmp
=
wcscmp
(
location
,
s
->
request_uri
);
git__free
(
location
);
git__free
(
location
);
if
(
!
redirect_cmp
)
{
/* Replay the request */
/* Replay the request */
WinHttpCloseHandle
(
s
->
request
);
WinHttpCloseHandle
(
s
->
request
);
s
->
request
=
NULL
;
s
->
request
=
NULL
;
s
->
sent_request
=
0
;
s
->
sent_request
=
0
;
goto
replay
;
if
(
!
git__prefixcmp_icase
(
location8
,
prefix_https
))
{
}
/* Upgrade to secure connection; disconnect and start over */
set_connection_data_from_url
(
t
,
location8
,
s
->
service_url
);
winhttp_connect
(
t
,
location8
);
}
}
git__free
(
location8
);
goto
replay
;
}
}
/* Handle authentication failures */
/* Handle authentication failures */
...
@@ -888,68 +1035,6 @@ static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream
...
@@ -888,68 +1035,6 @@ static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream
return
0
;
return
0
;
}
}
static
int
winhttp_connect
(
winhttp_subtransport
*
t
,
const
char
*
url
)
{
wchar_t
*
ua
=
L"git/1.0 (libgit2 "
WIDEN
(
LIBGIT2_VERSION
)
L")"
;
git_win32_path
host
;
int32_t
port
;
const
char
*
default_port
=
"80"
;
int
ret
;
if
(
!
git__prefixcmp
(
url
,
prefix_http
))
{
url
=
url
+
strlen
(
prefix_http
);
default_port
=
"80"
;
}
if
(
!
git__prefixcmp
(
url
,
prefix_https
))
{
url
+=
strlen
(
prefix_https
);
default_port
=
"443"
;
t
->
use_ssl
=
1
;
}
if
((
ret
=
gitno_extract_url_parts
(
&
t
->
host
,
&
t
->
port
,
&
t
->
user_from_url
,
&
t
->
pass_from_url
,
url
,
default_port
))
<
0
)
return
ret
;
t
->
path
=
strchr
(
url
,
'/'
);
/* Prepare port */
if
(
git__strtol32
(
&
port
,
t
->
port
,
NULL
,
10
)
<
0
)
return
-
1
;
/* Prepare host */
git_win32_path_from_c
(
host
,
t
->
host
);
/* Establish session */
t
->
session
=
WinHttpOpen
(
ua
,
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
WINHTTP_NO_PROXY_NAME
,
WINHTTP_NO_PROXY_BYPASS
,
0
);
if
(
!
t
->
session
)
{
giterr_set
(
GITERR_OS
,
"Failed to init WinHTTP"
);
return
-
1
;
}
/* Establish connection */
t
->
connection
=
WinHttpConnect
(
t
->
session
,
host
,
(
INTERNET_PORT
)
port
,
0
);
if
(
!
t
->
connection
)
{
giterr_set
(
GITERR_OS
,
"Failed to connect to host"
);
return
-
1
;
}
return
0
;
}
static
int
winhttp_uploadpack_ls
(
static
int
winhttp_uploadpack_ls
(
winhttp_subtransport
*
t
,
winhttp_subtransport
*
t
,
winhttp_stream
*
s
)
winhttp_stream
*
s
)
...
@@ -1014,7 +1099,8 @@ static int winhttp_action(
...
@@ -1014,7 +1099,8 @@ static int winhttp_action(
int
ret
=
-
1
;
int
ret
=
-
1
;
if
(
!
t
->
connection
&&
if
(
!
t
->
connection
&&
winhttp_connect
(
t
,
url
)
<
0
)
(
set_connection_data_from_url
(
t
,
url
,
NULL
)
<
0
||
winhttp_connect
(
t
,
url
)
<
0
))
return
-
1
;
return
-
1
;
if
(
winhttp_stream_alloc
(
t
,
&
s
)
<
0
)
if
(
winhttp_stream_alloc
(
t
,
&
s
)
<
0
)
...
@@ -1056,25 +1142,7 @@ static int winhttp_close(git_smart_subtransport *subtransport)
...
@@ -1056,25 +1142,7 @@ static int winhttp_close(git_smart_subtransport *subtransport)
winhttp_subtransport
*
t
=
(
winhttp_subtransport
*
)
subtransport
;
winhttp_subtransport
*
t
=
(
winhttp_subtransport
*
)
subtransport
;
int
ret
=
0
;
int
ret
=
0
;
if
(
t
->
host
)
{
free_connection_data
(
t
);
git__free
(
t
->
host
);
t
->
host
=
NULL
;
}
if
(
t
->
port
)
{
git__free
(
t
->
port
);
t
->
port
=
NULL
;
}
if
(
t
->
user_from_url
)
{
git__free
(
t
->
user_from_url
);
t
->
user_from_url
=
NULL
;
}
if
(
t
->
pass_from_url
)
{
git__free
(
t
->
pass_from_url
);
t
->
pass_from_url
=
NULL
;
}
if
(
t
->
cred
)
{
if
(
t
->
cred
)
{
t
->
cred
->
free
(
t
->
cred
);
t
->
cred
->
free
(
t
->
cred
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment