mirror of
https://github.com/actions/runner.git
synced 2026-07-07 13:21:08 +08:00
195 lines
6.9 KiB
C#
195 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Net.Security;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using GitHub.Services.WebApi.Utilities.Internal;
|
|
|
|
namespace GitHub.Services.Common
|
|
{
|
|
public class RawClientHttpRequestSettings
|
|
{
|
|
/// <summary>
|
|
/// Timespan to wait before timing out a request. Defaults to 100 seconds
|
|
/// </summary>
|
|
public TimeSpan SendTimeout
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// User-Agent header passed along in the request,
|
|
/// For multiple values, the order in the list is the order
|
|
/// in which they will appear in the header
|
|
/// </summary>
|
|
public List<ProductInfoHeaderValue> UserAgent
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The name of the culture is passed in the Accept-Language header
|
|
/// </summary>
|
|
public ICollection<CultureInfo> AcceptLanguages
|
|
{
|
|
get
|
|
{
|
|
return m_acceptLanguages;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A unique identifier for the user session
|
|
/// </summary>
|
|
public Guid SessionId
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Optional implementation used to validate server certificate validation
|
|
/// </summary>
|
|
public Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> ServerCertificateValidationCallback
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Number of times to retry a request that has an ambient failure
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This property is only used by RawConnection, so only relevant on the client
|
|
/// </remarks>
|
|
[DefaultValue(c_defaultMaxRetry)]
|
|
public Int32 MaxRetryRequest
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the property name used to reference this object.
|
|
/// </summary>
|
|
public const String PropertyName = "Actions.RequestSettings";
|
|
|
|
public static RawClientHttpRequestSettings Default => s_defaultSettings.Value;
|
|
|
|
protected RawClientHttpRequestSettings(RawClientHttpRequestSettings copy)
|
|
{
|
|
this.SendTimeout = copy.SendTimeout;
|
|
this.m_acceptLanguages = new List<CultureInfo>(copy.AcceptLanguages);
|
|
this.SessionId = copy.SessionId;
|
|
this.UserAgent = new List<ProductInfoHeaderValue>(copy.UserAgent);
|
|
this.ServerCertificateValidationCallback = copy.ServerCertificateValidationCallback;
|
|
this.MaxRetryRequest = copy.MaxRetryRequest;
|
|
}
|
|
|
|
public RawClientHttpRequestSettings Clone()
|
|
{
|
|
return new RawClientHttpRequestSettings(this);
|
|
}
|
|
|
|
public RawClientHttpRequestSettings()
|
|
: this(Guid.NewGuid())
|
|
{
|
|
}
|
|
|
|
public RawClientHttpRequestSettings(Guid sessionId)
|
|
{
|
|
this.SendTimeout = s_defaultTimeout;
|
|
if (!String.IsNullOrEmpty(CultureInfo.CurrentUICulture.Name)) // InvariantCulture for example has an empty name.
|
|
{
|
|
this.AcceptLanguages.Add(CultureInfo.CurrentUICulture);
|
|
}
|
|
this.SessionId = sessionId;
|
|
this.ServerCertificateValidationCallback = null;
|
|
|
|
// If different, we'll also add CurrentCulture to the request headers,
|
|
// but UICulture was added first, so it gets first preference
|
|
if (!CultureInfo.CurrentCulture.Equals(CultureInfo.CurrentUICulture) && !String.IsNullOrEmpty(CultureInfo.CurrentCulture.Name))
|
|
{
|
|
this.AcceptLanguages.Add(CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
this.MaxRetryRequest = c_defaultMaxRetry;
|
|
|
|
#if DEBUG
|
|
string customClientRequestTimeout = Environment.GetEnvironmentVariable("VSS_Client_Request_Timeout");
|
|
if (!string.IsNullOrEmpty(customClientRequestTimeout) && int.TryParse(customClientRequestTimeout, out int customTimeout))
|
|
{
|
|
// avoid disrupting a debug session due to the request timing out by setting a custom timeout.
|
|
this.SendTimeout = TimeSpan.FromSeconds(customTimeout);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
protected internal virtual Boolean ApplyTo(HttpRequestMessage request)
|
|
{
|
|
// Make sure we only apply the settings to the request once
|
|
if (request.Options.TryGetValue<object>(PropertyName, out _))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
request.Options.Set(new HttpRequestOptionsKey<RawClientHttpRequestSettings>(PropertyName), this);
|
|
|
|
if (this.AcceptLanguages != null && this.AcceptLanguages.Count > 0)
|
|
{
|
|
// An empty or null CultureInfo name will cause an ArgumentNullException in the
|
|
// StringWithQualityHeaderValue constructor. CultureInfo.InvariantCulture is an example of
|
|
// a CultureInfo that has an empty name.
|
|
foreach (CultureInfo culture in this.AcceptLanguages.Where(a => !String.IsNullOrEmpty(a.Name)))
|
|
{
|
|
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(culture.Name));
|
|
}
|
|
}
|
|
|
|
if (this.UserAgent != null)
|
|
{
|
|
foreach (var headerVal in this.UserAgent)
|
|
{
|
|
if (!request.Headers.UserAgent.Contains(headerVal))
|
|
{
|
|
request.Headers.UserAgent.Add(headerVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!request.Headers.Contains(Internal.RawHttpHeaders.SessionHeader))
|
|
{
|
|
request.Headers.Add(Internal.RawHttpHeaders.SessionHeader, this.SessionId.ToString("D"));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instance of the default request settings.
|
|
/// </summary>
|
|
/// <returns>The default request settings</returns>
|
|
private static RawClientHttpRequestSettings ConstructDefaultSettings()
|
|
{
|
|
// Set up reasonable defaults in case the registry keys are not present
|
|
var settings = new RawClientHttpRequestSettings();
|
|
settings.UserAgent = UserAgentUtility.GetDefaultRestUserAgent();
|
|
|
|
return settings;
|
|
}
|
|
|
|
private static Lazy<RawClientHttpRequestSettings> s_defaultSettings
|
|
= new Lazy<RawClientHttpRequestSettings>(ConstructDefaultSettings);
|
|
|
|
private const Int32 c_defaultMaxRetry = 3;
|
|
private static readonly TimeSpan s_defaultTimeout = TimeSpan.FromSeconds(100); //default WebAPI timeout
|
|
private ICollection<CultureInfo> m_acceptLanguages = new List<CultureInfo>();
|
|
}
|
|
}
|