Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(264)

Delta Between Two Patch Sets: Src/GoogleApis/Apis/Services/BaseClientService.cs

Issue 13096044: Issue 146: Pass override HTTP header when request URI too long (Closed)
Left Patch Set: Comments Created 10 years, 7 months ago
Right Patch Set: Refactor namespace Created 10 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Src/GoogleApis/Apis/Http/MaxUrlLengthInterceptor.cs ('k') | Src/GoogleApis/GoogleApis.csproj » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 Copyright 2013 Google Inc 2 Copyright 2013 Google Inc
3 3
4 Licensed under the Apache License, Version 2.0 (the "License"); 4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License. 5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at 6 You may obtain a copy of the License at
7 7
8 http://www.apache.org/licenses/LICENSE-2.0 8 http://www.apache.org/licenses/LICENSE-2.0
9 9
10 Unless required by applicable law or agreed to in writing, software 10 Unless required by applicable law or agreed to in writing, software
(...skipping 25 matching lines...) Expand all
36 36
37 namespace Google.Apis.Services 37 namespace Google.Apis.Services
38 { 38 {
39 /// <summary> 39 /// <summary>
40 /// A thread-safe base class for a client service which provides common mech anism for all services, like· 40 /// A thread-safe base class for a client service which provides common mech anism for all services, like·
41 /// serialization and GZip support. 41 /// serialization and GZip support.
42 /// This class adds a special <see cref="Google.Apis.Http.IHttpExecuteInterc eptor"/> to the· 42 /// This class adds a special <see cref="Google.Apis.Http.IHttpExecuteInterc eptor"/> to the·
43 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/> execute interc eptor list, which uses the given· 43 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/> execute interc eptor list, which uses the given·
44 /// Authenticator. It calls to its applying authentication method, and injec ts the "Authorization" header in the· 44 /// Authenticator. It calls to its applying authentication method, and injec ts the "Authorization" header in the·
45 /// request. 45 /// request.
46 /// If the given Authenticator implements <see cref="Google.Apis.Http.IUnsuc cessfulReponseHandler"/>, this class 46 /// If the given Authenticator implements <see cref="Google.Apis.Http.IHttpU nsuccessfulResponseHandler"/>, this·
47 /// adds the Authenticator to the <see cref="Google.Apis.Http.ConfigurableMe ssageHandler"/>'s unsuccessful response 47 /// class adds the Authenticator to the <see cref="Google.Apis.Http.Configur ableMessageHandler"/>'s unsuccessful·
48 /// handler list. 48 /// response handler list.
49 /// </summary> 49 /// </summary>
50 public abstract class BaseClientService : IClientService 50 public abstract class BaseClientService : IClientService
51 { 51 {
52 /// <summary> The class logger. </summary> 52 /// <summary>The class logger.</summary>
53 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<BaseClientService>(); 53 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<BaseClientService>();
54 54
55 /// <summary>The default maximum allowed length of a URL string for GET requests.</summary> 55 /// <summary>The default maximum allowed length of a URL string for GET requests.</summary>
56 private const uint DefaultMaxUrlLength = 2048; 56 [VisibleForTestOnly]
57 internal const uint DefaultMaxUrlLength = 2048;
57 58
58 #region Initializer 59 #region Initializer
59 60
60 /// <summary>· 61 /// <summary>An initializer class for the client service.</summary>
61 /// Indicates if exponential back-off is used automatically on exception in a service request and\or when 503·
62 /// response is returned form the server.
63 /// </summary>
64 [Flags]
65 public enum ExponentialBackOffPolicy
66 {
67 None = 0,
68 Exception = 1,
69 UnsuccessfulResponse503 = 2
70 }
71
72 /// <summary> An initializer class for the client service. </summary>
73 public class Initializer 62 public class Initializer
74 { 63 {
75 /// <summary> 64 /// <summary>
76 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. If this· 65 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. If this·
77 /// property is not set the service uses a new <see cref="Google.Api s.Http.HttpClientFactory"/> instance. 66 /// property is not set the service uses a new <see cref="Google.Api s.Http.HttpClientFactory"/> instance.
78 /// </summary> 67 /// </summary>
79 public IHttpClientFactory HttpClientFactory { get; set; } 68 public IHttpClientFactory HttpClientFactory { get; set; }
80 69
81 /// <summary> 70 /// <summary>
82 /// Gets or sets an Http client initializer which is able to customi ze properties on· 71 /// Gets or sets a HTTP client initializer which is able to customiz e properties on·
83 /// <see cref="Google.Apis.Http.ConfigurableHttpClient"/> and· 72 /// <see cref="Google.Apis.Http.ConfigurableHttpClient"/> and·
84 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/>. 73 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/>.
85 /// </summary> 74 /// </summary>
86 public IConfigurableHttpClientInitializer HttpClientInitializer { ge t; set; } 75 public IConfigurableHttpClientInitializer HttpClientInitializer { ge t; set; }
87 76
88 /// <summary> 77 /// <summary>
89 /// Get or sets the exponential back-off policy used by the service. Default value is· 78 /// Get or sets the exponential back-off policy used by the service. Default value is·
90 /// <c>UnsuccessfulResponse503</c>, which means that exponential bac k-off is used on 503 abnormal HTTP 79 /// <c>UnsuccessfulResponse503</c>, which means that exponential bac k-off is used on 503 abnormal HTTP
91 /// response. 80 /// response.
92 /// If the value is set to <c>None</c>, no exponential back-off poli cy is used, and it's up to user to 81 /// If the value is set to <c>None</c>, no exponential back-off poli cy is used, and it's up to user to
93 /// configure the <seealso cref="Google.Apis.Http.ConfigurableMessag eHandler"/> in an 82 /// configure the <seealso cref="Google.Apis.Http.ConfigurableMessag eHandler"/> in an
94 /// <seealso cref="Google.Apis.Http.IConfigurableHttpClientInitializ er"/> to set a specific back-off 83 /// <seealso cref="Google.Apis.Http.IConfigurableHttpClientInitializ er"/> to set a specific back-off
95 /// implementation (using <seealso cref="Google.Api.Http.BackOffHand ler"/>). 84 /// implementation (using <seealso cref="Google.Apis.Http.BackOffHan dler"/>).
96 /// </summary> 85 /// </summary>
97 public ExponentialBackOffPolicy DefaultExponentialBackOffPolicy { ge t; set; } 86 public ExponentialBackOffPolicy DefaultExponentialBackOffPolicy { ge t; set; }
98 87
99 /// <summary> Gets or sets whether this service supports GZip. Defau lt value is <c>true</c>. </summary> 88 /// <summary>Gets or sets whether this service supports GZip. Defaul t value is <c>true</c>.</summary>
100 public bool GZipEnabled { get; set; } 89 public bool GZipEnabled { get; set; }
101 90
102 /// <summary> 91 /// <summary>
103 /// Gets and Sets the Serializer. Default value is <see cref="Google .Apis.Json.NewtonsoftJsonSerializer"/>. 92 /// Gets and Sets the serializer. Default value is <see cref="Google .Apis.Json.NewtonsoftJsonSerializer"/>.
104 /// </summary> 93 /// </summary>
105 public ISerializer Serializer { get; set; } 94 public ISerializer Serializer { get; set; }
106 95
107 /// <summary> Gets or sets the API Key. Default value is <c>null</c> . </summary> 96 /// <summary>Gets or sets the API Key. Default value is <c>null</c>. </summary>
108 public string ApiKey { get; set; } 97 public string ApiKey { get; set; }
109 98
110 /// <summary> 99 /// <summary>
111 /// Gets or sets the Authenticator. Default value is· 100 /// Gets or sets the Authenticator. Default value is·
112 /// <see cref="Google.Apis.Authentication.NullAuthenticator.Instance "/>. 101 /// <see cref="Google.Apis.Authentication.NullAuthenticator.Instance "/>.
113 /// </summary> 102 /// </summary>
114 public IAuthenticator Authenticator { get; set; } 103 public IAuthenticator Authenticator { get; set; }
115 104
116 /// <summary> 105 /// <summary>
117 /// Gets or sets Application name to be used in the User-Agent heade r. Default value is <c>null</c>.· 106 /// Gets or sets Application name to be used in the User-Agent heade r. Default value is <c>null</c>.·
118 /// </summary> 107 /// </summary>
119 public string ApplicationName { get; set; } 108 public string ApplicationName { get; set; }
120 109
121 /// <summary> 110 /// <summary>
122 /// Maximum allowed length of a URL string for GET requests. Default value is <c>2048</c>. 111 /// Maximum allowed length of a URL string for GET requests. Default value is <c>2048</c>. If the value is
112 /// set to <c>0</c>, requests will never be modified due to URL stri ng length.
123 /// </summary> 113 /// </summary>
124 public uint MaxUrlLength { get; set; } 114 public uint MaxUrlLength { get; set; }
125 115
126 /// <summary> Constructs a new initializer with default values. </su mmary> 116 /// <summary>Constructs a new initializer with default values.</summ ary>
127 public Initializer() 117 public Initializer()
128 { 118 {
129 GZipEnabled = true; 119 GZipEnabled = true;
130 Serializer = new NewtonsoftJsonSerializer(); 120 Serializer = new NewtonsoftJsonSerializer();
131 Authenticator = NullAuthenticator.Instance; 121 Authenticator = NullAuthenticator.Instance;
132 DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.Unsuc cessfulResponse503; 122 DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.Unsuc cessfulResponse503;
133 MaxUrlLength = DefaultMaxUrlLength; 123 MaxUrlLength = DefaultMaxUrlLength;
134 } 124 }
135 } 125 }
136 126
137 /// <summary>
138 /// An initializer which adds exponential back-off as exception handler and\or unsuccessful response handler by
139 /// the given <seealso cref="BaseClientService.ExponentialBackOffPolicy" />.
140 /// </summary>
141 private class ExponentialBackOffInitializer : IConfigurableHttpClientIni tializer
142 {
143 private ExponentialBackOffPolicy Policy { get; set; }
144 private Func<BackOffHandler> CreateBackOff { get; set; }
145
146 /// <summary>
147 /// Constructs a new back-off initializer with the given policy and back-off handler create function.
148 /// </summary>
149 public ExponentialBackOffInitializer(ExponentialBackOffPolicy policy , Func<BackOffHandler> createBackOff)
150 {
151 Policy = policy;
152 CreateBackOff = createBackOff;
153 }
154
155 public void Initialize(ConfigurableHttpClient httpClient)
156 {
157 var backOff = CreateBackOff();
158
159 // add exception handler and\or unsuccessful response handler
160 if ((Policy & ExponentialBackOffPolicy.Exception) == Exponential BackOffPolicy.Exception)
161 {
162 httpClient.MessageHandler.ExceptionHandlers.Add(backOff);
163 }
164
165 if ((Policy & ExponentialBackOffPolicy.UnsuccessfulResponse503) ==
166 ExponentialBackOffPolicy.UnsuccessfulResponse503)
167 {
168 httpClient.MessageHandler.UnsuccessfulResponseHandlers.Add(b ackOff);
169 }
170 }
171 }
172
173 #endregion 127 #endregion
174 128
175 /// <summary> Constructs a new base client with the specified initialize r. </summary> 129 /// <summary>Constructs a new base client with the specified initializer .</summary>
176 protected BaseClientService(Initializer initializer) 130 protected BaseClientService(Initializer initializer)
177 { 131 {
178 // sets the right properties by the initializer's properties 132 // Set the right properties by the initializer's properties.
179 GZipEnabled = initializer.GZipEnabled; 133 GZipEnabled = initializer.GZipEnabled;
180 Serializer = initializer.Serializer; 134 Serializer = initializer.Serializer;
181 ApiKey = initializer.ApiKey; 135 ApiKey = initializer.ApiKey;
182 Authenticator = initializer.Authenticator; 136 Authenticator = initializer.Authenticator;
183 ApplicationName = initializer.ApplicationName; 137 ApplicationName = initializer.ApplicationName;
184 if (ApplicationName == null) 138 if (ApplicationName == null)
185 { 139 {
186 Logger.Warning("Application name is not set. Please set Initiali zer.ApplicationName property"); 140 Logger.Warning("Application name is not set. Please set Initiali zer.ApplicationName property");
187 } 141 }
188 HttpClientInitializer = initializer.HttpClientInitializer; 142 HttpClientInitializer = initializer.HttpClientInitializer;
189 143
190 // create an Http client for this service 144 // Create a HTTP client for this service.
191 HttpClient = CreateHttpClient(initializer); 145 HttpClient = CreateHttpClient(initializer);
192 } 146 }
193 147
194 /// <summary> Return <c>true</c> if this service contains the specified feature. </summary> 148 /// <summary>Returns <c>true</c> if this service contains the specified feature.</summary>
195 private bool HasFeature(Features feature) 149 private bool HasFeature(Features feature)
196 { 150 {
197 return Features.Contains(feature.GetStringValue()); 151 return Features.Contains(feature.GetStringValue());
198 } 152 }
199 153
200 private ConfigurableHttpClient CreateHttpClient(Initializer initializer) 154 private ConfigurableHttpClient CreateHttpClient(Initializer initializer)
201 { 155 {
202 // if factory wasn't set use the default Http client factory 156 // If factory wasn't set use the default HTTP client factory.
203 var factory = initializer.HttpClientFactory ?? new HttpClientFactory (); 157 var factory = initializer.HttpClientFactory ?? new HttpClientFactory ();
204 var args = new CreateHttpClientArgs 158 var args = new CreateHttpClientArgs
205 { 159 {
206 GZipEnabled = GZipEnabled, 160 GZipEnabled = GZipEnabled,
207 ApplicationName = ApplicationName, 161 ApplicationName = ApplicationName,
208 }; 162 };
209 163
210 // add the user's input initializer 164 // Add the user's input initializer.
211 if (HttpClientInitializer != null) 165 if (HttpClientInitializer != null)
212 { 166 {
213 args.Initializers.Add(HttpClientInitializer); 167 args.Initializers.Add(HttpClientInitializer);
214 } 168 }
215 169
216 // add exponential back-off initializer if necessary 170 // Add exponential back-off initializer if necessary.
217 if (initializer.DefaultExponentialBackOffPolicy != ExponentialBackOf fPolicy.None) 171 if (initializer.DefaultExponentialBackOffPolicy != ExponentialBackOf fPolicy.None)
218 { 172 {
219 args.Initializers.Add(new ExponentialBackOffInitializer(initiali zer.DefaultExponentialBackOffPolicy, 173 args.Initializers.Add(new ExponentialBackOffInitializer(initiali zer.DefaultExponentialBackOffPolicy,
220 CreateBackOffHandler)); 174 CreateBackOffHandler));
221 } 175 }
222 176
223 // add authenticator initializer to intercept a request and add the "Authorization" header and also handle 177 // Add authenticator initializer to intercept a request and add the "Authorization" header and also handle
224 // abnormal 401 responses in case the authenticator is an instance o f unsuccessful response handler. 178 // abnormal 401 responses in case the authenticator is an instance o f unsuccessful response handler.
225 args.Initializers.Add(new AuthenticatorMessageHandlerInitializer(Aut henticator)); 179 args.Initializers.Add(new AuthenticatorMessageHandlerInitializer(Aut henticator));
226 ············ 180 ············
227 var httpClient = factory.CreateHttpClient(args); 181 var httpClient = factory.CreateHttpClient(args);
228 httpClient.MessageHandler.ExecuteInterceptors.Add(new MaxUrlLengthIn terceptor(initializer.MaxUrlLength)); 182 if (initializer.MaxUrlLength > 0)
183 {
184 httpClient.MessageHandler.ExecuteInterceptors.Add(
185 new MaxUrlLengthInterceptor(initializer.MaxUrlLength));
186 }
229 return httpClient; 187 return httpClient;
230 } 188 }
231 189
232 /// <summary> 190 /// <summary>
233 /// Creates the back-off handler with <seealso cref="Google.Apis.Util.Ex ponentialBackOff"/>.· 191 /// Creates the back-off handler with <seealso cref="Google.Apis.Util.Ex ponentialBackOff"/>.·
234 /// Overrides this method to change the default behavior of back-off han dler (e.g. you can change the maximum 192 /// Overrides this method to change the default behavior of back-off han dler (e.g. you can change the maximum
235 /// waited request's time span, or create a back-off handler with you ow n implementation of· 193 /// waited request's time span, or create a back-off handler with you ow n implementation of·
236 /// <seealso cref="Google.Apis.Util.IBackOff"/>). 194 /// <seealso cref="Google.Apis.Util.IBackOff"/>).
237 /// </summary> 195 /// </summary>
238 protected virtual BackOffHandler CreateBackOffHandler() 196 protected virtual BackOffHandler CreateBackOffHandler()
239 { 197 {
240 // TODO(peleyal): consider return here interface and not the concret e class 198 // TODO(peleyal): consider return here interface and not the concret e class
241 return new BackOffHandler(new ExponentialBackOff()); 199 return new BackOffHandler(new ExponentialBackOff());
242 } 200 }
243 201
244 #region IClientService Members 202 #region IClientService Members
245 203
246 public ConfigurableHttpClient HttpClient { get; private set; } 204 public ConfigurableHttpClient HttpClient { get; private set; }
247 205
248 public IConfigurableHttpClientInitializer HttpClientInitializer { get; p rivate set; } 206 public IConfigurableHttpClientInitializer HttpClientInitializer { get; p rivate set; }
249 207
250 public bool GZipEnabled { get; private set; } 208 public bool GZipEnabled { get; private set; }
251 209
252 public string ApiKey { get; private set; } 210 public string ApiKey { get; private set; }
253 211
254 public IAuthenticator Authenticator { get; private set; } 212 public IAuthenticator Authenticator { get; private set; }
255 213
256 public string ApplicationName { get; private set; } 214 public string ApplicationName { get; private set; }
257 215
258 public int MaxUrlLength { get; private set; }
peleyal 2013/08/26 01:28:48 but you don't set it now :) So you can remove it f
ngmiceli 2013/08/29 19:17:06 ...oh right. Done :)
259
260 public void SetRequestSerailizedContent(HttpRequestMessage request, obje ct body) 216 public void SetRequestSerailizedContent(HttpRequestMessage request, obje ct body)
261 { 217 {
262 if (body == null) 218 if (body == null)
263 { 219 {
264 return; 220 return;
265 } 221 }
266 222
267 HttpContent content = null; 223 HttpContent content = null;
268 224
269 var mediaType = "application/" + Serializer.Format; 225 var mediaType = "application/" + Serializer.Format;
(...skipping 21 matching lines...) Expand all
291 public ISerializer Serializer { get; private set; } 247 public ISerializer Serializer { get; private set; }
292 248
293 public virtual string SerializeObject(object obj) 249 public virtual string SerializeObject(object obj)
294 { 250 {
295 if (HasFeature(Discovery.Features.LegacyDataResponse)) 251 if (HasFeature(Discovery.Features.LegacyDataResponse))
296 { 252 {
297 // Legacy path 253 // Legacy path
298 var request = new StandardResponse<object> { Data = obj }; 254 var request = new StandardResponse<object> { Data = obj };
299 return Serializer.Serialize(request); 255 return Serializer.Serialize(request);
300 } 256 }
301
302 // New v1.0 path
303 return Serializer.Serialize(obj); 257 return Serializer.Serialize(obj);
304 } 258 }
305 259
306 public virtual async Task<T> DeserializeResponse<T>(HttpResponseMessage response) 260 public virtual async Task<T> DeserializeResponse<T>(HttpResponseMessage response)
307 { 261 {
308 var text = await response.Content.ReadAsStringAsync().ConfigureAwait (false); 262 var text = await response.Content.ReadAsStringAsync().ConfigureAwait (false);
309 263
310 // If a string is request, don't parse the response. 264 // If a string is request, don't parse the response.
311 if (typeof(T).Equals(typeof(string))) 265 if (typeof(T).Equals(typeof(string)))
312 { 266 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 // Standard response (which contains data and error properties) 335 // Standard response (which contains data and error properties)
382 throw new GoogleApiException(Name, 336 throw new GoogleApiException(Name,
383 "An Error occurred, but the error response could not be dese rialized", ex); 337 "An Error occurred, but the error response could not be dese rialized", ex);
384 } 338 }
385 339
386 return errorResponse.Error; 340 return errorResponse.Error;
387 } 341 }
388 342
389 #endregion 343 #endregion
390 344
391 #region Abstract Memebrs 345 #region Abstract Members
392 346
393 public abstract string Name { get; } 347 public abstract string Name { get; }
394 public abstract string BaseUri { get; } 348 public abstract string BaseUri { get; }
395 public abstract string BasePath { get; } 349 public abstract string BasePath { get; }
396 350
397 public abstract IList<string> Features { get; } 351 public abstract IList<string> Features { get; }
398 352
399 #endregion 353 #endregion
400 354
401 #endregion 355 #endregion
402 356
403 /// <summary> Creates a GZip stream by the given serialized object. </su mmary> 357 /// <summary>Creates a GZip stream by the given serialized object.</summ ary>
404 private static Stream CreateGZipStream(string serializedObject) 358 private static Stream CreateGZipStream(string serializedObject)
405 { 359 {
406 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(serializedObject); 360 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(serializedObject);
407 using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 361 using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
408 { 362 {
409 using (GZipStream gzip = new GZipStream(ms, CompressionMode.Comp ress, true)) 363 using (GZipStream gzip = new GZipStream(ms, CompressionMode.Comp ress, true))
410 { 364 {
411 gzip.Write(bytes, 0, bytes.Length); 365 gzip.Write(bytes, 0, bytes.Length);
412 } 366 }
413 367
414 // reset the stream to the beginning. It doesn't work otherwise! 368 // reset the stream to the beginning. It doesn't work otherwise!
415 ms.Position = 0; 369 ms.Position = 0;
416 byte[] compressed = new byte[ms.Length]; 370 byte[] compressed = new byte[ms.Length];
417 ms.Read(compressed, 0, compressed.Length); 371 ms.Read(compressed, 0, compressed.Length);
418 return new MemoryStream(compressed); 372 return new MemoryStream(compressed);
419 } 373 }
420 } 374 }
421 375
422 public virtual void Dispose() 376 public virtual void Dispose()
423 { 377 {
424 if (HttpClient != null) 378 if (HttpClient != null)
425 { 379 {
426 HttpClient.Dispose(); 380 HttpClient.Dispose();
427 } 381 }
428 } 382 }
429 } 383 }
430
431 [VisibleForTestOnly]
432 /// <summary>
433 /// Intercepts HTTP GET requests with a URLs longer than <see cref="MaxUrlLe ngth" />.
peleyal 2013/08/26 01:28:48 <see cref="Initializer.MaxUrlLength"
ngmiceli 2013/08/29 19:17:06 Done.
434 /// The interceptor will change such requests as follows:·
435 /// <list type="bullet">
436 /// <item>The request type will be changed to POST</item>
peleyal 2013/08/26 01:28:48 I think you mean "request's method" and not "reque
ngmiceli 2013/08/29 19:17:06 Done.
437 /// <item>A <c>X-HTTP-Method-Override</c> header will be added with the valu e <c>GET</c></item>
438 /// <item>Any query parameters from the URI will be moved into the body of t he request.
439 /// <item>If query parameters are moved, the content type is set to <c>appli cation/x-www-form-urlencoded</c></item>
440 /// </item></list>
441 /// </summary>
442 internal class MaxUrlLengthInterceptor : IHttpExecuteInterceptor·
443 {
444 private readonly uint maxUrlLength;
445
446 ///<summary>Constructs a new Max URL length interceptor with the given m ax length.</summary>
447 public MaxUrlLengthInterceptor(uint maxUrlLength)
448 {
449 this.maxUrlLength = maxUrlLength;
450 }
451
452 public void Intercept(HttpRequestMessage request)
453 {
454 if (request.Method == HttpMethod.Get && request.RequestUri.AbsoluteU ri.Length > maxUrlLength) {
peleyal 2013/08/26 01:28:48 [optional] I think that you are the one that actua
ngmiceli 2013/08/29 19:17:06 Hey, you're right! I do prefer that :) Done.
455 // Change the method to POST
456 request.Method = HttpMethod.Post;
457 var query = request.RequestUri.Query;
458 if (! String.IsNullOrEmpty(query))
peleyal 2013/08/26 01:28:48 if (! String.IsNullOrEmpty(query)) => if (!String.
ngmiceli 2013/08/29 19:17:06 Done.
459 {
460 // Move query parameters to the body (without the "?")
461 request.Content = new StringContent(query.Substring(1));
462 request.Content.Headers.ContentType = new MediaTypeHeaderVal ue("application/x-www-form-urlencoded");
463 var requestString = request.RequestUri.ToString();
464 request.RequestUri = new Uri(requestString.Remove(requestStr ing.IndexOf("?") - 1));
465 }
466 request.Headers.Add("X-HTTP-Method-Override", "GET");
467 }
468 }
469 }
470 } 384 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b