зеркало из https://github.com/mono/nuget.git
Fix of work item 4050: push does not follow redirect.
This commit is contained in:
Родитель
6c62b543c7
Коммит
2cda345ffd
|
@ -1,7 +1,7 @@
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Runtime Version:4.0.30319.34003
|
// Runtime Version:4.0.30319.34011
|
||||||
//
|
//
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// the code is regenerated.
|
// the code is regenerated.
|
||||||
|
@ -285,6 +285,15 @@ namespace NuGet.Resources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Too many automatic redirections were attempted..
|
||||||
|
/// </summary>
|
||||||
|
public static string Error_TooManyRedirections {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Error_TooManyRedirections", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to An error occurred while loading packages from '{0}': {1}.
|
/// Looks up a localized string similar to An error occurred while loading packages from '{0}': {1}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -469,4 +469,7 @@
|
||||||
<data name="Log_UninstallPackageFromProject" xml:space="preserve">
|
<data name="Log_UninstallPackageFromProject" xml:space="preserve">
|
||||||
<value>Remove '{0}' from project {1}.</value>
|
<value>Remove '{0}' from project {1}.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error_TooManyRedirections" xml:space="preserve">
|
||||||
|
<value>Too many automatic redirections were attempted.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -10,8 +10,9 @@ namespace NuGet
|
||||||
{
|
{
|
||||||
private const string ServiceEndpoint = "/api/v2/package";
|
private const string ServiceEndpoint = "/api/v2/package";
|
||||||
private const string ApiKeyHeader = "X-NuGet-ApiKey";
|
private const string ApiKeyHeader = "X-NuGet-ApiKey";
|
||||||
|
private const int MaxRediretionCount = 20;
|
||||||
|
|
||||||
private readonly Lazy<Uri> _baseUri;
|
private Lazy<Uri> _baseUri;
|
||||||
private readonly string _source;
|
private readonly string _source;
|
||||||
private readonly string _userAgent;
|
private readonly string _userAgent;
|
||||||
|
|
||||||
|
@ -79,34 +80,50 @@ namespace NuGet
|
||||||
long packageSize,
|
long packageSize,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient("", "PUT", "application/octet-stream");
|
int redirectionCount = 0;
|
||||||
|
while (true)
|
||||||
client.SendingRequest += (sender, e) =>
|
|
||||||
{
|
{
|
||||||
SendingRequest(this, e);
|
HttpClient client = GetClient("", "PUT", "application/octet-stream");
|
||||||
var request = (HttpWebRequest)e.Request;
|
|
||||||
request.AllowWriteStreamBuffering = false;
|
|
||||||
|
|
||||||
// Set the timeout
|
client.SendingRequest += (sender, e) =>
|
||||||
if (timeout <= 0)
|
|
||||||
{
|
{
|
||||||
timeout = request.ReadWriteTimeout; // Default to 5 minutes if the value is invalid.
|
SendingRequest(this, e);
|
||||||
|
var request = (HttpWebRequest)e.Request;
|
||||||
|
request.AllowWriteStreamBuffering = false;
|
||||||
|
|
||||||
|
// Set the timeout
|
||||||
|
if (timeout <= 0)
|
||||||
|
{
|
||||||
|
timeout = request.ReadWriteTimeout; // Default to 5 minutes if the value is invalid.
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Timeout = timeout;
|
||||||
|
request.ReadWriteTimeout = timeout;
|
||||||
|
if (!String.IsNullOrEmpty(apiKey))
|
||||||
|
{
|
||||||
|
request.Headers.Add(ApiKeyHeader, apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
var multiPartRequest = new MultipartWebRequest();
|
||||||
|
multiPartRequest.AddFile(packageStreamFactory, "package", packageSize);
|
||||||
|
|
||||||
|
multiPartRequest.CreateMultipartRequest(request);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Since AllowWriteStreamBuffering is set to false, redirection will not be handled
|
||||||
|
// automatically by HttpWebRequest. So we need to check redirect status code and
|
||||||
|
// update _baseUri and retry if redirection happens.
|
||||||
|
if (EnsureSuccessfulResponse(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Timeout = timeout;
|
++redirectionCount;
|
||||||
request.ReadWriteTimeout = timeout;
|
if (redirectionCount > MaxRediretionCount)
|
||||||
if (!String.IsNullOrEmpty(apiKey))
|
|
||||||
{
|
{
|
||||||
request.Headers.Add(ApiKeyHeader, apiKey);
|
throw new WebException(NuGetResources.Error_TooManyRedirections);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var multiPartRequest = new MultipartWebRequest();
|
|
||||||
multiPartRequest.AddFile(packageStreamFactory, "package", packageSize);
|
|
||||||
|
|
||||||
multiPartRequest.CreateMultipartRequest(request);
|
|
||||||
};
|
|
||||||
|
|
||||||
EnsureSuccessfulResponse(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -214,7 +231,15 @@ namespace NuGet
|
||||||
return requestUri;
|
return requestUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureSuccessfulResponse(HttpClient client, HttpStatusCode? expectedStatusCode = null)
|
/// <summary>
|
||||||
|
/// Ensures that success response is received.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">The client that is making the request.</param>
|
||||||
|
/// <param name="expectedStatusCode">The exected status code.</param>
|
||||||
|
/// <returns>True if success response is received; false if redirection response is received.
|
||||||
|
/// In this case, _baseUri will be updated to be the new redirected Uri and the requrest
|
||||||
|
/// should be retried.</returns>
|
||||||
|
private bool EnsureSuccessfulResponse(HttpClient client, HttpStatusCode? expectedStatusCode = null)
|
||||||
{
|
{
|
||||||
HttpWebResponse response = null;
|
HttpWebResponse response = null;
|
||||||
try
|
try
|
||||||
|
@ -229,6 +254,8 @@ namespace NuGet
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, NuGetResources.PackageServerError, response.StatusDescription, String.Empty));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, NuGetResources.PackageServerError, response.StatusDescription, String.Empty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
{
|
{
|
||||||
|
@ -237,10 +264,31 @@ namespace NuGet
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
response = (HttpWebResponse)e.Response;
|
response = (HttpWebResponse)e.Response;
|
||||||
|
|
||||||
|
// Check if the error is caused by redirection
|
||||||
|
if (response.StatusCode == HttpStatusCode.MultipleChoices ||
|
||||||
|
response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||||
|
response.StatusCode == HttpStatusCode.Found ||
|
||||||
|
response.StatusCode == HttpStatusCode.SeeOther ||
|
||||||
|
response.StatusCode == HttpStatusCode.TemporaryRedirect)
|
||||||
|
{
|
||||||
|
var location = response.Headers["Location"];
|
||||||
|
Uri newUri;
|
||||||
|
if (!Uri.TryCreate(client.Uri, location, out newUri))
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_baseUri = new Lazy<Uri>(() => newUri);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (expectedStatusCode != response.StatusCode)
|
if (expectedStatusCode != response.StatusCode)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, NuGetResources.PackageServerError, response.StatusDescription, e.Message), e);
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, NuGetResources.PackageServerError, response.StatusDescription, e.Message), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче