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 port, TestHost, LocalServer;
158 public void SetupFixture ()
160 if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
166 TestHost = "localhost:" + port;
167 LocalServer = string.Format ("http://{0}/", TestHost);
171 public void Ctor_Default ()
173 var client = new HttpClient ();
174 Assert.IsNull (client.BaseAddress, "#1");
175 Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
176 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
177 Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
181 public void CancelPendingRequests ()
183 var mh = new HttpMessageHandlerMock ();
185 var client = new HttpClient (mh);
186 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
187 var mre = new ManualResetEvent (false);
189 mh.OnSendFull = (l, c) => {
191 Assert.IsTrue (c.WaitHandle.WaitOne (1000), "#20");
192 Assert.IsTrue (c.IsCancellationRequested, "#21");
194 return Task.FromResult (new HttpResponseMessage ());
197 var t = Task.Factory.StartNew (() => {
198 client.SendAsync (request).Wait (WaitTimeout);
201 Assert.IsTrue (mre.WaitOne (500), "#1");
203 client.CancelPendingRequests ();
204 Assert.IsTrue (t.Wait (500), "#2");
206 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
207 mh.OnSendFull = (l, c) => {
208 Assert.IsFalse (c.IsCancellationRequested, "#30");
209 return Task.FromResult (new HttpResponseMessage ());
212 client.SendAsync (request).Wait (WaitTimeout);
216 public void CancelPendingRequests_BeforeSend ()
218 var ct = new CancellationTokenSource ();
220 var rr = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken (), ct.Token);
223 var mh = new HttpMessageHandlerMock ();
225 var client = new HttpClient (mh);
226 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
227 client.CancelPendingRequests ();
229 mh.OnSendFull = (l, c) => {
230 Assert.IsFalse (c.IsCancellationRequested, "#30");
231 return Task.FromResult (new HttpResponseMessage ());
234 client.SendAsync (request).Wait (WaitTimeout);
236 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
237 client.SendAsync (request).Wait (WaitTimeout);
242 public void CancelRequestViaProxy ()
244 var handler = new HttpClientHandler {
245 Proxy = new WebProxy ("192.168.10.25:8888/"), // proxy that doesn't exist
247 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
250 var httpClient = new HttpClient (handler) {
251 BaseAddress = new Uri ("https://google.com"),
252 Timeout = TimeSpan.FromMilliseconds (1)
256 var restRequest = new HttpRequestMessage {
257 Method = HttpMethod.Post,
258 RequestUri = new Uri("foo", UriKind.Relative),
259 Content = new StringContent("", null, "application/json")
262 httpClient.PostAsync (restRequest.RequestUri, restRequest.Content).Wait (WaitTimeout);
264 } catch (AggregateException e) {
265 Assert.IsTrue (e.InnerException is TaskCanceledException, "#2");
270 public void Properties ()
272 var client = new HttpClient ();
273 client.BaseAddress = null;
274 client.MaxResponseContentBufferSize = int.MaxValue;
275 client.Timeout = Timeout.InfiniteTimeSpan;
277 Assert.IsNull (client.BaseAddress, "#1");
278 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#2");
279 Assert.AreEqual (Timeout.InfiniteTimeSpan, client.Timeout, "#3");
283 public void Properties_Invalid ()
285 var client = new HttpClient ();
287 client.MaxResponseContentBufferSize = 0;
289 } catch (ArgumentOutOfRangeException) {
293 client.Timeout = TimeSpan.MinValue;
295 } catch (ArgumentOutOfRangeException) {
302 var mh = new HttpMessageHandlerMock ();
304 var client = new HttpClient (mh);
305 client.BaseAddress = new Uri ("http://xamarin.com");
306 var request = new HttpRequestMessage ();
307 var response = new HttpResponseMessage ();
310 Assert.AreEqual (l, request, "#2");
311 Assert.AreEqual (client.BaseAddress, l.RequestUri, "#2");
312 return Task.FromResult (response);
315 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
319 public void Send_BaseAddress ()
321 var mh = new HttpMessageHandlerMock ();
323 var client = new HttpClient (mh);
324 client.BaseAddress = new Uri ("http://localhost/");
325 var response = new HttpResponseMessage ();
328 Assert.AreEqual ("http://localhost/relative", l.RequestUri.ToString (), "#2");
329 return Task.FromResult (response);
332 Assert.AreEqual (response, client.GetAsync ("relative").Result, "#1");
333 Assert.AreEqual (response, client.GetAsync ("/relative").Result, "#2");
337 public void Send_DefaultRequestHeaders ()
339 var mh = new HttpMessageHandlerMock ();
341 var client = new HttpClient (mh);
342 client.DefaultRequestHeaders.Referrer = new Uri ("http://google.com");
344 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
345 var response = new HttpResponseMessage ();
348 Assert.AreEqual (client.DefaultRequestHeaders.Referrer, l.Headers.Referrer, "#2");
349 Assert.IsNotNull (l.Headers.Referrer, "#3");
350 return Task.FromResult (response);
353 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
357 public void Send_Complete_Default ()
360 var listener = CreateListener (l => {
362 var request = l.Request;
364 Assert.IsNull (request.AcceptTypes, "#1");
365 Assert.AreEqual (0, request.ContentLength64, "#2");
366 Assert.IsNull (request.ContentType, "#3");
367 Assert.AreEqual (0, request.Cookies.Count, "#4");
368 Assert.IsFalse (request.HasEntityBody, "#5");
369 Assert.AreEqual (TestHost, request.Headers["Host"], "#6b");
370 Assert.AreEqual ("GET", request.HttpMethod, "#7");
371 Assert.IsFalse (request.IsAuthenticated, "#8");
372 Assert.IsTrue (request.IsLocal, "#9");
373 Assert.IsFalse (request.IsSecureConnection, "#10");
374 Assert.IsFalse (request.IsWebSocketRequest, "#11");
375 Assert.IsTrue (request.KeepAlive, "#12");
376 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
377 Assert.IsNull (request.ServiceName, "#14");
378 Assert.IsNull (request.UrlReferrer, "#15");
379 Assert.IsNull (request.UserAgent, "#16");
380 Assert.IsNull (request.UserLanguages, "#17");
388 var client = new HttpClient ();
389 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
390 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
392 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
393 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
394 Assert.AreEqual (false, failed, "#102");
401 public void Send_Complete_Version_1_0 ()
405 var listener = CreateListener (l => {
407 var request = l.Request;
409 Assert.IsNull (request.AcceptTypes, "#1");
410 Assert.AreEqual (0, request.ContentLength64, "#2");
411 Assert.IsNull (request.ContentType, "#3");
412 Assert.AreEqual (0, request.Cookies.Count, "#4");
413 Assert.IsFalse (request.HasEntityBody, "#5");
414 Assert.AreEqual (1, request.Headers.Count, "#6");
415 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
416 Assert.AreEqual ("GET", request.HttpMethod, "#7");
417 Assert.IsFalse (request.IsAuthenticated, "#8");
418 Assert.IsTrue (request.IsLocal, "#9");
419 Assert.IsFalse (request.IsSecureConnection, "#10");
420 Assert.IsFalse (request.IsWebSocketRequest, "#11");
421 Assert.IsFalse (request.KeepAlive, "#12");
422 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
423 Assert.IsNull (request.ServiceName, "#14");
424 Assert.IsNull (request.UrlReferrer, "#15");
425 Assert.IsNull (request.UserAgent, "#16");
426 Assert.IsNull (request.UserLanguages, "#17");
434 var client = new HttpClient ();
435 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
436 request.Version = HttpVersion.Version10;
437 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
439 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
440 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
441 Assert.AreEqual (false, failed, "#102");
448 public void Send_Complete_ClientHandlerSettings ()
452 var listener = CreateListener (l => {
453 var request = l.Request;
456 Assert.IsNull (request.AcceptTypes, "#1");
457 Assert.AreEqual (0, request.ContentLength64, "#2");
458 Assert.IsNull (request.ContentType, "#3");
459 Assert.AreEqual (1, request.Cookies.Count, "#4");
460 Assert.AreEqual (new Cookie ("mycookie", "vv"), request.Cookies[0], "#4a");
461 Assert.IsFalse (request.HasEntityBody, "#5");
462 Assert.AreEqual (4, request.Headers.Count, "#6");
463 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
464 Assert.AreEqual ("gzip", request.Headers["Accept-Encoding"], "#6b");
465 Assert.AreEqual ("mycookie=vv", request.Headers["Cookie"], "#6c");
466 Assert.AreEqual ("GET", request.HttpMethod, "#7");
467 Assert.IsFalse (request.IsAuthenticated, "#8");
468 Assert.IsTrue (request.IsLocal, "#9");
469 Assert.IsFalse (request.IsSecureConnection, "#10");
470 Assert.IsFalse (request.IsWebSocketRequest, "#11");
471 Assert.IsTrue (request.KeepAlive, "#12");
472 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
473 Assert.IsNull (request.ServiceName, "#14");
474 Assert.IsNull (request.UrlReferrer, "#15");
475 Assert.IsNull (request.UserAgent, "#16");
476 Assert.IsNull (request.UserLanguages, "#17");
484 var chandler = new HttpClientHandler ();
485 chandler.AllowAutoRedirect = true;
486 chandler.AutomaticDecompression = DecompressionMethods.GZip;
487 chandler.MaxAutomaticRedirections = 33;
488 chandler.MaxRequestContentBufferSize = 5555;
489 chandler.PreAuthenticate = true;
490 chandler.CookieContainer.Add (new Uri (LocalServer), new Cookie ( "mycookie", "vv"));
491 chandler.UseCookies = true;
492 chandler.UseDefaultCredentials = true;
493 chandler.Proxy = new WebProxy ("ee");
494 chandler.UseProxy = true;
496 var client = new HttpClient (chandler);
497 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
498 request.Version = HttpVersion.Version10;
499 request.Headers.Add ("Keep-Alive", "false");
500 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
502 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
503 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
504 Assert.AreEqual (false, failed, "#102");
512 public void Send_Complete_CustomHeaders ()
516 var listener = CreateListener (l => {
517 var request = l.Request;
519 Assert.AreEqual ("vv", request.Headers["aa"], "#1");
521 var response = l.Response;
522 response.Headers.Add ("rsp", "rrr");
523 response.Headers.Add ("upgrade", "vvvvaa");
524 response.Headers.Add ("Date", "aa");
525 response.Headers.Add ("cache-control", "audio");
527 response.StatusDescription = "test description";
528 response.ProtocolVersion = HttpVersion.Version10;
529 response.SendChunked = true;
530 response.RedirectLocation = "w3.org";
539 var client = new HttpClient ();
540 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
541 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
542 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
544 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
545 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
547 IEnumerable<string> values;
548 Assert.IsTrue (response.Headers.TryGetValues ("rsp", out values), "#102");
549 Assert.AreEqual ("rrr", values.First (), "#102a");
551 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#103");
552 Assert.AreEqual ("chunked", values.First (), "#103a");
553 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#103b");
555 Assert.IsTrue (response.Headers.TryGetValues ("Date", out values), "#104");
556 Assert.AreEqual (1, values.Count (), "#104b");
557 // .NET overwrites Date, Mono does not
558 // Assert.IsNotNull (response.Headers.Date, "#104c");
560 Assert.AreEqual (new ProductHeaderValue ("vvvvaa"), response.Headers.Upgrade.First (), "#105");
562 Assert.AreEqual ("audio", response.Headers.CacheControl.Extensions.First ().Name, "#106");
564 Assert.AreEqual ("w3.org", response.Headers.Location.OriginalString, "#107");
566 Assert.AreEqual ("test description", response.ReasonPhrase, "#110");
567 Assert.AreEqual (HttpVersion.Version11, response.Version, "#111");
569 Assert.AreEqual (false, failed, "#112");
576 public void Send_Complete_CustomHeaders_SpecialSeparators ()
580 var listener = CreateListener (l => {
581 var request = l.Request;
584 Assert.AreEqual ("MLK Android Phone 1.1.9", request.UserAgent, "#1");
592 var client = new HttpClient ();
594 client.DefaultRequestHeaders.Add("User-Agent", "MLK Android Phone 1.1.9");
596 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
598 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
600 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
601 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
602 Assert.AreEqual (false, failed, "#102");
610 public void Send_Complete_CustomHeaders_Host ()
613 var listener = CreateListener (l => {
614 var request = l.Request;
617 Assert.AreEqual ("customhost", request.Headers["Host"], "#1");
625 var client = new HttpClient ();
627 client.DefaultRequestHeaders.Add("Host", "customhost");
629 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
631 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
633 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
634 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
635 Assert.AreEqual (false, failed, "#102");
643 public void Send_Transfer_Encoding_Chunked ()
647 var listener = CreateListener (l => {
648 var request = l.Request;
651 Assert.AreEqual (1, request.Headers.Count, "#1");
659 var client = new HttpClient ();
660 client.DefaultRequestHeaders.TransferEncodingChunked = true;
662 client.GetAsync (LocalServer).Wait ();
664 Assert.AreEqual (false, failed, "#102");
672 public void Send_Transfer_Encoding_Custom ()
676 var listener = CreateListener (l => {
681 var client = new HttpClient ();
682 client.DefaultRequestHeaders.TransferEncoding.Add (new TransferCodingHeaderValue ("chunked2"));
684 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
687 client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Wait ();
689 } catch (AggregateException e) {
690 Assert.AreEqual (typeof (ProtocolViolationException), e.InnerException.GetType (), "#2");
692 Assert.IsNull (failed, "#102");
700 public void Send_Complete_Content ()
702 var listener = CreateListener (l => {
703 var request = l.Request;
704 l.Response.OutputStream.WriteByte (55);
705 l.Response.OutputStream.WriteByte (75);
709 var client = new HttpClient ();
710 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
711 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
712 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
714 Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
715 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
717 IEnumerable<string> values;
718 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
719 Assert.AreEqual ("chunked", values.First (), "#102a");
720 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
727 public void Send_Complete_Content_MaxResponseContentBufferSize ()
729 var listener = CreateListener (l => {
730 var request = l.Request;
731 var b = new byte[4000];
732 l.Response.OutputStream.Write (b, 0, b.Length);
736 var client = new HttpClient ();
737 client.MaxResponseContentBufferSize = 1000;
738 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
739 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
741 Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
742 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
749 public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
751 var listener = CreateListener (l => {
752 var request = l.Request;
753 var b = new byte[4000];
754 l.Response.OutputStream.Write (b, 0, b.Length);
758 var client = new HttpClient ();
759 client.MaxResponseContentBufferSize = 1000;
760 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
763 client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait (WaitTimeout);
765 } catch (AggregateException e) {
766 Assert.IsTrue (e.InnerException is HttpRequestException, "#3");
775 public void Send_Complete_NoContent ()
777 foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
779 var listener = CreateListener (l => {
781 var request = l.Request;
783 Assert.AreEqual (2, request.Headers.Count, "#1");
784 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b");
785 Assert.AreEqual (method.Method, request.HttpMethod, "#2");
793 var client = new HttpClient ();
794 var request = new HttpRequestMessage (method, LocalServer);
795 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
797 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
798 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
799 Assert.AreEqual (false, failed, "#102");
807 public void Send_Complete_Error ()
809 var listener = CreateListener (l => {
810 var response = l.Response;
811 response.StatusCode = 500;
815 var client = new HttpClient ();
816 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
817 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
819 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
820 Assert.AreEqual (HttpStatusCode.InternalServerError, response.StatusCode, "#101");
827 public void Send_Content_Get ()
829 var listener = CreateListener (l => {
830 var request = l.Request;
831 l.Response.OutputStream.WriteByte (72);
835 var client = new HttpClient ();
836 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
837 var response = client.SendAsync (r).Result;
839 Assert.AreEqual ("H", response.Content.ReadAsStringAsync ().Result);
846 public void Send_Content_BomEncoding ()
848 var listener = CreateListener (l => {
849 var request = l.Request;
851 var str = l.Response.OutputStream;
852 str.WriteByte (0xEF);
853 str.WriteByte (0xBB);
854 str.WriteByte (0xBF);
859 var client = new HttpClient ();
860 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
861 var response = client.SendAsync (r).Result;
863 Assert.AreEqual ("G", response.Content.ReadAsStringAsync ().Result);
870 public void Send_Content_Put ()
873 var listener = CreateListener (l => {
874 var request = l.Request;
875 passed = 7 == request.ContentLength64;
876 passed &= request.ContentType == "text/plain; charset=utf-8";
877 passed &= request.InputStream.ReadByte () == 'm';
881 var client = new HttpClient ();
882 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
883 r.Content = new StringContent ("my text");
884 var response = client.SendAsync (r).Result;
886 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
887 Assert.IsTrue (passed, "#2");
895 public void Send_Content_Put_CustomStream ()
898 var listener = CreateListener (l => {
899 var request = l.Request;
900 passed = 44 == request.ContentLength64;
901 passed &= request.ContentType == null;
905 var client = new HttpClient ();
906 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
907 r.Content = new StreamContent (new CustomStream ());
908 var response = client.SendAsync (r).Result;
910 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
911 Assert.IsTrue (passed, "#2");
920 public void Send_Timeout ()
922 var mh = new HttpMessageHandlerMock ();
924 var client = new HttpClient (mh);
925 client.Timeout = TimeSpan.FromMilliseconds (100);
926 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
927 var response = new HttpResponseMessage ();
929 mh.OnSendFull = (l, c) => {
930 Assert.IsTrue (c.WaitHandle.WaitOne (500), "#2");
931 return Task.FromResult (response);
934 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
938 public void Send_Invalid ()
940 var client = new HttpClient ();
942 client.SendAsync (null).Wait (WaitTimeout);
944 } catch (ArgumentNullException) {
948 var request = new HttpRequestMessage ();
949 client.SendAsync (request).Wait (WaitTimeout);
951 } catch (InvalidOperationException) {
956 public void Send_InvalidHandler ()
958 var mh = new HttpMessageHandlerMock ();
960 var client = new HttpClient (mh);
961 client.BaseAddress = new Uri ("http://xamarin.com");
962 var request = new HttpRequestMessage ();
965 Assert.AreEqual (l, request, "#1");
971 client.SendAsync (request).Wait (WaitTimeout);
973 } catch (Exception) {
978 public void Send_SameMessage ()
980 var mh = new HttpMessageHandlerMock ();
982 var client = new HttpClient (mh);
983 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
985 mh.OnSend = l => Task.FromResult (new HttpResponseMessage ());
987 client.SendAsync (request).Wait (WaitTimeout);
989 client.SendAsync (request).Wait (WaitTimeout);
991 } catch (InvalidOperationException) {
996 [Category ("MobileNotWorking")] // Missing encoding
997 public void GetString_Many ()
999 Action<HttpListenerContext> context = (HttpListenerContext l) => {
1000 var response = l.Response;
1001 response.StatusCode = 200;
1002 response.OutputStream.WriteByte (0x68);
1003 response.OutputStream.WriteByte (0x65);
1004 response.OutputStream.WriteByte (0x6c);
1005 response.OutputStream.WriteByte (0x6c);
1006 response.OutputStream.WriteByte (0x6f);
1009 var listener = CreateListener (context); // creates a default request handler
1010 AddListenerContext (listener, context); // add another request handler for the second request
1013 var client = new HttpClient ();
1014 var t1 = client.GetStringAsync (LocalServer);
1015 var t2 = client.GetStringAsync (LocalServer);
1016 Assert.IsTrue (Task.WaitAll (new [] { t1, t2 }, WaitTimeout));
1017 Assert.AreEqual ("hello", t1.Result, "#1");
1018 Assert.AreEqual ("hello", t2.Result, "#2");
1026 public void GetByteArray_ServerError ()
1028 var listener = CreateListener (l => {
1029 var response = l.Response;
1030 response.StatusCode = 500;
1031 l.Response.OutputStream.WriteByte (72);
1035 var client = new HttpClient ();
1037 client.GetByteArrayAsync (LocalServer).Wait (WaitTimeout);
1039 } catch (AggregateException e) {
1040 Assert.IsTrue (e.InnerException is HttpRequestException , "#2");
1048 public void DisallowAutoRedirect ()
1050 var listener = CreateListener (l => {
1051 var request = l.Request;
1052 var response = l.Response;
1054 response.StatusCode = (int)HttpStatusCode.Moved;
1055 response.RedirectLocation = "http://xamarin.com/";
1059 var chandler = new HttpClientHandler ();
1060 chandler.AllowAutoRedirect = false;
1061 var client = new HttpClient (chandler);
1064 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1066 } catch (AggregateException e) {
1067 Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
1076 public void RequestUriAfterRedirect ()
1078 var listener = CreateListener (l => {
1079 var request = l.Request;
1080 var response = l.Response;
1082 response.StatusCode = (int)HttpStatusCode.Moved;
1083 response.RedirectLocation = "http://xamarin.com/";
1087 var chandler = new HttpClientHandler ();
1088 chandler.AllowAutoRedirect = true;
1089 var client = new HttpClient (chandler);
1091 var r = client.GetAsync (LocalServer);
1092 Assert.IsTrue (r.Wait (WaitTimeout), "#1");
1093 var resp = r.Result;
1094 Assert.AreEqual ("http://xamarin.com/", resp.RequestMessage.RequestUri.AbsoluteUri, "#2");
1103 * Properties may only be modified before sending the first request.
1105 public void ModifyHandlerAfterFirstRequest ()
1107 var chandler = new HttpClientHandler ();
1108 chandler.AllowAutoRedirect = true;
1109 var client = new HttpClient (chandler, true);
1111 var listener = CreateListener (l => {
1112 var response = l.Response;
1113 response.StatusCode = 200;
1114 response.OutputStream.WriteByte (55);
1118 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1120 chandler.AllowAutoRedirect = false;
1122 } catch (InvalidOperationException) {
1133 * However, this policy is not enforced for custom handlers and there
1134 * is also no way a derived class could tell its HttpClientHandler parent
1135 * that it just sent a request.
1138 public void ModifyHandlerAfterFirstRequest_Mock ()
1140 var ch = new HttpClientHandlerMock ();
1141 ch.AllowAutoRedirect = true;
1143 var client = new HttpClient (ch);
1145 ch.OnSend = (l) => {
1146 return Task.FromResult (new HttpResponseMessage ());
1149 client.GetAsync ("http://xamarin.com").Wait (WaitTimeout);
1150 ch.AllowAutoRedirect = false;
1153 HttpListener CreateListener (Action<HttpListenerContext> contextAssert)
1155 var l = new HttpListener ();
1156 l.Prefixes.Add (string.Format ("http://+:{0}/", port));
1158 AddListenerContext(l, contextAssert);
1163 HttpListener AddListenerContext (HttpListener l, Action<HttpListenerContext> contextAssert)
1165 l.BeginGetContext (ar => {
1166 var ctx = l.EndGetContext (ar);
1169 if (contextAssert != null)
1170 contextAssert (ctx);
1172 ctx.Response.Close ();