@@ -66,6 +66,11 @@ public abstract class ProviderBase<TProvider>
6666 /// </summary>
6767 private IBackoffPolicy _backoffPolicy ;
6868
69+ /// <summary>
70+ /// This is the backing field for the <see cref="ApplicationUserAgent"/> property.
71+ /// </summary>
72+ private string _applicationUserAgent ;
73+
6974 /// <summary>
7075 /// Initializes a new instance of the <see cref="ProviderBase{TProvider}"/> class using
7176 /// the specified default identity, default region, identity provider, and REST service
@@ -166,6 +171,36 @@ public IBackoffPolicy BackoffPolicy
166171 }
167172 }
168173
174+ /// <summary>
175+ /// Gets or sets the application-specific user agent for the provider instance.
176+ /// </summary>
177+ /// <remarks>
178+ /// <para>This value is used for determining the <see cref="DefaultUserAgent"/> value. The documentation for
179+ /// that property includes specific information.</para>
180+ /// <para>The default value is <see langword="null"/>.</para>
181+ /// </remarks>
182+ /// <value>
183+ /// <para>The application-specific user agent, as a string. This string should be a valid
184+ /// <strong>User-Agent</strong> header value according to RFC 7231.</para>
185+ /// <para>-or-</para>
186+ /// <para><see langword="null"/> (or <see cref="string.Empty"/>) if the provider should not include an
187+ /// application-specific user agent in HTTP requests, or if the user agent is customized in another manner (such
188+ /// as overriding the <see cref="BuildDefaultRequestSettings"/> method.</para>
189+ /// </value>
190+ /// <preliminary/>
191+ public string ApplicationUserAgent
192+ {
193+ get
194+ {
195+ return _applicationUserAgent ;
196+ }
197+
198+ set
199+ {
200+ _applicationUserAgent = value ;
201+ }
202+ }
203+
169204 /// <summary>
170205 /// Gets the default back-off policy for the current provider.
171206 /// </summary>
@@ -182,6 +217,32 @@ protected virtual IBackoffPolicy DefaultBackoffPolicy
182217 }
183218 }
184219
220+ /// <summary>
221+ /// Gets the default value for the <strong>User-Agent</strong> header for HTTP requests sent by this provider.
222+ /// </summary>
223+ /// <remarks>
224+ /// <para>If the <see cref="ApplicationUserAgent"/> property is not set, this property simply returns
225+ /// <see cref="UserAgentGenerator.UserAgent"/>.</para>
226+ /// <para>If the <see cref="ApplicationUserAgent"/> property is set, this property returns a two-part user agent
227+ /// starting with the <see cref="ApplicationUserAgent"/> value, followed by the
228+ /// <see cref="UserAgentGenerator.UserAgent"/> value.</para>
229+ /// </remarks>
230+ /// <value>
231+ /// The default value for the <strong>User-Agent</strong> header for HTTP requests sent by this provider.
232+ /// </value>
233+ protected string DefaultUserAgent
234+ {
235+ get
236+ {
237+ string userAgent = UserAgentGenerator . UserAgent ;
238+ string applicationUserAgent = ApplicationUserAgent ;
239+ if ( ! string . IsNullOrEmpty ( applicationUserAgent ) )
240+ return applicationUserAgent + " " + userAgent ;
241+
242+ return userAgent ;
243+ }
244+ }
245+
185246 /// <summary>
186247 /// Execute a REST request with an <see cref="object"/> body and strongly-typed result.
187248 /// </summary>
@@ -439,7 +500,7 @@ private T ExecuteRESTRequest<T>(CloudIdentity identity, Uri absoluteUri, HttpMet
439500 }
440501
441502 if ( string . IsNullOrEmpty ( requestSettings . UserAgent ) )
442- requestSettings . UserAgent = UserAgentGenerator . UserAgent ;
503+ requestSettings . UserAgent = DefaultUserAgent ;
443504
444505 var response = callback ( absoluteUri , method , bodyStr , headers , queryStringParameter , requestSettings ) ;
445506
@@ -536,7 +597,7 @@ protected Response StreamRESTRequest(CloudIdentity identity, Uri absoluteUri, Ht
536597 headers [ "X-Auth-Token" ] = IdentityProvider . GetToken ( identity , isRetry ) . Id ;
537598
538599 if ( string . IsNullOrEmpty ( requestSettings . UserAgent ) )
539- requestSettings . UserAgent = UserAgentGenerator . UserAgent ;
600+ requestSettings . UserAgent = DefaultUserAgent ;
540601
541602 long ? initialPosition ;
542603 try
@@ -609,7 +670,7 @@ protected Response StreamRESTRequest(CloudIdentity identity, Uri absoluteUri, Ht
609670 /// <item>The <see cref="RequestSettings.RetryCount"/> is 0.</item>
610671 /// <item>The <see cref="RequestSettings.RetryDelay"/> is 200 milliseconds.</item>
611672 /// <item>The <see cref="RequestSettings.Non200SuccessCodes"/> contains <see cref="HttpStatusCode.Unauthorized"/> and <see cref="HttpStatusCode.Conflict"/>, along with the values in <paramref name="non200SuccessCodes"/> (if any).</item>
612- /// <item>The <see cref="RequestSettings.UserAgent"/> is set to <see cref="UserAgentGenerator.UserAgent "/>.</item>
673+ /// <item>The <see cref="RequestSettings.UserAgent"/> is set to <see cref="DefaultUserAgent "/>.</item>
613674 /// <item>The <see cref="RequestSettings.AllowZeroContentLength"/> is set to <see langword="true"/>.</item>
614675 /// <item>The <see cref="RequestSettings.ConnectionLimit"/> is set to <see cref="ConnectionLimit"/>.</item>
615676 /// <item>Other properties are set to the default values for <see cref="JsonRequestSettings"/>.</item>
@@ -630,7 +691,7 @@ protected virtual RequestSettings BuildDefaultRequestSettings(IEnumerable<HttpSt
630691 RetryCount = 0 ,
631692 RetryDelay = TimeSpan . FromMilliseconds ( 200 ) ,
632693 Non200SuccessCodes = non200SuccessCodesAggregate ,
633- UserAgent = UserAgentGenerator . UserAgent ,
694+ UserAgent = DefaultUserAgent ,
634695 AllowZeroContentLength = true ,
635696 ConnectionLimit = ConnectionLimit ,
636697 } ;
@@ -1045,7 +1106,7 @@ protected virtual byte[] EncodeRequestBodyImpl<TBody>(HttpWebRequest request, TB
10451106 /// </item>
10461107 /// <item>
10471108 /// <description><see cref="HttpWebRequest.UserAgent"/></description>
1048- /// <description><see cref="UserAgentGenerator.UserAgent "/></description>
1109+ /// <description><see cref="DefaultUserAgent "/></description>
10491110 /// </item>
10501111 /// <item>
10511112 /// <description><see cref="WebRequest.Timeout"/></description>
@@ -1085,7 +1146,7 @@ protected virtual HttpWebRequest PrepareRequestImpl(HttpMethod method, IdentityT
10851146 request . Method = method . ToString ( ) . ToUpperInvariant ( ) ;
10861147 request . Accept = JsonRequestSettings . JsonContentType ;
10871148 request . Headers [ "X-Auth-Token" ] = identityToken . Id ;
1088- request . UserAgent = UserAgentGenerator . UserAgent ;
1149+ request . UserAgent = DefaultUserAgent ;
10891150 request . Timeout = ( int ) TimeSpan . FromSeconds ( 14400 ) . TotalMilliseconds ;
10901151 if ( ConnectionLimit . HasValue )
10911152 request . ServicePoint . ConnectionLimit = ConnectionLimit . Value ;
0 commit comments