5 // Marek Safar <marek.safar@gmail.com>
7 // Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
31 using System.Collections.Generic;
32 using NUnit.Framework;
33 using System.Net.Http;
34 using System.Net.Http.Headers;
35 using System.Threading;
36 using System.Threading.Tasks;
41 namespace MonoTests.System.Net.Http
44 public class HttpClientTest
46 class HttpMessageHandlerMock : HttpMessageHandler
48 public Func<HttpRequestMessage, Task<HttpResponseMessage>> OnSend;
49 public Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> OnSendFull;
51 public HttpMessageHandlerMock ()
55 protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
58 return OnSend (request);
60 if (OnSendFull != null)
61 return OnSendFull (request, cancellationToken);
68 class HttpClientHandlerMock : HttpClientHandler
70 public Func<HttpRequestMessage, Task<HttpResponseMessage>> OnSend;
71 public Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> OnSendFull;
73 protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
76 return OnSend (request);
78 if (OnSendFull != null)
79 return OnSendFull (request, cancellationToken);
86 class CustomStream : Stream
88 public override void Flush ()
90 throw new NotImplementedException ();
95 public override int Read (byte[] buffer, int offset, int count)
104 public override long Seek (long offset, SeekOrigin origin)
106 throw new NotImplementedException ();
109 public override void SetLength (long value)
111 throw new NotImplementedException ();
114 public override void Write (byte[] buffer, int offset, int count)
116 throw new NotImplementedException ();
119 public override bool CanRead {
125 public override bool CanSeek {
131 public override bool CanWrite {
133 throw new NotImplementedException ();
137 public override long Length {
139 throw new NotImplementedException ();
143 public override long Position {
145 throw new NotImplementedException ();
148 throw new NotImplementedException ();
153 const int WaitTimeout = 5000;
155 string TestHost, LocalServer;
159 public void SetupFixture ()
161 if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
167 TestHost = "localhost:" + port;
168 LocalServer = string.Format ("http://{0}/", TestHost);
172 public void Ctor_Default ()
174 var client = new HttpClient ();
175 Assert.IsNull (client.BaseAddress, "#1");
176 Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
177 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
178 Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
182 public void CancelPendingRequests ()
184 var mh = new HttpMessageHandlerMock ();
186 var client = new HttpClient (mh);
187 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
188 var mre = new ManualResetEvent (false);
190 mh.OnSendFull = (l, c) => {
192 Assert.IsTrue (c.WaitHandle.WaitOne (1000), "#20");
193 Assert.IsTrue (c.IsCancellationRequested, "#21");
195 return Task.FromResult (new HttpResponseMessage ());
198 var t = Task.Factory.StartNew (() => {
199 client.SendAsync (request).Wait (WaitTimeout);
202 Assert.IsTrue (mre.WaitOne (500), "#1");
204 client.CancelPendingRequests ();
205 Assert.IsTrue (t.Wait (500), "#2");
207 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
208 mh.OnSendFull = (l, c) => {
209 Assert.IsFalse (c.IsCancellationRequested, "#30");
210 return Task.FromResult (new HttpResponseMessage ());
213 client.SendAsync (request).Wait (WaitTimeout);
217 public void CancelPendingRequests_BeforeSend ()
219 var ct = new CancellationTokenSource ();
221 var rr = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken (), ct.Token);
224 var mh = new HttpMessageHandlerMock ();
226 var client = new HttpClient (mh);
227 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
228 client.CancelPendingRequests ();
230 mh.OnSendFull = (l, c) => {
231 Assert.IsFalse (c.IsCancellationRequested, "#30");
232 return Task.FromResult (new HttpResponseMessage ());
235 client.SendAsync (request).Wait (WaitTimeout);
237 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
238 client.SendAsync (request).Wait (WaitTimeout);
243 public void CancelRequestViaProxy ()
245 var handler = new HttpClientHandler {
246 Proxy = new WebProxy ("192.168.10.25:8888/"), // proxy that doesn't exist
248 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
251 var httpClient = new HttpClient (handler) {
252 BaseAddress = new Uri ("https://google.com"),
253 Timeout = TimeSpan.FromMilliseconds (1)
257 var restRequest = new HttpRequestMessage {
258 Method = HttpMethod.Post,
259 RequestUri = new Uri("foo", UriKind.Relative),
260 Content = new StringContent("", null, "application/json")
263 httpClient.PostAsync (restRequest.RequestUri, restRequest.Content).Wait (WaitTimeout);
265 } catch (AggregateException e) {
266 Assert.IsTrue (e.InnerException is TaskCanceledException, "#2");
271 public void Properties ()
273 var client = new HttpClient ();
274 client.BaseAddress = null;
275 client.MaxResponseContentBufferSize = int.MaxValue;
276 client.Timeout = Timeout.InfiniteTimeSpan;
278 Assert.IsNull (client.BaseAddress, "#1");
279 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#2");
280 Assert.AreEqual (Timeout.InfiniteTimeSpan, client.Timeout, "#3");
284 public void Properties_Invalid ()
286 var client = new HttpClient ();
288 client.MaxResponseContentBufferSize = 0;
290 } catch (ArgumentOutOfRangeException) {
294 client.Timeout = TimeSpan.MinValue;
296 } catch (ArgumentOutOfRangeException) {
303 var mh = new HttpMessageHandlerMock ();
305 var client = new HttpClient (mh);
306 client.BaseAddress = new Uri ("http://xamarin.com");
307 var request = new HttpRequestMessage ();
308 var response = new HttpResponseMessage ();
311 Assert.AreEqual (l, request, "#2");
312 Assert.AreEqual (client.BaseAddress, l.RequestUri, "#2");
313 return Task.FromResult (response);
316 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
320 public void Send_BaseAddress ()
322 var mh = new HttpMessageHandlerMock ();
324 var client = new HttpClient (mh);
325 client.BaseAddress = new Uri ("http://localhost/");
326 var response = new HttpResponseMessage ();
329 Assert.AreEqual ("http://localhost/relative", l.RequestUri.ToString (), "#2");
330 return Task.FromResult (response);
333 Assert.AreEqual (response, client.GetAsync ("relative").Result, "#1");
334 Assert.AreEqual (response, client.GetAsync ("/relative").Result, "#2");
338 public void Send_DefaultRequestHeaders ()
340 var mh = new HttpMessageHandlerMock ();
342 var client = new HttpClient (mh);
343 client.DefaultRequestHeaders.Referrer = new Uri ("http://google.com");
345 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
346 var response = new HttpResponseMessage ();
349 Assert.AreEqual (client.DefaultRequestHeaders.Referrer, l.Headers.Referrer, "#2");
350 Assert.IsNotNull (l.Headers.Referrer, "#3");
351 return Task.FromResult (response);
354 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
358 public void Send_Complete_Default ()
361 var listener = CreateListener (l => {
363 var request = l.Request;
365 Assert.IsNull (request.AcceptTypes, "#1");
366 Assert.AreEqual (0, request.ContentLength64, "#2");
367 Assert.IsNull (request.ContentType, "#3");
368 Assert.AreEqual (0, request.Cookies.Count, "#4");
369 Assert.IsFalse (request.HasEntityBody, "#5");
370 Assert.AreEqual (TestHost, request.Headers["Host"], "#6b");
371 Assert.AreEqual ("GET", request.HttpMethod, "#7");
372 Assert.IsFalse (request.IsAuthenticated, "#8");
373 Assert.IsTrue (request.IsLocal, "#9");
374 Assert.IsFalse (request.IsSecureConnection, "#10");
375 Assert.IsFalse (request.IsWebSocketRequest, "#11");
376 Assert.IsTrue (request.KeepAlive, "#12");
377 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
378 Assert.IsNull (request.ServiceName, "#14");
379 Assert.IsNull (request.UrlReferrer, "#15");
380 Assert.IsNull (request.UserAgent, "#16");
381 Assert.IsNull (request.UserLanguages, "#17");
389 var client = new HttpClient ();
390 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
391 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
393 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
394 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
395 Assert.AreEqual (false, failed, "#102");
402 public void Send_Complete_Version_1_0 ()
406 var listener = CreateListener (l => {
408 var request = l.Request;
410 Assert.IsNull (request.AcceptTypes, "#1");
411 Assert.AreEqual (0, request.ContentLength64, "#2");
412 Assert.IsNull (request.ContentType, "#3");
413 Assert.AreEqual (0, request.Cookies.Count, "#4");
414 Assert.IsFalse (request.HasEntityBody, "#5");
415 Assert.AreEqual (1, request.Headers.Count, "#6");
416 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
417 Assert.AreEqual ("GET", request.HttpMethod, "#7");
418 Assert.IsFalse (request.IsAuthenticated, "#8");
419 Assert.IsTrue (request.IsLocal, "#9");
420 Assert.IsFalse (request.IsSecureConnection, "#10");
421 Assert.IsFalse (request.IsWebSocketRequest, "#11");
422 Assert.IsFalse (request.KeepAlive, "#12");
423 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
424 Assert.IsNull (request.ServiceName, "#14");
425 Assert.IsNull (request.UrlReferrer, "#15");
426 Assert.IsNull (request.UserAgent, "#16");
427 Assert.IsNull (request.UserLanguages, "#17");
435 var client = new HttpClient ();
436 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
437 request.Version = HttpVersion.Version10;
438 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
440 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
441 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
442 Assert.AreEqual (false, failed, "#102");
449 public void Send_Complete_ClientHandlerSettings ()
453 var listener = CreateListener (l => {
454 var request = l.Request;
457 Assert.IsNull (request.AcceptTypes, "#1");
458 Assert.AreEqual (0, request.ContentLength64, "#2");
459 Assert.IsNull (request.ContentType, "#3");
460 Assert.AreEqual (1, request.Cookies.Count, "#4");
461 Assert.AreEqual (new Cookie ("mycookie", "vv"), request.Cookies[0], "#4a");
462 Assert.IsFalse (request.HasEntityBody, "#5");
463 Assert.AreEqual (4, request.Headers.Count, "#6");
464 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
465 Assert.AreEqual ("gzip", request.Headers["Accept-Encoding"], "#6b");
466 Assert.AreEqual ("mycookie=vv", request.Headers["Cookie"], "#6c");
467 Assert.AreEqual ("GET", request.HttpMethod, "#7");
468 Assert.IsFalse (request.IsAuthenticated, "#8");
469 Assert.IsTrue (request.IsLocal, "#9");
470 Assert.IsFalse (request.IsSecureConnection, "#10");
471 Assert.IsFalse (request.IsWebSocketRequest, "#11");
472 Assert.IsTrue (request.KeepAlive, "#12");
473 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
474 Assert.IsNull (request.ServiceName, "#14");
475 Assert.IsNull (request.UrlReferrer, "#15");
476 Assert.IsNull (request.UserAgent, "#16");
477 Assert.IsNull (request.UserLanguages, "#17");
485 var chandler = new HttpClientHandler ();
486 chandler.AllowAutoRedirect = true;
487 chandler.AutomaticDecompression = DecompressionMethods.GZip;
488 chandler.MaxAutomaticRedirections = 33;
489 chandler.MaxRequestContentBufferSize = 5555;
490 chandler.PreAuthenticate = true;
491 chandler.CookieContainer.Add (new Uri (LocalServer), new Cookie ( "mycookie", "vv"));
492 chandler.UseCookies = true;
493 chandler.UseDefaultCredentials = true;
494 chandler.Proxy = new WebProxy ("ee");
495 chandler.UseProxy = true;
497 var client = new HttpClient (chandler);
498 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
499 request.Version = HttpVersion.Version10;
500 request.Headers.Add ("Keep-Alive", "false");
501 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
503 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
504 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
505 Assert.AreEqual (false, failed, "#102");
513 public void Send_Complete_CustomHeaders ()
517 var listener = CreateListener (l => {
518 var request = l.Request;
520 Assert.AreEqual ("vv", request.Headers["aa"], "#1");
522 var response = l.Response;
523 response.Headers.Add ("rsp", "rrr");
524 response.Headers.Add ("upgrade", "vvvvaa");
525 response.Headers.Add ("Date", "aa");
526 response.Headers.Add ("cache-control", "audio");
528 response.StatusDescription = "test description";
529 response.ProtocolVersion = HttpVersion.Version10;
530 response.SendChunked = true;
531 response.RedirectLocation = "w3.org";
540 var client = new HttpClient ();
541 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
542 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
543 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
545 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
546 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
548 IEnumerable<string> values;
549 Assert.IsTrue (response.Headers.TryGetValues ("rsp", out values), "#102");
550 Assert.AreEqual ("rrr", values.First (), "#102a");
552 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#103");
553 Assert.AreEqual ("chunked", values.First (), "#103a");
554 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#103b");
556 Assert.IsTrue (response.Headers.TryGetValues ("Date", out values), "#104");
557 Assert.AreEqual (1, values.Count (), "#104b");
558 // .NET overwrites Date, Mono does not
559 // Assert.IsNotNull (response.Headers.Date, "#104c");
561 Assert.AreEqual (new ProductHeaderValue ("vvvvaa"), response.Headers.Upgrade.First (), "#105");
563 Assert.AreEqual ("audio", response.Headers.CacheControl.Extensions.First ().Name, "#106");
565 Assert.AreEqual ("w3.org", response.Headers.Location.OriginalString, "#107");
567 Assert.AreEqual ("test description", response.ReasonPhrase, "#110");
568 Assert.AreEqual (HttpVersion.Version11, response.Version, "#111");
570 Assert.AreEqual (false, failed, "#112");
577 public void Send_Complete_CustomHeaders_SpecialSeparators ()
581 var listener = CreateListener (l => {
582 var request = l.Request;
585 Assert.AreEqual ("MLK Android Phone 1.1.9", request.UserAgent, "#1");
593 var client = new HttpClient ();
595 client.DefaultRequestHeaders.Add("User-Agent", "MLK Android Phone 1.1.9");
597 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
599 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
601 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
602 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
603 Assert.AreEqual (false, failed, "#102");
611 public void Send_Complete_CustomHeaders_Host ()
614 var listener = CreateListener (l => {
615 var request = l.Request;
618 Assert.AreEqual ("customhost", request.Headers["Host"], "#1");
626 var client = new HttpClient ();
628 client.DefaultRequestHeaders.Add("Host", "customhost");
630 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
632 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
634 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
635 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
636 Assert.AreEqual (false, failed, "#102");
644 public void Send_Transfer_Encoding_Chunked ()
648 var listener = CreateListener (l => {
649 var request = l.Request;
652 Assert.AreEqual (1, request.Headers.Count, "#1");
660 var client = new HttpClient ();
661 client.DefaultRequestHeaders.TransferEncodingChunked = true;
663 client.GetAsync (LocalServer).Wait ();
665 Assert.AreEqual (false, failed, "#102");
673 public void Send_Transfer_Encoding_Custom ()
677 var listener = CreateListener (l => {
682 var client = new HttpClient ();
683 client.DefaultRequestHeaders.TransferEncoding.Add (new TransferCodingHeaderValue ("chunked2"));
685 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
688 client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Wait ();
690 } catch (AggregateException e) {
691 Assert.AreEqual (typeof (ProtocolViolationException), e.InnerException.GetType (), "#2");
693 Assert.IsNull (failed, "#102");
701 public void Send_Complete_Content ()
703 var listener = CreateListener (l => {
704 var request = l.Request;
705 l.Response.OutputStream.WriteByte (55);
706 l.Response.OutputStream.WriteByte (75);
710 var client = new HttpClient ();
711 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
712 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
713 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
715 Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
716 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
718 IEnumerable<string> values;
719 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
720 Assert.AreEqual ("chunked", values.First (), "#102a");
721 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
728 public void Send_Complete_Content_MaxResponseContentBufferSize ()
730 var listener = CreateListener (l => {
731 var request = l.Request;
732 var b = new byte[4000];
733 l.Response.OutputStream.Write (b, 0, b.Length);
737 var client = new HttpClient ();
738 client.MaxResponseContentBufferSize = 1000;
739 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
740 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
742 Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
743 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
750 public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
752 var listener = CreateListener (l => {
753 var request = l.Request;
754 var b = new byte[4000];
755 l.Response.OutputStream.Write (b, 0, b.Length);
759 var client = new HttpClient ();
760 client.MaxResponseContentBufferSize = 1000;
761 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
764 client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait (WaitTimeout);
766 } catch (AggregateException e) {
767 Assert.IsTrue (e.InnerException is HttpRequestException, "#3");
776 public void Send_Complete_NoContent ()
778 foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
780 var listener = CreateListener (l => {
782 var request = l.Request;
784 Assert.AreEqual (2, request.Headers.Count, "#1");
785 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b");
786 Assert.AreEqual (method.Method, request.HttpMethod, "#2");
794 var client = new HttpClient ();
795 var request = new HttpRequestMessage (method, LocalServer);
796 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
798 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
799 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
800 Assert.AreEqual (false, failed, "#102");
808 public void Send_Complete_Error ()
810 var listener = CreateListener (l => {
811 var response = l.Response;
812 response.StatusCode = 500;
816 var client = new HttpClient ();
817 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
818 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
820 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
821 Assert.AreEqual (HttpStatusCode.InternalServerError, response.StatusCode, "#101");
828 public void Send_Content_Get ()
830 var listener = CreateListener (l => {
831 var request = l.Request;
832 l.Response.OutputStream.WriteByte (72);
836 var client = new HttpClient ();
837 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
838 var response = client.SendAsync (r).Result;
840 Assert.AreEqual ("H", response.Content.ReadAsStringAsync ().Result);
847 public void Send_Content_BomEncoding ()
849 var listener = CreateListener (l => {
850 var request = l.Request;
852 var str = l.Response.OutputStream;
853 str.WriteByte (0xEF);
854 str.WriteByte (0xBB);
855 str.WriteByte (0xBF);
860 var client = new HttpClient ();
861 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
862 var response = client.SendAsync (r).Result;
864 Assert.AreEqual ("G", response.Content.ReadAsStringAsync ().Result);
871 public void Send_Content_Put ()
874 var listener = CreateListener (l => {
875 var request = l.Request;
876 passed = 7 == request.ContentLength64;
877 passed &= request.ContentType == "text/plain; charset=utf-8";
878 passed &= request.InputStream.ReadByte () == 'm';
882 var client = new HttpClient ();
883 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
884 r.Content = new StringContent ("my text");
885 var response = client.SendAsync (r).Result;
887 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
888 Assert.IsTrue (passed, "#2");
896 public void Send_Content_Put_CustomStream ()
899 var listener = CreateListener (l => {
900 var request = l.Request;
901 passed = 44 == request.ContentLength64;
902 passed &= request.ContentType == null;
906 var client = new HttpClient ();
907 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
908 r.Content = new StreamContent (new CustomStream ());
909 var response = client.SendAsync (r).Result;
911 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
912 Assert.IsTrue (passed, "#2");
921 public void Send_Timeout ()
923 var mh = new HttpMessageHandlerMock ();
925 var client = new HttpClient (mh);
926 client.Timeout = TimeSpan.FromMilliseconds (100);
927 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
928 var response = new HttpResponseMessage ();
930 mh.OnSendFull = (l, c) => {
931 Assert.IsTrue (c.WaitHandle.WaitOne (500), "#2");
932 return Task.FromResult (response);
935 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
939 public void Send_Invalid ()
941 var client = new HttpClient ();
943 client.SendAsync (null).Wait (WaitTimeout);
945 } catch (ArgumentNullException) {
949 var request = new HttpRequestMessage ();
950 client.SendAsync (request).Wait (WaitTimeout);
952 } catch (InvalidOperationException) {
957 public void Send_InvalidHandler ()
959 var mh = new HttpMessageHandlerMock ();
961 var client = new HttpClient (mh);
962 client.BaseAddress = new Uri ("http://xamarin.com");
963 var request = new HttpRequestMessage ();
966 Assert.AreEqual (l, request, "#1");
972 client.SendAsync (request).Wait (WaitTimeout);
974 } catch (Exception) {
979 public void Send_SameMessage ()
981 var mh = new HttpMessageHandlerMock ();
983 var client = new HttpClient (mh);
984 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
986 mh.OnSend = l => Task.FromResult (new HttpResponseMessage ());
988 client.SendAsync (request).Wait (WaitTimeout);
990 client.SendAsync (request).Wait (WaitTimeout);
992 } catch (InvalidOperationException) {
997 [Category ("MobileNotWorking")] // Missing encoding
998 public void GetString_Many ()
1000 Action<HttpListenerContext> context = (HttpListenerContext l) => {
1001 var response = l.Response;
1002 response.StatusCode = 200;
1003 response.OutputStream.WriteByte (0x68);
1004 response.OutputStream.WriteByte (0x65);
1005 response.OutputStream.WriteByte (0x6c);
1006 response.OutputStream.WriteByte (0x6c);
1007 response.OutputStream.WriteByte (0x6f);
1010 var listener = CreateListener (context); // creates a default request handler
1011 AddListenerContext (listener, context); // add another request handler for the second request
1014 var client = new HttpClient ();
1015 var t1 = client.GetStringAsync (LocalServer);
1016 var t2 = client.GetStringAsync (LocalServer);
1017 Assert.IsTrue (Task.WaitAll (new [] { t1, t2 }, WaitTimeout));
1018 Assert.AreEqual ("hello", t1.Result, "#1");
1019 Assert.AreEqual ("hello", t2.Result, "#2");
1027 public void GetByteArray_ServerError ()
1029 var listener = CreateListener (l => {
1030 var response = l.Response;
1031 response.StatusCode = 500;
1032 l.Response.OutputStream.WriteByte (72);
1036 var client = new HttpClient ();
1038 client.GetByteArrayAsync (LocalServer).Wait (WaitTimeout);
1040 } catch (AggregateException e) {
1041 Assert.IsTrue (e.InnerException is HttpRequestException , "#2");
1049 public void DisallowAutoRedirect ()
1051 var listener = CreateListener (l => {
1052 var request = l.Request;
1053 var response = l.Response;
1055 response.StatusCode = (int)HttpStatusCode.Moved;
1056 response.RedirectLocation = "http://xamarin.com/";
1060 var chandler = new HttpClientHandler ();
1061 chandler.AllowAutoRedirect = false;
1062 var client = new HttpClient (chandler);
1065 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1067 } catch (AggregateException e) {
1068 Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
1077 public void RequestUriAfterRedirect ()
1079 var listener = CreateListener (l => {
1080 var request = l.Request;
1081 var response = l.Response;
1083 response.StatusCode = (int)HttpStatusCode.Moved;
1084 response.RedirectLocation = "http://localhost:8811/";
1087 var listener2 = CreateListener (l => {
1088 var response = l.Response;
1090 response.StatusCode = (int)HttpStatusCode.OK;
1091 response.OutputStream.WriteByte (0x68);
1092 response.OutputStream.WriteByte (0x65);
1093 response.OutputStream.WriteByte (0x6c);
1094 response.OutputStream.WriteByte (0x6c);
1095 response.OutputStream.WriteByte (0x6f);
1099 var chandler = new HttpClientHandler ();
1100 chandler.AllowAutoRedirect = true;
1101 var client = new HttpClient (chandler);
1103 var r = client.GetAsync (LocalServer);
1104 Assert.IsTrue (r.Wait (WaitTimeout), "#1");
1105 var resp = r.Result;
1106 Assert.AreEqual ("http://localhost:8811/", resp.RequestMessage.RequestUri.AbsoluteUri, "#2");
1107 Assert.AreEqual ("hello", resp.Content.ReadAsStringAsync ().Result, "#3");
1118 * Properties may only be modified before sending the first request.
1120 public void ModifyHandlerAfterFirstRequest ()
1122 var chandler = new HttpClientHandler ();
1123 chandler.AllowAutoRedirect = true;
1124 var client = new HttpClient (chandler, true);
1126 var listener = CreateListener (l => {
1127 var response = l.Response;
1128 response.StatusCode = 200;
1129 response.OutputStream.WriteByte (55);
1133 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1135 chandler.AllowAutoRedirect = false;
1137 } catch (InvalidOperationException) {
1148 * However, this policy is not enforced for custom handlers and there
1149 * is also no way a derived class could tell its HttpClientHandler parent
1150 * that it just sent a request.
1153 public void ModifyHandlerAfterFirstRequest_Mock ()
1155 var ch = new HttpClientHandlerMock ();
1156 ch.AllowAutoRedirect = true;
1158 var client = new HttpClient (ch);
1160 ch.OnSend = (l) => {
1161 return Task.FromResult (new HttpResponseMessage ());
1164 client.GetAsync ("http://xamarin.com").Wait (WaitTimeout);
1165 ch.AllowAutoRedirect = false;
1168 HttpListener CreateListener (Action<HttpListenerContext> contextAssert)
1170 return CreateListener (contextAssert, port);
1173 HttpListener CreateListener (Action<HttpListenerContext> contextAssert, int port)
1175 var l = new HttpListener ();
1176 l.Prefixes.Add (string.Format ("http://+:{0}/", port));
1178 AddListenerContext(l, contextAssert);
1183 HttpListener AddListenerContext (HttpListener l, Action<HttpListenerContext> contextAssert)
1185 l.BeginGetContext (ar => {
1186 var ctx = l.EndGetContext (ar);
1189 if (contextAssert != null)
1190 contextAssert (ctx);
1192 ctx.Response.Close ();