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 class ThrowOnlyProxy : IWebProxy
155 public ICredentials Credentials {
157 throw new NotImplementedException ();
161 throw new NotImplementedException ();
165 public Uri GetProxy (Uri destination)
167 throw new NotImplementedException ();
170 public bool IsBypassed (Uri host)
172 throw new NotImplementedException ();
176 const int WaitTimeout = 5000;
178 string TestHost, LocalServer;
182 public void SetupFixture ()
184 if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
190 TestHost = "localhost:" + port;
191 LocalServer = string.Format ("http://{0}/", TestHost);
195 public void Ctor_Default ()
197 var client = new HttpClient ();
198 Assert.IsNull (client.BaseAddress, "#1");
199 Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
200 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
201 Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
205 public void CancelPendingRequests ()
207 var mh = new HttpMessageHandlerMock ();
209 var client = new HttpClient (mh);
210 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
211 var mre = new ManualResetEvent (false);
213 mh.OnSendFull = (l, c) => {
215 Assert.IsTrue (c.WaitHandle.WaitOne (1000), "#20");
216 Assert.IsTrue (c.IsCancellationRequested, "#21");
218 return Task.FromResult (new HttpResponseMessage ());
221 var t = Task.Factory.StartNew (() => {
222 client.SendAsync (request).Wait (WaitTimeout);
225 Assert.IsTrue (mre.WaitOne (500), "#1");
227 client.CancelPendingRequests ();
228 Assert.IsTrue (t.Wait (500), "#2");
230 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
231 mh.OnSendFull = (l, c) => {
232 Assert.IsFalse (c.IsCancellationRequested, "#30");
233 return Task.FromResult (new HttpResponseMessage ());
236 client.SendAsync (request).Wait (WaitTimeout);
240 public void CancelPendingRequests_BeforeSend ()
242 var ct = new CancellationTokenSource ();
244 var rr = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken (), ct.Token);
247 var mh = new HttpMessageHandlerMock ();
249 var client = new HttpClient (mh);
250 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
251 client.CancelPendingRequests ();
253 mh.OnSendFull = (l, c) => {
254 Assert.IsFalse (c.IsCancellationRequested, "#30");
255 return Task.FromResult (new HttpResponseMessage ());
258 client.SendAsync (request).Wait (WaitTimeout);
260 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
261 client.SendAsync (request).Wait (WaitTimeout);
266 #if FEATURE_NO_BSD_SOCKETS
267 // Using HttpClientHandler, which indirectly requires BSD sockets.
268 [ExpectedException (typeof (PlatformNotSupportedException))]
270 public void CancelRequestViaProxy ()
272 var handler = new HttpClientHandler {
273 Proxy = new WebProxy ("192.168.10.25:8888/"), // proxy that doesn't exist
275 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
278 var httpClient = new HttpClient (handler) {
279 BaseAddress = new Uri ("https://google.com"),
280 Timeout = TimeSpan.FromMilliseconds (1)
284 var restRequest = new HttpRequestMessage {
285 Method = HttpMethod.Post,
286 RequestUri = new Uri("foo", UriKind.Relative),
287 Content = new StringContent("", null, "application/json")
290 httpClient.PostAsync (restRequest.RequestUri, restRequest.Content).Wait (WaitTimeout);
292 } catch (AggregateException e) {
293 Assert.IsTrue (e.InnerException is TaskCanceledException, "#2");
298 public void Properties ()
300 var client = new HttpClient ();
301 client.BaseAddress = null;
302 client.MaxResponseContentBufferSize = int.MaxValue;
303 client.Timeout = Timeout.InfiniteTimeSpan;
305 Assert.IsNull (client.BaseAddress, "#1");
306 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#2");
307 Assert.AreEqual (Timeout.InfiniteTimeSpan, client.Timeout, "#3");
311 public void Properties_Invalid ()
313 var client = new HttpClient ();
315 client.MaxResponseContentBufferSize = 0;
317 } catch (ArgumentOutOfRangeException) {
321 client.Timeout = TimeSpan.MinValue;
323 } catch (ArgumentOutOfRangeException) {
328 #if FEATURE_NO_BSD_SOCKETS
329 [ExpectedException (typeof (PlatformNotSupportedException))]
331 public void Proxy_Disabled ()
333 var pp = WebRequest.DefaultWebProxy;
336 WebRequest.DefaultWebProxy = new ThrowOnlyProxy ();
338 var request = new HttpClientHandler {
342 var client = new HttpClient (request);
343 Assert.IsTrue (client.GetAsync ("http://google.com").Wait (5000), "needs internet access");
345 WebRequest.DefaultWebProxy = pp;
352 var mh = new HttpMessageHandlerMock ();
354 var client = new HttpClient (mh);
355 client.BaseAddress = new Uri ("http://xamarin.com");
356 var request = new HttpRequestMessage ();
357 var response = new HttpResponseMessage ();
360 Assert.AreEqual (l, request, "#2");
361 Assert.AreEqual (client.BaseAddress, l.RequestUri, "#2");
362 return Task.FromResult (response);
365 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
369 public void Send_BaseAddress ()
371 var mh = new HttpMessageHandlerMock ();
373 var client = new HttpClient (mh);
374 client.BaseAddress = new Uri ("http://localhost/");
375 var response = new HttpResponseMessage ();
378 Assert.AreEqual ("http://localhost/relative", l.RequestUri.ToString (), "#2");
379 return Task.FromResult (response);
382 Assert.AreEqual (response, client.GetAsync ("relative").Result, "#1");
383 Assert.AreEqual (response, client.GetAsync ("/relative").Result, "#2");
387 public void Send_DefaultRequestHeaders ()
389 var mh = new HttpMessageHandlerMock ();
391 var client = new HttpClient (mh);
392 client.DefaultRequestHeaders.Referrer = new Uri ("http://google.com");
394 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
395 var response = new HttpResponseMessage ();
398 Assert.AreEqual (client.DefaultRequestHeaders.Referrer, l.Headers.Referrer, "#2");
399 Assert.IsNotNull (l.Headers.Referrer, "#3");
400 return Task.FromResult (response);
403 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
407 #if FEATURE_NO_BSD_SOCKETS
408 [ExpectedException (typeof (PlatformNotSupportedException))]
410 public void Send_Complete_Default ()
413 var listener = CreateListener (l => {
415 var request = l.Request;
417 Assert.IsNull (request.AcceptTypes, "#1");
418 Assert.AreEqual (0, request.ContentLength64, "#2");
419 Assert.IsNull (request.ContentType, "#3");
420 Assert.AreEqual (0, request.Cookies.Count, "#4");
421 Assert.IsFalse (request.HasEntityBody, "#5");
422 Assert.AreEqual (TestHost, request.Headers["Host"], "#6b");
423 Assert.AreEqual ("GET", request.HttpMethod, "#7");
424 Assert.IsFalse (request.IsAuthenticated, "#8");
425 Assert.IsTrue (request.IsLocal, "#9");
426 Assert.IsFalse (request.IsSecureConnection, "#10");
427 Assert.IsFalse (request.IsWebSocketRequest, "#11");
428 Assert.IsTrue (request.KeepAlive, "#12");
429 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
430 Assert.IsNull (request.ServiceName, "#14");
431 Assert.IsNull (request.UrlReferrer, "#15");
432 Assert.IsNull (request.UserAgent, "#16");
433 Assert.IsNull (request.UserLanguages, "#17");
441 var client = new HttpClient ();
442 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
443 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
445 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
446 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
447 Assert.AreEqual (false, failed, "#102");
454 #if FEATURE_NO_BSD_SOCKETS
455 [ExpectedException (typeof (PlatformNotSupportedException))]
457 public void Send_Complete_Version_1_0 ()
461 var listener = CreateListener (l => {
463 var request = l.Request;
465 Assert.IsNull (request.AcceptTypes, "#1");
466 Assert.AreEqual (0, request.ContentLength64, "#2");
467 Assert.IsNull (request.ContentType, "#3");
468 Assert.AreEqual (0, request.Cookies.Count, "#4");
469 Assert.IsFalse (request.HasEntityBody, "#5");
470 Assert.AreEqual (1, request.Headers.Count, "#6");
471 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
472 Assert.AreEqual ("GET", request.HttpMethod, "#7");
473 Assert.IsFalse (request.IsAuthenticated, "#8");
474 Assert.IsTrue (request.IsLocal, "#9");
475 Assert.IsFalse (request.IsSecureConnection, "#10");
476 Assert.IsFalse (request.IsWebSocketRequest, "#11");
477 Assert.IsFalse (request.KeepAlive, "#12");
478 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
479 Assert.IsNull (request.ServiceName, "#14");
480 Assert.IsNull (request.UrlReferrer, "#15");
481 Assert.IsNull (request.UserAgent, "#16");
482 Assert.IsNull (request.UserLanguages, "#17");
490 var client = new HttpClient ();
491 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
492 request.Version = HttpVersion.Version10;
493 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
495 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
496 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
497 Assert.AreEqual (false, failed, "#102");
504 #if FEATURE_NO_BSD_SOCKETS
505 [ExpectedException (typeof (PlatformNotSupportedException))]
507 public void Send_Complete_ClientHandlerSettings ()
511 var listener = CreateListener (l => {
512 var request = l.Request;
515 Assert.IsNull (request.AcceptTypes, "#1");
516 Assert.AreEqual (0, request.ContentLength64, "#2");
517 Assert.IsNull (request.ContentType, "#3");
518 Assert.AreEqual (1, request.Cookies.Count, "#4");
519 Assert.AreEqual (new Cookie ("mycookie", "vv"), request.Cookies[0], "#4a");
520 Assert.IsFalse (request.HasEntityBody, "#5");
521 Assert.AreEqual (4, request.Headers.Count, "#6");
522 Assert.AreEqual (TestHost, request.Headers["Host"], "#6a");
523 Assert.AreEqual ("gzip", request.Headers["Accept-Encoding"], "#6b");
524 Assert.AreEqual ("mycookie=vv", request.Headers["Cookie"], "#6c");
525 Assert.AreEqual ("GET", request.HttpMethod, "#7");
526 Assert.IsFalse (request.IsAuthenticated, "#8");
527 Assert.IsTrue (request.IsLocal, "#9");
528 Assert.IsFalse (request.IsSecureConnection, "#10");
529 Assert.IsFalse (request.IsWebSocketRequest, "#11");
530 Assert.IsTrue (request.KeepAlive, "#12");
531 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
532 Assert.IsNull (request.ServiceName, "#14");
533 Assert.IsNull (request.UrlReferrer, "#15");
534 Assert.IsNull (request.UserAgent, "#16");
535 Assert.IsNull (request.UserLanguages, "#17");
543 var chandler = new HttpClientHandler ();
544 chandler.AllowAutoRedirect = true;
545 chandler.AutomaticDecompression = DecompressionMethods.GZip;
546 chandler.MaxAutomaticRedirections = 33;
547 chandler.MaxRequestContentBufferSize = 5555;
548 chandler.PreAuthenticate = true;
549 chandler.CookieContainer.Add (new Uri (LocalServer), new Cookie ( "mycookie", "vv"));
550 chandler.UseCookies = true;
551 chandler.UseDefaultCredentials = true;
552 chandler.Proxy = new WebProxy ("ee");
553 chandler.UseProxy = true;
555 var client = new HttpClient (chandler);
556 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
557 request.Version = HttpVersion.Version10;
558 request.Headers.Add ("Keep-Alive", "false");
559 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
561 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
562 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
563 Assert.AreEqual (false, failed, "#102");
571 #if FEATURE_NO_BSD_SOCKETS
572 [ExpectedException (typeof (PlatformNotSupportedException))]
574 public void Send_Complete_CustomHeaders ()
578 var listener = CreateListener (l => {
579 var request = l.Request;
581 Assert.AreEqual ("vv", request.Headers["aa"], "#1");
583 var response = l.Response;
584 response.Headers.Add ("rsp", "rrr");
585 response.Headers.Add ("upgrade", "vvvvaa");
586 response.Headers.Add ("Date", "aa");
587 response.Headers.Add ("cache-control", "audio");
589 response.StatusDescription = "test description";
590 response.ProtocolVersion = HttpVersion.Version10;
591 response.SendChunked = true;
592 response.RedirectLocation = "w3.org";
601 var client = new HttpClient ();
602 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
603 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
604 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
606 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
607 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
609 IEnumerable<string> values;
610 Assert.IsTrue (response.Headers.TryGetValues ("rsp", out values), "#102");
611 Assert.AreEqual ("rrr", values.First (), "#102a");
613 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#103");
614 Assert.AreEqual ("chunked", values.First (), "#103a");
615 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#103b");
617 Assert.IsTrue (response.Headers.TryGetValues ("Date", out values), "#104");
618 Assert.AreEqual (1, values.Count (), "#104b");
619 // .NET overwrites Date, Mono does not
620 // Assert.IsNotNull (response.Headers.Date, "#104c");
622 Assert.AreEqual (new ProductHeaderValue ("vvvvaa"), response.Headers.Upgrade.First (), "#105");
624 Assert.AreEqual ("audio", response.Headers.CacheControl.Extensions.First ().Name, "#106");
626 Assert.AreEqual ("w3.org", response.Headers.Location.OriginalString, "#107");
628 Assert.AreEqual ("test description", response.ReasonPhrase, "#110");
629 Assert.AreEqual (HttpVersion.Version11, response.Version, "#111");
631 Assert.AreEqual (false, failed, "#112");
638 #if FEATURE_NO_BSD_SOCKETS
639 [ExpectedException (typeof (PlatformNotSupportedException))]
641 public void Send_Complete_CustomHeaders_SpecialSeparators ()
645 var listener = CreateListener (l => {
646 var request = l.Request;
649 Assert.AreEqual ("MLK Android Phone 1.1.9", request.UserAgent, "#1");
657 var client = new HttpClient ();
659 client.DefaultRequestHeaders.Add("User-Agent", "MLK Android Phone 1.1.9");
661 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
663 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
665 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
666 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
667 Assert.AreEqual (false, failed, "#102");
675 #if FEATURE_NO_BSD_SOCKETS
676 [ExpectedException (typeof (PlatformNotSupportedException))]
678 public void Send_Complete_CustomHeaders_Host ()
681 var listener = CreateListener (l => {
682 var request = l.Request;
685 Assert.AreEqual ("customhost", request.Headers["Host"], "#1");
693 var client = new HttpClient ();
695 client.DefaultRequestHeaders.Add("Host", "customhost");
697 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
699 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
701 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
702 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
703 Assert.AreEqual (false, failed, "#102");
711 #if FEATURE_NO_BSD_SOCKETS
712 [ExpectedException (typeof (PlatformNotSupportedException))]
714 public void Send_Transfer_Encoding_Chunked ()
718 var listener = CreateListener (l => {
719 var request = l.Request;
722 Assert.AreEqual (1, request.Headers.Count, "#1");
730 var client = new HttpClient ();
731 client.DefaultRequestHeaders.TransferEncodingChunked = true;
733 client.GetAsync (LocalServer).Wait ();
735 Assert.AreEqual (false, failed, "#102");
743 #if FEATURE_NO_BSD_SOCKETS
744 [ExpectedException (typeof (PlatformNotSupportedException))]
746 public void Send_Transfer_Encoding_Custom ()
750 var listener = CreateListener (l => {
755 var client = new HttpClient ();
756 client.DefaultRequestHeaders.TransferEncoding.Add (new TransferCodingHeaderValue ("chunked2"));
758 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
761 client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Wait ();
763 } catch (AggregateException e) {
764 Assert.AreEqual (typeof (ProtocolViolationException), e.InnerException.GetType (), "#2");
766 Assert.IsNull (failed, "#102");
774 #if FEATURE_NO_BSD_SOCKETS
775 [ExpectedException (typeof (PlatformNotSupportedException))]
777 public void Send_Complete_Content ()
779 var listener = CreateListener (l => {
780 var request = l.Request;
781 l.Response.OutputStream.WriteByte (55);
782 l.Response.OutputStream.WriteByte (75);
786 var client = new HttpClient ();
787 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
788 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
789 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
791 Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
792 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
794 IEnumerable<string> values;
795 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
796 Assert.AreEqual ("chunked", values.First (), "#102a");
797 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
804 #if FEATURE_NO_BSD_SOCKETS
805 [ExpectedException (typeof (PlatformNotSupportedException))]
807 public void Send_Complete_Content_MaxResponseContentBufferSize ()
809 var listener = CreateListener (l => {
810 var request = l.Request;
811 var b = new byte[4000];
812 l.Response.OutputStream.Write (b, 0, b.Length);
816 var client = new HttpClient ();
817 client.MaxResponseContentBufferSize = 1000;
818 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
819 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
821 Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
822 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
829 #if FEATURE_NO_BSD_SOCKETS
830 [ExpectedException (typeof (PlatformNotSupportedException))]
832 public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
834 var listener = CreateListener (l => {
835 var request = l.Request;
836 var b = new byte[4000];
837 l.Response.OutputStream.Write (b, 0, b.Length);
841 var client = new HttpClient ();
842 client.MaxResponseContentBufferSize = 1000;
843 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
846 client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait (WaitTimeout);
848 } catch (AggregateException e) {
849 Assert.IsTrue (e.InnerException is HttpRequestException, "#3");
858 #if FEATURE_NO_BSD_SOCKETS
859 [ExpectedException (typeof (PlatformNotSupportedException))]
861 public void Send_Complete_NoContent ()
863 foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
865 var listener = CreateListener (l => {
867 var request = l.Request;
869 Assert.AreEqual (2, request.Headers.Count, "#1");
870 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b");
871 Assert.AreEqual (method.Method, request.HttpMethod, "#2");
879 var client = new HttpClient ();
880 var request = new HttpRequestMessage (method, LocalServer);
881 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
883 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
884 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
885 Assert.AreEqual (false, failed, "#102");
893 #if FEATURE_NO_BSD_SOCKETS
894 [ExpectedException (typeof (PlatformNotSupportedException))]
896 public void Send_Complete_Error ()
898 var listener = CreateListener (l => {
899 var response = l.Response;
900 response.StatusCode = 500;
904 var client = new HttpClient ();
905 var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
906 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
908 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
909 Assert.AreEqual (HttpStatusCode.InternalServerError, response.StatusCode, "#101");
916 #if FEATURE_NO_BSD_SOCKETS
917 [ExpectedException (typeof (PlatformNotSupportedException))]
919 public void Send_Content_Get ()
921 var listener = CreateListener (l => {
922 var request = l.Request;
923 l.Response.OutputStream.WriteByte (72);
927 var client = new HttpClient ();
928 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
929 var response = client.SendAsync (r).Result;
931 Assert.AreEqual ("H", response.Content.ReadAsStringAsync ().Result);
938 #if FEATURE_NO_BSD_SOCKETS
939 [ExpectedException (typeof (PlatformNotSupportedException))]
941 public void Send_Content_BomEncoding ()
943 var listener = CreateListener (l => {
944 var request = l.Request;
946 var str = l.Response.OutputStream;
947 str.WriteByte (0xEF);
948 str.WriteByte (0xBB);
949 str.WriteByte (0xBF);
954 var client = new HttpClient ();
955 var r = new HttpRequestMessage (HttpMethod.Get, LocalServer);
956 var response = client.SendAsync (r).Result;
958 Assert.AreEqual ("G", response.Content.ReadAsStringAsync ().Result);
965 #if FEATURE_NO_BSD_SOCKETS
966 [ExpectedException (typeof (PlatformNotSupportedException))]
968 public void Send_Content_Put ()
971 var listener = CreateListener (l => {
972 var request = l.Request;
973 passed = 7 == request.ContentLength64;
974 passed &= request.ContentType == "text/plain; charset=utf-8";
975 passed &= request.InputStream.ReadByte () == 'm';
979 var client = new HttpClient ();
980 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
981 r.Content = new StringContent ("my text");
982 var response = client.SendAsync (r).Result;
984 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
985 Assert.IsTrue (passed, "#2");
993 #if FEATURE_NO_BSD_SOCKETS
994 [ExpectedException (typeof (PlatformNotSupportedException))]
996 public void Send_Content_Put_CustomStream ()
999 var listener = CreateListener (l => {
1000 var request = l.Request;
1001 passed = 44 == request.ContentLength64;
1002 passed &= request.ContentType == null;
1006 var client = new HttpClient ();
1007 var r = new HttpRequestMessage (HttpMethod.Put, LocalServer);
1008 r.Content = new StreamContent (new CustomStream ());
1009 var response = client.SendAsync (r).Result;
1011 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
1012 Assert.IsTrue (passed, "#2");
1021 public void Send_Timeout ()
1023 var mh = new HttpMessageHandlerMock ();
1025 var client = new HttpClient (mh);
1026 client.Timeout = TimeSpan.FromMilliseconds (100);
1027 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
1028 var response = new HttpResponseMessage ();
1030 mh.OnSendFull = (l, c) => {
1031 Assert.IsTrue (c.WaitHandle.WaitOne (500), "#2");
1032 return Task.FromResult (response);
1035 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
1039 public void Send_Invalid ()
1041 var client = new HttpClient ();
1043 client.SendAsync (null).Wait (WaitTimeout);
1045 } catch (ArgumentNullException) {
1049 var request = new HttpRequestMessage ();
1050 client.SendAsync (request).Wait (WaitTimeout);
1052 } catch (InvalidOperationException) {
1057 public void Send_InvalidHandler ()
1059 var mh = new HttpMessageHandlerMock ();
1061 var client = new HttpClient (mh);
1062 client.BaseAddress = new Uri ("http://xamarin.com");
1063 var request = new HttpRequestMessage ();
1066 Assert.AreEqual (l, request, "#1");
1072 client.SendAsync (request).Wait (WaitTimeout);
1074 } catch (Exception) {
1079 public void Send_SameMessage ()
1081 var mh = new HttpMessageHandlerMock ();
1083 var client = new HttpClient (mh);
1084 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
1086 mh.OnSend = l => Task.FromResult (new HttpResponseMessage ());
1088 client.SendAsync (request).Wait (WaitTimeout);
1090 client.SendAsync (request).Wait (WaitTimeout);
1092 } catch (InvalidOperationException) {
1097 #if FEATURE_NO_BSD_SOCKETS
1098 [ExpectedException (typeof (PlatformNotSupportedException))]
1100 public void Post_TransferEncodingChunked ()
1102 bool? failed = null;
1103 var listener = CreateListener (l => {
1105 var request = l.Request;
1107 Assert.IsNull (request.AcceptTypes, "#1");
1108 Assert.AreEqual (-1, request.ContentLength64, "#2");
1109 Assert.IsNull (request.ContentType, "#3");
1110 Assert.AreEqual (0, request.Cookies.Count, "#4");
1111 Assert.IsTrue (request.HasEntityBody, "#5");
1112 Assert.AreEqual (TestHost, request.Headers ["Host"], "#6b");
1113 Assert.AreEqual ("POST", request.HttpMethod, "#7");
1114 Assert.IsFalse (request.IsAuthenticated, "#8");
1115 Assert.IsTrue (request.IsLocal, "#9");
1116 Assert.IsFalse (request.IsSecureConnection, "#10");
1117 Assert.IsFalse (request.IsWebSocketRequest, "#11");
1118 Assert.IsTrue (request.KeepAlive, "#12");
1119 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
1120 Assert.IsNull (request.ServiceName, "#14");
1121 Assert.IsNull (request.UrlReferrer, "#15");
1122 Assert.IsNull (request.UserAgent, "#16");
1123 Assert.IsNull (request.UserLanguages, "#17");
1124 Assert.AreEqual ("chunked", request.Headers ["Transfer-Encoding"], "#18");
1125 Assert.IsNull (request.Headers ["Content-Length"], "#19");
1127 } catch (Exception e) {
1129 Console.WriteLine (e);
1134 var client = new HttpClient ();
1136 client.DefaultRequestHeaders.TransferEncodingChunked = true;
1138 var imageContent = new StreamContent (new MemoryStream ());
1140 var response = client.PostAsync (LocalServer, imageContent).Result;
1142 Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101");
1143 Assert.AreEqual(false, failed, "#102");
1150 #if FEATURE_NO_BSD_SOCKETS
1151 [ExpectedException (typeof (PlatformNotSupportedException))]
1153 public void Post_StreamCaching ()
1155 bool? failed = null;
1156 var listener = CreateListener (l => {
1158 var request = l.Request;
1160 Assert.IsNull (request.AcceptTypes, "#1");
1161 Assert.AreEqual (0, request.ContentLength64, "#2");
1162 Assert.IsNull (request.ContentType, "#3");
1163 Assert.AreEqual (0, request.Cookies.Count, "#4");
1164 Assert.IsFalse (request.HasEntityBody, "#5");
1165 Assert.AreEqual (TestHost, request.Headers ["Host"], "#6b");
1166 Assert.AreEqual ("POST", request.HttpMethod, "#7");
1167 Assert.IsFalse (request.IsAuthenticated, "#8");
1168 Assert.IsTrue (request.IsLocal, "#9");
1169 Assert.IsFalse (request.IsSecureConnection, "#10");
1170 Assert.IsFalse (request.IsWebSocketRequest, "#11");
1171 Assert.IsTrue (request.KeepAlive, "#12");
1172 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
1173 Assert.IsNull (request.ServiceName, "#14");
1174 Assert.IsNull (request.UrlReferrer, "#15");
1175 Assert.IsNull (request.UserAgent, "#16");
1176 Assert.IsNull (request.UserLanguages, "#17");
1177 Assert.IsNull (request.Headers ["Transfer-Encoding"], "#18");
1178 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#19");
1180 } catch (Exception e) {
1182 Console.WriteLine (e);
1187 var client = new HttpClient ();
1189 var imageContent = new StreamContent (new MemoryStream ());
1191 var response = client.PostAsync (LocalServer, imageContent).Result;
1193 Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101");
1194 Assert.AreEqual(false, failed, "#102");
1201 [Category ("MobileNotWorking")] // Missing encoding
1202 #if FEATURE_NO_BSD_SOCKETS
1203 [ExpectedException (typeof (PlatformNotSupportedException))]
1205 public void GetString_Many ()
1207 Action<HttpListenerContext> context = (HttpListenerContext l) => {
1208 var response = l.Response;
1209 response.StatusCode = 200;
1210 response.OutputStream.WriteByte (0x68);
1211 response.OutputStream.WriteByte (0x65);
1212 response.OutputStream.WriteByte (0x6c);
1213 response.OutputStream.WriteByte (0x6c);
1214 response.OutputStream.WriteByte (0x6f);
1217 var listener = CreateListener (context); // creates a default request handler
1218 AddListenerContext (listener, context); // add another request handler for the second request
1221 var client = new HttpClient ();
1222 var t1 = client.GetStringAsync (LocalServer);
1223 var t2 = client.GetStringAsync (LocalServer);
1224 Assert.IsTrue (Task.WaitAll (new [] { t1, t2 }, WaitTimeout));
1225 Assert.AreEqual ("hello", t1.Result, "#1");
1226 Assert.AreEqual ("hello", t2.Result, "#2");
1234 #if FEATURE_NO_BSD_SOCKETS
1235 [ExpectedException (typeof (PlatformNotSupportedException))]
1237 public void GetByteArray_ServerError ()
1239 var listener = CreateListener (l => {
1240 var response = l.Response;
1241 response.StatusCode = 500;
1242 l.Response.OutputStream.WriteByte (72);
1246 var client = new HttpClient ();
1248 client.GetByteArrayAsync (LocalServer).Wait (WaitTimeout);
1250 } catch (AggregateException e) {
1251 Assert.IsTrue (e.InnerException is HttpRequestException , "#2");
1259 #if FEATURE_NO_BSD_SOCKETS
1260 [ExpectedException (typeof (PlatformNotSupportedException))]
1262 public void DisallowAutoRedirect ()
1264 var listener = CreateListener (l => {
1265 var request = l.Request;
1266 var response = l.Response;
1268 response.StatusCode = (int)HttpStatusCode.Moved;
1269 response.RedirectLocation = "http://xamarin.com/";
1273 var chandler = new HttpClientHandler ();
1274 chandler.AllowAutoRedirect = false;
1275 var client = new HttpClient (chandler);
1278 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1280 } catch (AggregateException e) {
1281 Assert.IsTrue (e.InnerException is HttpRequestException, "#2");
1290 #if FEATURE_NO_BSD_SOCKETS
1291 [ExpectedException (typeof (PlatformNotSupportedException))]
1293 public void RequestUriAfterRedirect ()
1295 var listener = CreateListener (l => {
1296 var request = l.Request;
1297 var response = l.Response;
1299 response.StatusCode = (int)HttpStatusCode.Moved;
1300 response.RedirectLocation = "http://localhost:8811/";
1303 var listener2 = CreateListener (l => {
1304 var response = l.Response;
1306 response.StatusCode = (int)HttpStatusCode.OK;
1307 response.OutputStream.WriteByte (0x68);
1308 response.OutputStream.WriteByte (0x65);
1309 response.OutputStream.WriteByte (0x6c);
1310 response.OutputStream.WriteByte (0x6c);
1311 response.OutputStream.WriteByte (0x6f);
1315 var chandler = new HttpClientHandler ();
1316 chandler.AllowAutoRedirect = true;
1317 var client = new HttpClient (chandler);
1319 var r = client.GetAsync (LocalServer);
1320 Assert.IsTrue (r.Wait (WaitTimeout), "#1");
1321 var resp = r.Result;
1322 Assert.AreEqual ("http://localhost:8811/", resp.RequestMessage.RequestUri.AbsoluteUri, "#2");
1323 Assert.AreEqual ("hello", resp.Content.ReadAsStringAsync ().Result, "#3");
1333 #if FEATURE_NO_BSD_SOCKETS
1334 [ExpectedException (typeof (PlatformNotSupportedException))]
1337 * Properties may only be modified before sending the first request.
1339 public void ModifyHandlerAfterFirstRequest ()
1341 var chandler = new HttpClientHandler ();
1342 chandler.AllowAutoRedirect = true;
1343 var client = new HttpClient (chandler, true);
1345 var listener = CreateListener (l => {
1346 var response = l.Response;
1347 response.StatusCode = 200;
1348 response.OutputStream.WriteByte (55);
1352 client.GetStringAsync (LocalServer).Wait (WaitTimeout);
1354 chandler.AllowAutoRedirect = false;
1356 } catch (InvalidOperationException) {
1366 #if FEATURE_NO_BSD_SOCKETS
1367 // Using HttpClientHandler, which indirectly requires BSD sockets.
1368 [ExpectedException (typeof (PlatformNotSupportedException))]
1371 * However, this policy is not enforced for custom handlers and there
1372 * is also no way a derived class could tell its HttpClientHandler parent
1373 * that it just sent a request.
1376 public void ModifyHandlerAfterFirstRequest_Mock ()
1378 var ch = new HttpClientHandlerMock ();
1379 ch.AllowAutoRedirect = true;
1381 var client = new HttpClient (ch);
1383 ch.OnSend = (l) => {
1384 return Task.FromResult (new HttpResponseMessage ());
1387 client.GetAsync ("http://xamarin.com").Wait (WaitTimeout);
1388 ch.AllowAutoRedirect = false;
1391 HttpListener CreateListener (Action<HttpListenerContext> contextAssert)
1393 return CreateListener (contextAssert, port);
1396 HttpListener CreateListener (Action<HttpListenerContext> contextAssert, int port)
1398 var l = new HttpListener ();
1399 l.Prefixes.Add (string.Format ("http://+:{0}/", port));
1401 AddListenerContext(l, contextAssert);
1406 HttpListener AddListenerContext (HttpListener l, Action<HttpListenerContext> contextAssert)
1408 l.BeginGetContext (ar => {
1409 var ctx = l.EndGetContext (ar);
1412 if (contextAssert != null)
1413 contextAssert (ctx);
1415 ctx.Response.Close ();