diff options
author | Matt Ward <matt.ward@xamarin.com> | 2015-06-09 14:09:33 +0300 |
---|---|---|
committer | Matt Ward <matt.ward@xamarin.com> | 2015-06-09 14:15:26 +0300 |
commit | 71f9800c69e2b192a249022716118e6efb27dd6b (patch) | |
tree | 4af2d8b4e026cda279f371fbc7f2869d50ef3c56 | |
parent | 4116eedea9e4f4b59ceb94d452bde5ec5874b8b2 (diff) |
[Core] Fix proxy credentials not requested for https url.proxy-authentication-https-url
When a system wide proxy is configured for all https requests then
a https url would fail to request proxy credentials on Mono and the
user will not be prompted. Instead the request would be retried 10
times and then fail.
This only affects https requests. Requests to http url will prompt
for proxy credentials.
The problem is a difference in behaviour of Mono compared with
Microsoft's .NET Framework when a proxy requires authentication and
a https url is requested:
https://bugzilla.xamarin.com/show_bug.cgi?id=19594
When connecting to a https url through a proxy that requires
authentication when using Microsoft's .NET Framework a WebException
is thrown with:
WebException.Status = ProtocolError
WebException.Response.StatusCode = ProxyAuthenticationRequired
On Mono a WebException is thrown with:
WebException.Status = SecureChannelFailure
WebException.Response = null
So now a check is made when not running on Windows to see if the
exception is a proxy authentication error.
3 files changed, 68 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/MonoProxyAuthenticationRequiredResponse.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/MonoProxyAuthenticationRequiredResponse.cs new file mode 100644 index 0000000000..65fa4cd913 --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/MonoProxyAuthenticationRequiredResponse.cs @@ -0,0 +1,51 @@ +// +// MonoProxyAuthenticationRequiredResponse.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2015 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Specialized; +using System.Net; + +namespace MonoDevelop.Core.Web +{ + class MonoProxyAuthenticationRequiredResponse : IHttpWebResponse + { + public MonoProxyAuthenticationRequiredResponse () + { + Headers = new NameValueCollection (); + StatusCode = HttpStatusCode.ProxyAuthenticationRequired; + } + + public void Dispose () + { + } + + public string AuthType { get; private set; } + public NameValueCollection Headers { get; private set; } + public Uri ResponseUri { get; private set; } + public HttpStatusCode StatusCode { get; private set; } + } +} + diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/RequestHelper.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/RequestHelper.cs index c3afcac25b..92a242707a 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/RequestHelper.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Web/RequestHelper.cs @@ -125,6 +125,14 @@ namespace MonoDevelop.Core.Web { if (_continueIfFailed) { + if (IsMonoProxyAuthenticationRequiredError (ex, response)) + { + _previousStatusCode = HttpStatusCode.ProxyAuthenticationRequired; + _previousResponse = new MonoProxyAuthenticationRequiredResponse (); + _previousRequest = request; + continue; + } + // Act like we got a 401 so that we prompt for credentials on the next request _previousStatusCode = HttpStatusCode.Unauthorized; continue; @@ -259,6 +267,14 @@ namespace MonoDevelop.Core.Web return httpWebResponse; } + private static bool IsMonoProxyAuthenticationRequiredError (WebException ex, IHttpWebResponse response) + { + return (response == null) && + !Platform.IsWindows && + (ex.Message != null) && + ex.Message.Contains ("The remote server returned a 407 status code."); + } + private static bool IsAuthenticationResponse(IHttpWebResponse response) { return response.StatusCode == HttpStatusCode.Unauthorized || diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj index 85d70f49fd..6a2927e67f 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj @@ -479,6 +479,7 @@ <Compile Include="MonoDevelop.Projects\ProjectOperationContext.cs" /> <Compile Include="MonoDevelop.Projects\TargetEvaluationContext.cs" /> <Compile Include="MonoDevelop.Projects\TargetEvaluationResult.cs" /> + <Compile Include="MonoDevelop.Core.Web\MonoProxyAuthenticationRequiredResponse.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> |