Allow file:// based Uri's to be used in HttpClient when the BaseAddress is set
[mono-project.git] / mcs / class / System.Net.Http / Test / System.Net.Http / HttpClientTest.cs
blob402be6aa876ec7e2027125c6f8f73517e56b703a
1 //
2 // HttpClientTest.cs
3 //
4 // Authors:
5 // Marek Safar <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
8 //
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.
29 using System;
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;
37 using System.Net;
38 using System.Linq;
39 using System.IO;
41 using MonoTests.Helpers;
43 namespace MonoTests.System.Net.Http
45 [TestFixture]
46 public class HttpClientTest
48 class HttpMessageHandlerMock : HttpMessageHandler
50 public Func<HttpRequestMessage, Task<HttpResponseMessage>> OnSend;
51 public Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> OnSendFull;
53 public HttpMessageHandlerMock ()
57 protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
59 if (OnSend != null)
60 return OnSend (request);
62 if (OnSendFull != null)
63 return OnSendFull (request, cancellationToken);
65 Assert.Fail ("Send");
66 return null;
70 class HttpClientHandlerMock : HttpClientHandler
72 public Func<HttpRequestMessage, Task<HttpResponseMessage>> OnSend;
73 public Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> OnSendFull;
75 protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
77 if (OnSend != null)
78 return OnSend (request);
80 if (OnSendFull != null)
81 return OnSendFull (request, cancellationToken);
83 Assert.Fail ("Send");
84 return null;
88 class CustomStream : Stream
90 public override void Flush ()
92 throw new NotImplementedException ();
95 int pos;
97 public override int Read (byte[] buffer, int offset, int count)
99 ++pos;
100 if (pos > 4)
101 return 0;
103 return 11;
106 public override long Seek (long offset, SeekOrigin origin)
108 throw new NotImplementedException ();
111 public override void SetLength (long value)
113 throw new NotImplementedException ();
116 public override void Write (byte[] buffer, int offset, int count)
118 throw new NotImplementedException ();
121 public override bool CanRead {
122 get {
123 return true;
127 public override bool CanSeek {
128 get {
129 return false;
133 public override bool CanWrite {
134 get {
135 throw new NotImplementedException ();
139 public override long Length {
140 get {
141 throw new NotImplementedException ();
145 public override long Position {
146 get {
147 throw new NotImplementedException ();
149 set {
150 throw new NotImplementedException ();
155 class ThrowOnlyProxy : IWebProxy
157 public ICredentials Credentials {
158 get {
159 throw new NotImplementedException ();
162 set {
163 throw new NotImplementedException ();
167 public Uri GetProxy (Uri destination)
169 throw new NotImplementedException ();
172 public bool IsBypassed (Uri host)
174 throw new NotImplementedException ();
178 const int WaitTimeout = 5000;
180 [Test]
181 public void Ctor ()
183 var client = new HttpClient ();
184 Assert.IsNull (client.BaseAddress, "#1");
185 Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
186 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
187 Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
190 [Test]
191 #if FEATURE_NO_BSD_SOCKETS
192 [ExpectedException (typeof (PlatformNotSupportedException))]
193 #endif
194 public void Ctor_HttpClientHandler ()
196 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
197 Assert.IsNull (client.BaseAddress, "#1");
198 Assert.IsNotNull (client.DefaultRequestHeaders, "#2"); // TODO: full check
199 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#3");
200 Assert.AreEqual (TimeSpan.FromSeconds (100), client.Timeout, "#4");
203 [Test]
204 public void CancelPendingRequests ()
206 var mh = new HttpMessageHandlerMock ();
208 var client = new HttpClient (mh);
209 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
210 var mre = new ManualResetEvent (false);
212 mh.OnSendFull = (l, c) => {
213 mre.Set ();
214 Assert.IsTrue (c.WaitHandle.WaitOne (1000), "#20");
215 Assert.IsTrue (c.IsCancellationRequested, "#21");
216 mre.Set ();
217 return Task.FromResult (new HttpResponseMessage ());
220 var t = Task.Factory.StartNew (() => {
221 client.SendAsync (request).Wait (WaitTimeout);
224 Assert.IsTrue (mre.WaitOne (500), "#1");
225 mre.Reset ();
226 client.CancelPendingRequests ();
227 Assert.IsTrue (t.Wait (500), "#2");
229 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
230 mh.OnSendFull = (l, c) => {
231 Assert.IsFalse (c.IsCancellationRequested, "#30");
232 return Task.FromResult (new HttpResponseMessage ());
235 client.SendAsync (request).Wait (WaitTimeout);
238 [Test]
239 public void CancelPendingRequests_BeforeSend ()
241 var ct = new CancellationTokenSource ();
242 ct.Cancel ();
243 var rr = CancellationTokenSource.CreateLinkedTokenSource (new CancellationToken (), ct.Token);
246 var mh = new HttpMessageHandlerMock ();
248 var client = new HttpClient (mh);
249 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
250 client.CancelPendingRequests ();
252 mh.OnSendFull = (l, c) => {
253 Assert.IsFalse (c.IsCancellationRequested, "#30");
254 return Task.FromResult (new HttpResponseMessage ());
257 client.SendAsync (request).Wait (WaitTimeout);
259 request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
260 client.SendAsync (request).Wait (WaitTimeout);
264 [Test]
265 [Ignore]
266 #if FEATURE_NO_BSD_SOCKETS
267 // Using HttpClientHandler, which indirectly requires BSD sockets.
268 [ExpectedException (typeof (PlatformNotSupportedException))]
269 #endif
270 public void CancelRequestViaProxy ()
272 var handler = HttpClientTestHelpers.CreateHttpClientHandler ();
273 handler.Proxy = new WebProxy ("192.168.10.25:8888/"); // proxy that doesn't exist
274 handler.UseProxy = true;
275 handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
277 var httpClient = new HttpClient (handler) {
278 BaseAddress = new Uri ("https://www.example.com"),
279 Timeout = TimeSpan.FromMilliseconds (1)
282 try {
283 var restRequest = new HttpRequestMessage {
284 Method = HttpMethod.Post,
285 RequestUri = new Uri("foo", UriKind.Relative),
286 Content = new StringContent("", null, "application/json")
289 httpClient.PostAsync (restRequest.RequestUri, restRequest.Content).Wait (WaitTimeout);
290 Assert.Fail ("#1");
291 } catch (AggregateException e) {
292 Assert.That (e.InnerException, Is.InstanceOf<TaskCanceledException> (), $"#2: {e}");
296 [Test]
297 public void Properties ()
299 var client = new HttpClient ();
300 client.BaseAddress = null;
301 client.MaxResponseContentBufferSize = int.MaxValue;
302 client.Timeout = Timeout.InfiniteTimeSpan;
304 Assert.IsNull (client.BaseAddress, "#1");
305 Assert.AreEqual (int.MaxValue, client.MaxResponseContentBufferSize, "#2");
306 Assert.AreEqual (Timeout.InfiniteTimeSpan, client.Timeout, "#3");
309 [Test]
310 public void Properties_Invalid ()
312 var client = new HttpClient ();
313 try {
314 client.MaxResponseContentBufferSize = 0;
315 Assert.Fail ("#1");
316 } catch (ArgumentOutOfRangeException) {
319 try {
320 client.Timeout = TimeSpan.MinValue;
321 Assert.Fail ("#2");
322 } catch (ArgumentOutOfRangeException) {
325 try {
326 client.Timeout = TimeSpan.Zero;
327 Assert.Fail ("#3");
328 } catch (ArgumentOutOfRangeException) {
331 try {
332 client.Timeout = TimeSpan.FromMilliseconds (int.MaxValue + 1L);
333 Assert.Fail ("#3");
334 } catch (ArgumentOutOfRangeException) {
338 [Test]
339 #if FEATURE_NO_BSD_SOCKETS
340 [ExpectedException (typeof (PlatformNotSupportedException))]
341 #endif
342 public void Proxy_Disabled ()
344 var pp = WebRequest.DefaultWebProxy;
346 try {
347 WebRequest.DefaultWebProxy = new ThrowOnlyProxy ();
349 var request = HttpClientTestHelpers.CreateHttpClientHandler ();
350 request.UseProxy = false;
352 var client = new HttpClient (request);
353 Assert.IsTrue (client.GetAsync ("http://www.example.com").Wait (5000), "needs internet access");
354 } finally {
355 WebRequest.DefaultWebProxy = pp;
359 [Test]
360 public void Send ()
362 var mh = new HttpMessageHandlerMock ();
364 var client = new HttpClient (mh);
365 client.BaseAddress = new Uri ("http://www.example.com");
366 var request = new HttpRequestMessage ();
367 var response = new HttpResponseMessage ();
369 mh.OnSend = l => {
370 Assert.AreEqual (l, request, "#2");
371 Assert.AreEqual (client.BaseAddress, l.RequestUri, "#2");
372 return Task.FromResult (response);
375 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
378 [Test]
379 public void Send_BaseAddress ()
381 var mh = new HttpMessageHandlerMock ();
383 var client = new HttpClient (mh);
384 client.BaseAddress = new Uri ("http://localhost/");
385 var response = new HttpResponseMessage ();
387 mh.OnSend = l => {
388 Assert.AreEqual ("http://localhost/relative", l.RequestUri.ToString (), "#2");
389 return Task.FromResult (response);
392 Assert.AreEqual (response, client.GetAsync ("relative").Result, "#1");
393 Assert.AreEqual (response, client.GetAsync ("/relative").Result, "#2");
396 [Test]
397 public void Send_DefaultRequestHeaders ()
399 var mh = new HttpMessageHandlerMock ();
401 var client = new HttpClient (mh);
402 client.DefaultRequestHeaders.Referrer = new Uri ("http://www.example.com");
404 var request = new HttpRequestMessage (HttpMethod.Get, "http://www.example.org");
405 var response = new HttpResponseMessage ();
407 mh.OnSend = l => {
408 Assert.AreEqual (client.DefaultRequestHeaders.Referrer, l.Headers.Referrer, "#2");
409 Assert.IsNotNull (l.Headers.Referrer, "#3");
410 return Task.FromResult (response);
413 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
416 [Test]
417 #if FEATURE_NO_BSD_SOCKETS
418 [ExpectedException (typeof (PlatformNotSupportedException))]
419 #endif
420 public void Send_Complete_Default ()
422 bool? failed = null;
423 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Default/");
424 AddListenerContext (listener, l => {
425 try {
426 var request = l.Request;
428 Assert.IsNull (request.AcceptTypes, "#1");
429 Assert.AreEqual (0, request.ContentLength64, "#2");
430 Assert.IsNull (request.ContentType, "#3");
431 Assert.AreEqual (0, request.Cookies.Count, "#4");
432 Assert.IsFalse (request.HasEntityBody, "#5");
433 Assert.AreEqual ($"localhost:{port}", request.Headers["Host"], "#6b");
434 Assert.AreEqual ("GET", request.HttpMethod, "#7");
435 Assert.IsFalse (request.IsAuthenticated, "#8");
436 Assert.IsTrue (request.IsLocal, "#9");
437 Assert.IsFalse (request.IsSecureConnection, "#10");
438 Assert.IsFalse (request.IsWebSocketRequest, "#11");
439 Assert.IsTrue (request.KeepAlive, "#12");
440 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
441 Assert.IsNull (request.ServiceName, "#14");
442 Assert.IsNull (request.UrlReferrer, "#15");
443 Assert.IsNull (request.UserAgent, "#16");
444 Assert.IsNull (request.UserLanguages, "#17");
445 failed = false;
446 } catch {
447 failed = true;
451 try {
452 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
453 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Default/");
454 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
456 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
457 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
458 Assert.AreEqual (false, failed, "#102");
459 } finally {
460 listener.Close ();
464 [Test]
465 #if FEATURE_NO_BSD_SOCKETS
466 [ExpectedException (typeof (PlatformNotSupportedException))]
467 #endif
468 public void Send_Complete_Version_1_0 ()
470 bool? failed = null;
472 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Version_1_0/");
473 AddListenerContext (listener, l => {
474 try {
475 var request = l.Request;
477 Assert.IsNull (request.AcceptTypes, "#1");
478 Assert.AreEqual (0, request.ContentLength64, "#2");
479 Assert.IsNull (request.ContentType, "#3");
480 Assert.AreEqual (0, request.Cookies.Count, "#4");
481 Assert.IsFalse (request.HasEntityBody, "#5");
482 Assert.AreEqual (1, request.Headers.Count, "#6");
483 Assert.AreEqual ($"localhost:{port}", request.Headers["Host"], "#6a");
484 Assert.AreEqual ("GET", request.HttpMethod, "#7");
485 Assert.IsFalse (request.IsAuthenticated, "#8");
486 Assert.IsTrue (request.IsLocal, "#9");
487 Assert.IsFalse (request.IsSecureConnection, "#10");
488 Assert.IsFalse (request.IsWebSocketRequest, "#11");
489 Assert.IsFalse (request.KeepAlive, "#12");
490 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
491 Assert.IsNull (request.ServiceName, "#14");
492 Assert.IsNull (request.UrlReferrer, "#15");
493 Assert.IsNull (request.UserAgent, "#16");
494 Assert.IsNull (request.UserLanguages, "#17");
495 failed = false;
496 } catch {
497 failed = true;
501 try {
502 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
503 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Version_1_0/");
504 request.Version = HttpVersion.Version10;
505 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
507 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
508 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
509 Assert.AreEqual (false, failed, "#102");
510 } finally {
511 listener.Close ();
515 [Test]
516 #if FEATURE_NO_BSD_SOCKETS
517 [ExpectedException (typeof (PlatformNotSupportedException))]
518 #endif
519 public void Send_Complete_ClientHandlerSettings ()
521 bool? failed = null;
523 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_ClientHandlerSettings/");
524 AddListenerContext (listener, l => {
525 var request = l.Request;
527 try {
528 Assert.IsNull (request.AcceptTypes, "#1");
529 Assert.AreEqual (0, request.ContentLength64, "#2");
530 Assert.IsNull (request.ContentType, "#3");
531 Assert.AreEqual (1, request.Cookies.Count, "#4");
532 Assert.AreEqual (new Cookie ("mycookie", "vv"), request.Cookies[0], "#4a");
533 Assert.IsFalse (request.HasEntityBody, "#5");
534 Assert.AreEqual (4, request.Headers.Count, "#6");
535 Assert.AreEqual ($"localhost:{port}", request.Headers["Host"], "#6a");
536 Assert.AreEqual ("gzip", request.Headers["Accept-Encoding"], "#6b");
537 Assert.AreEqual ("mycookie=vv", request.Headers["Cookie"], "#6c");
538 Assert.AreEqual ("GET", request.HttpMethod, "#7");
539 Assert.IsFalse (request.IsAuthenticated, "#8");
540 Assert.IsTrue (request.IsLocal, "#9");
541 Assert.IsFalse (request.IsSecureConnection, "#10");
542 Assert.IsFalse (request.IsWebSocketRequest, "#11");
543 Assert.IsTrue (request.KeepAlive, "#12");
544 Assert.AreEqual (HttpVersion.Version10, request.ProtocolVersion, "#13");
545 Assert.IsNull (request.ServiceName, "#14");
546 Assert.IsNull (request.UrlReferrer, "#15");
547 Assert.IsNull (request.UserAgent, "#16");
548 Assert.IsNull (request.UserLanguages, "#17");
549 failed = false;
550 } catch {
551 failed = true;
555 try {
556 var chandler = HttpClientTestHelpers.CreateHttpClientHandler ();
557 chandler.AllowAutoRedirect = true;
558 chandler.AutomaticDecompression = DecompressionMethods.GZip;
559 chandler.MaxAutomaticRedirections = 33;
560 chandler.MaxRequestContentBufferSize = 5555;
561 chandler.PreAuthenticate = true;
562 chandler.CookieContainer.Add (new Uri ($"http://localhost:{port}/Send_Complete_ClientHandlerSettings/"), new Cookie ( "mycookie", "vv"));
563 chandler.UseCookies = true;
564 chandler.UseDefaultCredentials = true;
565 chandler.Proxy = new WebProxy ("ee");
566 chandler.UseProxy = true;
568 var client = new HttpClient (chandler);
569 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_ClientHandlerSettings/");
570 request.Version = HttpVersion.Version10;
571 request.Headers.Add ("Keep-Alive", "false");
572 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
574 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
575 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
576 Assert.AreEqual (false, failed, "#102");
577 } finally {
578 listener.Abort ();
579 listener.Close ();
583 [Test]
584 #if FEATURE_NO_BSD_SOCKETS
585 [ExpectedException (typeof (PlatformNotSupportedException))]
586 #endif
587 public void Send_Complete_CustomHeaders ()
589 bool? failed = null;
591 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_CustomHeaders/");
592 AddListenerContext (listener, l => {
593 var request = l.Request;
594 try {
595 Assert.AreEqual ("vv", request.Headers["aa"], "#1");
597 var response = l.Response;
598 response.Headers.Add ("rsp", "rrr");
599 response.Headers.Add ("upgrade", "vvvvaa");
600 response.Headers.Add ("Date", "aa");
601 response.Headers.Add ("cache-control", "audio");
603 response.StatusDescription = "test description";
604 response.ProtocolVersion = HttpVersion.Version10;
605 response.SendChunked = true;
606 response.RedirectLocation = "w3.org";
608 failed = false;
609 } catch {
610 failed = true;
614 try {
615 var handler = HttpClientTestHelpers.CreateHttpClientHandler ();
616 var client = new HttpClient (handler);
617 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_CustomHeaders/");
618 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
619 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
621 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
622 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
624 IEnumerable<string> values;
625 Assert.IsTrue (response.Headers.TryGetValues ("rsp", out values), "#102");
626 Assert.AreEqual ("rrr", values.First (), "#102a");
628 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#103");
629 Assert.AreEqual ("chunked", values.First (), "#103a");
630 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#103b");
632 Assert.IsTrue (response.Headers.TryGetValues ("Date", out values), "#104");
633 Assert.AreEqual (1, values.Count (), "#104b");
634 // .NET overwrites Date, Mono does not
635 // Assert.IsNotNull (response.Headers.Date, "#104c");
637 Assert.AreEqual (new ProductHeaderValue ("vvvvaa"), response.Headers.Upgrade.First (), "#105");
639 Assert.AreEqual ("audio", response.Headers.CacheControl.Extensions.First ().Name, "#106");
641 Assert.AreEqual ("w3.org", response.Headers.Location.OriginalString, "#107");
643 Assert.AreEqual ("test description", response.ReasonPhrase, "#110");
644 if (HttpClientTestHelpers.IsSocketsHandler (handler))
645 Assert.AreEqual (HttpVersion.Version10, response.Version, "#111");
646 else
647 Assert.AreEqual (HttpVersion.Version11, response.Version, "#111");
649 Assert.AreEqual (false, failed, "#112");
650 } finally {
651 listener.Close ();
655 [Test]
656 #if FEATURE_NO_BSD_SOCKETS
657 [ExpectedException (typeof (PlatformNotSupportedException))]
658 #endif
659 public void Send_Complete_CustomHeaders_SpecialSeparators ()
661 bool? failed = null;
663 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_CustomHeaders_SpecialSeparators/");
664 AddListenerContext (listener, l => {
665 var request = l.Request;
667 try {
668 Assert.AreEqual ("MLK Android Phone 1.1.9", request.UserAgent, "#1");
669 failed = false;
670 } catch {
671 failed = true;
675 try {
676 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
678 client.DefaultRequestHeaders.Add("User-Agent", "MLK Android Phone 1.1.9");
680 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_CustomHeaders_SpecialSeparators/");
682 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
684 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
685 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
686 Assert.AreEqual (false, failed, "#102");
687 } finally {
688 listener.Abort ();
689 listener.Close ();
693 [Test]
694 #if FEATURE_NO_BSD_SOCKETS
695 [ExpectedException (typeof (PlatformNotSupportedException))]
696 #endif
697 public void Send_Complete_CustomHeaders_Host ()
699 Exception error = null;
700 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_CustomHeaders_Host/");
701 AddListenerContext (listener, l => {
702 var request = l.Request;
704 try {
705 Assert.AreEqual ("customhost", request.Headers["Host"], "#1");
706 } catch (Exception ex) {
707 error = ex;
711 try {
712 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
714 client.DefaultRequestHeaders.Add("Host", "customhost");
716 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_CustomHeaders_Host/");
718 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
720 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
721 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
722 Assert.IsNull (error, "#102");
723 } finally {
724 listener.Abort ();
725 listener.Close ();
729 [Test]
730 #if FEATURE_NO_BSD_SOCKETS
731 [ExpectedException (typeof (PlatformNotSupportedException))]
732 #endif
733 public void Send_Transfer_Encoding_Chunked_Needs_Content ()
735 if (!HttpClientTestHelpers.UsingSocketsHandler)
736 Assert.Ignore ("Requires SocketsHttpHandler");
738 bool? failed = null;
740 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Transfer_Encoding_Chunked_Needs_Content/");
741 AddListenerContext (listener, l => {
742 failed = true;
745 try {
746 try {
747 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
748 client.DefaultRequestHeaders.TransferEncodingChunked = true;
749 client.GetAsync ($"http://localhost:{port}/Send_Transfer_Encoding_Chunked_Needs_Content/").Wait ();
750 // fails with
751 // 'Transfer-Encoding: chunked' header can not be used when content object is not specified.
752 } catch (AggregateException e) {
753 Assert.AreEqual (typeof (HttpRequestException), e.InnerException.GetType (), "#2");
755 Assert.IsNull (failed, "#102");
756 } finally {
757 listener.Abort ();
758 listener.Close ();
762 [Test]
763 #if FEATURE_NO_BSD_SOCKETS
764 [ExpectedException (typeof (PlatformNotSupportedException))]
765 #endif
766 public void Send_Transfer_Encoding_Chunked ()
768 if (HttpClientTestHelpers.UsingSocketsHandler)
769 Assert.Ignore ("Requires LegacyHttpClient");
771 bool? failed = null;
773 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Transfer_Encoding_Chunked/");
774 AddListenerContext (listener, l => {
775 var request = l.Request;
777 try {
778 Assert.AreEqual (2, request.Headers.Count, "#1");
779 Assert.AreEqual ("keep-alive", request.Headers ["Connection"], "#2");
780 failed = false;
781 } catch (Exception ex){
782 Console.WriteLine (ex);
783 Console.WriteLine (String.Join ("#", l.Request.Headers.AllKeys));
784 failed = true;
788 try {
789 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
790 client.DefaultRequestHeaders.TransferEncodingChunked = true;
792 client.GetAsync ($"http://localhost:{port}/Send_Transfer_Encoding_Chunked/").Wait ();
794 Assert.AreEqual (false, failed, "#102");
795 } finally {
796 listener.Abort ();
797 listener.Close ();
801 [Test]
802 #if FEATURE_NO_BSD_SOCKETS
803 [ExpectedException (typeof (PlatformNotSupportedException))]
804 #endif
805 public void Send_Complete_Content ()
807 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Content/");
808 AddListenerContext (listener, l => {
809 var request = l.Request;
810 l.Response.OutputStream.WriteByte (55);
811 l.Response.OutputStream.WriteByte (75);
814 try {
815 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
816 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Content/");
817 Assert.IsTrue (request.Headers.TryAddWithoutValidation ("aa", "vv"), "#0");
818 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
820 Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
821 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
823 IEnumerable<string> values;
824 Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
825 Assert.AreEqual ("chunked", values.First (), "#102a");
826 Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
827 } finally {
828 listener.Close ();
832 [Test]
833 #if FEATURE_NO_BSD_SOCKETS
834 [ExpectedException (typeof (PlatformNotSupportedException))]
835 #endif
836 public void Send_Complete_Content_MaxResponseContentBufferSize ()
838 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Content_MaxResponseContentBufferSize/");
839 AddListenerContext (listener, l => {
840 var request = l.Request;
841 var b = new byte[4000];
842 l.Response.OutputStream.Write (b, 0, b.Length);
845 try {
846 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
847 client.MaxResponseContentBufferSize = 1000;
848 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Content_MaxResponseContentBufferSize/");
849 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
851 Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
852 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
853 } finally {
854 listener.Close ();
858 [Test]
859 #if FEATURE_NO_BSD_SOCKETS
860 [ExpectedException (typeof (PlatformNotSupportedException))]
861 #endif
862 public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
864 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Content_MaxResponseContentBufferSize_Error/");
865 AddListenerContext (listener, l => {
866 var request = l.Request;
867 var b = new byte[4000];
868 l.Response.OutputStream.Write (b, 0, b.Length);
871 try {
872 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
873 client.MaxResponseContentBufferSize = 1000;
874 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Content_MaxResponseContentBufferSize_Error/");
876 try {
877 client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait (WaitTimeout);
878 Assert.Fail ("#2");
879 } catch (AggregateException e) {
880 Assert.That (e.InnerException, Is.InstanceOf<HttpRequestException> (), $"#3: {e}");
883 } finally {
884 listener.Close ();
888 [Test]
889 #if FEATURE_NO_BSD_SOCKETS
890 [ExpectedException (typeof (PlatformNotSupportedException))]
891 #endif
892 public void Send_Complete_NoContent_Post ()
894 Send_Complete_NoContent (HttpMethod.Post);
897 [Test]
898 #if FEATURE_NO_BSD_SOCKETS
899 [ExpectedException (typeof (PlatformNotSupportedException))]
900 #endif
901 public void Send_Complete_NoContent_Put ()
903 Send_Complete_NoContent (HttpMethod.Put);
906 [Test]
907 #if FEATURE_NO_BSD_SOCKETS
908 [ExpectedException (typeof (PlatformNotSupportedException))]
909 #endif
910 public void Send_Complete_NoContent_Delete ()
912 Send_Complete_NoContent (HttpMethod.Delete);
915 void Send_Complete_NoContent (HttpMethod method)
917 bool? failed = null;
918 var handler = HttpClientTestHelpers.CreateHttpClientHandler ();
919 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_NoContent/");
920 AddListenerContext (listener, l => {
921 try {
922 var request = l.Request;
924 if (HttpClientTestHelpers.IsSocketsHandler (handler)) {
925 Assert.AreEqual (2, request.Headers.Count, "#1");
926 Assert.IsNull (request.Headers["Connection"], "#1c");
927 } else {
928 Assert.AreEqual (3, request.Headers.Count, "#1");
929 Assert.AreEqual ("keep-alive", request.Headers["Connection"], "#1c");
931 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b");
932 Assert.AreEqual (method.Method, request.HttpMethod, "#2");
933 failed = false;
934 } catch (Exception ex){
935 Console.WriteLine (ex);
936 Console.WriteLine (String.Join ("#", l.Request.Headers.AllKeys));
938 failed = true;
942 try {
943 var client = new HttpClient (handler);
944 var request = new HttpRequestMessage (method, $"http://localhost:{port}/Send_Complete_NoContent/");
945 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
947 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
948 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
949 Assert.AreEqual (false, failed, "#102");
950 } finally {
951 listener.Close ();
955 [Test]
956 #if FEATURE_NO_BSD_SOCKETS
957 [ExpectedException (typeof (PlatformNotSupportedException))]
958 #endif
959 public void Send_Complete_Error ()
961 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Complete_Error/");
962 AddListenerContext (listener, l => {
963 var response = l.Response;
964 response.StatusCode = 500;
967 try {
968 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
969 var request = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Complete_Error/");
970 var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
972 Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
973 Assert.AreEqual (HttpStatusCode.InternalServerError, response.StatusCode, "#101");
974 } finally {
975 listener.Close ();
979 [Test]
980 #if FEATURE_NO_BSD_SOCKETS
981 [ExpectedException (typeof (PlatformNotSupportedException))]
982 #endif
983 public void Send_Content_Get ()
985 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Content_Get/");
986 AddListenerContext (listener, l => {
987 var request = l.Request;
988 l.Response.OutputStream.WriteByte (72);
991 try {
992 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
993 var r = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Content_Get/");
994 var response = client.SendAsync (r).Result;
996 Assert.AreEqual ("H", response.Content.ReadAsStringAsync ().Result);
997 } finally {
998 listener.Close ();
1002 [Test]
1003 #if FEATURE_NO_BSD_SOCKETS
1004 [ExpectedException (typeof (PlatformNotSupportedException))]
1005 #endif
1006 public void Send_Content_BomEncoding ()
1008 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Content_BomEncoding/");
1009 AddListenerContext (listener, l => {
1010 var request = l.Request;
1012 var str = l.Response.OutputStream;
1013 str.WriteByte (0xEF);
1014 str.WriteByte (0xBB);
1015 str.WriteByte (0xBF);
1016 str.WriteByte (71);
1019 try {
1020 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1021 var r = new HttpRequestMessage (HttpMethod.Get, $"http://localhost:{port}/Send_Content_BomEncoding/");
1022 var response = client.SendAsync (r).Result;
1024 Assert.AreEqual ("G", response.Content.ReadAsStringAsync ().Result);
1025 } finally {
1026 listener.Close ();
1030 [Test]
1031 #if FEATURE_NO_BSD_SOCKETS
1032 [ExpectedException (typeof (PlatformNotSupportedException))]
1033 #endif
1034 public void Send_Content_Put ()
1036 bool passed = false;
1037 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Content_Put/");
1038 AddListenerContext (listener, l => {
1039 var request = l.Request;
1040 passed = 7 == request.ContentLength64;
1041 passed &= request.ContentType == "text/plain; charset=utf-8";
1042 passed &= request.InputStream.ReadByte () == 'm';
1045 try {
1046 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1047 var r = new HttpRequestMessage (HttpMethod.Put, $"http://localhost:{port}/Send_Content_Put/");
1048 r.Content = new StringContent ("my text");
1049 var response = client.SendAsync (r).Result;
1051 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
1052 Assert.IsTrue (passed, "#2");
1053 } finally {
1054 listener.Abort ();
1055 listener.Close ();
1059 [Test]
1060 #if FEATURE_NO_BSD_SOCKETS
1061 [ExpectedException (typeof (PlatformNotSupportedException))]
1062 #endif
1063 public void Send_Content_Put_CustomStream ()
1065 bool passed = false;
1066 var handler = HttpClientTestHelpers.CreateHttpClientHandler ();
1067 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Send_Content_Put_CustomStream/");
1068 AddListenerContext (listener, l => {
1069 var request = l.Request;
1070 if (HttpClientTestHelpers.IsSocketsHandler (handler))
1071 passed = -1 == request.ContentLength64;
1072 else
1073 passed = 44 == request.ContentLength64;
1074 passed &= request.ContentType == null;
1077 try {
1078 var client = new HttpClient (handler);
1079 var r = new HttpRequestMessage (HttpMethod.Put, $"http://localhost:{port}/Send_Content_Put_CustomStream/");
1080 r.Content = new StreamContent (new CustomStream ());
1081 var response = client.SendAsync (r).Result;
1083 Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1");
1084 Assert.IsTrue (passed, "#2");
1085 } finally {
1086 listener.Abort ();
1088 listener.Close ();
1092 [Test]
1093 public void Send_Timeout ()
1095 var mh = new HttpMessageHandlerMock ();
1097 var client = new HttpClient (mh);
1098 client.Timeout = TimeSpan.FromMilliseconds (100);
1099 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
1100 var response = new HttpResponseMessage ();
1102 mh.OnSendFull = (l, c) => {
1103 Assert.IsTrue (c.WaitHandle.WaitOne (500), "#2");
1104 return Task.FromResult (response);
1107 Assert.AreEqual (response, client.SendAsync (request).Result, "#1");
1110 [Test]
1111 #if FEATURE_NO_BSD_SOCKETS
1112 [ExpectedException (typeof (PlatformNotSupportedException))]
1113 #endif
1114 public void Send_Invalid ()
1116 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1117 try {
1118 client.SendAsync (null).Wait (WaitTimeout);
1119 Assert.Fail ("#1");
1120 } catch (ArgumentNullException) {
1123 try {
1124 var request = new HttpRequestMessage ();
1125 client.SendAsync (request).Wait (WaitTimeout);
1126 Assert.Fail ("#2");
1127 } catch (InvalidOperationException) {
1131 [Test]
1132 public void Send_InvalidHandler ()
1134 var mh = new HttpMessageHandlerMock ();
1136 var client = new HttpClient (mh);
1137 client.BaseAddress = new Uri ("http://xamarin.com");
1138 var request = new HttpRequestMessage ();
1140 mh.OnSend = l => {
1141 Assert.AreEqual (l, request, "#1");
1142 return null;
1145 try {
1146 // Broken by design
1147 client.SendAsync (request).Wait (WaitTimeout);
1148 Assert.Fail ("#2");
1149 } catch (Exception) {
1153 [Test]
1154 public void Send_SameMessage ()
1156 var mh = new HttpMessageHandlerMock ();
1158 var client = new HttpClient (mh);
1159 var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com");
1161 mh.OnSend = l => Task.FromResult (new HttpResponseMessage ());
1163 client.SendAsync (request).Wait (WaitTimeout);
1164 try {
1165 client.SendAsync (request).Wait (WaitTimeout);
1166 Assert.Fail ("#1");
1167 } catch (InvalidOperationException) {
1171 [Test]
1172 #if FEATURE_NO_BSD_SOCKETS
1173 [ExpectedException (typeof (PlatformNotSupportedException))]
1174 #endif
1175 public void Post_TransferEncodingChunked ()
1177 bool? failed = null;
1178 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Post_TransferEncodingChunked/");
1179 AddListenerContext (listener, l => {
1180 try {
1181 var request = l.Request;
1183 Assert.IsNull (request.AcceptTypes, "#1");
1184 Assert.AreEqual (-1, request.ContentLength64, "#2");
1185 Assert.IsNull (request.ContentType, "#3");
1186 Assert.AreEqual (0, request.Cookies.Count, "#4");
1187 Assert.IsTrue (request.HasEntityBody, "#5");
1188 Assert.AreEqual ($"localhost:{port}", request.Headers ["Host"], "#6b");
1189 Assert.AreEqual ("POST", request.HttpMethod, "#7");
1190 Assert.IsFalse (request.IsAuthenticated, "#8");
1191 Assert.IsTrue (request.IsLocal, "#9");
1192 Assert.IsFalse (request.IsSecureConnection, "#10");
1193 Assert.IsFalse (request.IsWebSocketRequest, "#11");
1194 Assert.IsTrue (request.KeepAlive, "#12");
1195 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
1196 Assert.IsNull (request.ServiceName, "#14");
1197 Assert.IsNull (request.UrlReferrer, "#15");
1198 Assert.IsNull (request.UserAgent, "#16");
1199 Assert.IsNull (request.UserLanguages, "#17");
1200 Assert.AreEqual ("chunked", request.Headers ["Transfer-Encoding"], "#18");
1201 Assert.IsNull (request.Headers ["Content-Length"], "#19");
1202 failed = false;
1203 } catch (Exception e) {
1204 failed = true;
1205 Console.WriteLine (e);
1209 try {
1210 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1212 client.DefaultRequestHeaders.TransferEncodingChunked = true;
1214 var imageContent = new StreamContent (new MemoryStream ());
1216 var response = client.PostAsync ($"http://localhost:{port}/Post_TransferEncodingChunked/", imageContent).Result;
1218 Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101");
1219 Assert.AreEqual(false, failed, "#102");
1220 } finally {
1221 listener.Close ();
1225 [Test]
1226 #if FEATURE_NO_BSD_SOCKETS
1227 [ExpectedException (typeof (PlatformNotSupportedException))]
1228 #endif
1229 public void Post_StreamCaching ()
1231 bool? failed = null;
1232 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/Post_StreamCaching/");
1233 AddListenerContext (listener, l => {
1234 try {
1235 var request = l.Request;
1237 Assert.IsNull (request.AcceptTypes, "#1");
1238 Assert.AreEqual (0, request.ContentLength64, "#2");
1239 Assert.IsNull (request.ContentType, "#3");
1240 Assert.AreEqual (0, request.Cookies.Count, "#4");
1241 Assert.IsFalse (request.HasEntityBody, "#5");
1242 Assert.AreEqual ($"localhost:{port}", request.Headers ["Host"], "#6b");
1243 Assert.AreEqual ("POST", request.HttpMethod, "#7");
1244 Assert.IsFalse (request.IsAuthenticated, "#8");
1245 Assert.IsTrue (request.IsLocal, "#9");
1246 Assert.IsFalse (request.IsSecureConnection, "#10");
1247 Assert.IsFalse (request.IsWebSocketRequest, "#11");
1248 Assert.IsTrue (request.KeepAlive, "#12");
1249 Assert.AreEqual (HttpVersion.Version11, request.ProtocolVersion, "#13");
1250 Assert.IsNull (request.ServiceName, "#14");
1251 Assert.IsNull (request.UrlReferrer, "#15");
1252 Assert.IsNull (request.UserAgent, "#16");
1253 Assert.IsNull (request.UserLanguages, "#17");
1254 Assert.IsNull (request.Headers ["Transfer-Encoding"], "#18");
1255 Assert.AreEqual ("0", request.Headers ["Content-Length"], "#19");
1256 failed = false;
1257 } catch (Exception e) {
1258 failed = true;
1259 Console.WriteLine (e);
1263 try {
1264 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1266 var imageContent = new StreamContent (new MemoryStream ());
1268 var response = client.PostAsync ($"http://localhost:{port}/Post_StreamCaching/", imageContent).Result;
1270 Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "#101");
1271 Assert.AreEqual(false, failed, "#102");
1272 } finally {
1273 listener.Close ();
1277 [Test]
1278 [Category ("MobileNotWorking")] // Missing encoding
1279 #if FEATURE_NO_BSD_SOCKETS
1280 [ExpectedException (typeof (PlatformNotSupportedException))]
1281 #endif
1282 public void GetString_Many ()
1284 Action<HttpListenerContext> context = (HttpListenerContext l) => {
1285 var response = l.Response;
1286 response.StatusCode = 200;
1287 response.OutputStream.WriteByte (0x68);
1288 response.OutputStream.WriteByte (0x65);
1289 response.OutputStream.WriteByte (0x6c);
1290 response.OutputStream.WriteByte (0x6c);
1291 response.OutputStream.WriteByte (0x6f);
1294 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/GetString_Many/");
1295 AddListenerContext (listener, context); // creates a default request handler
1296 AddListenerContext (listener, context); // add another request handler for the second request
1298 try {
1299 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1300 var t1 = client.GetStringAsync ($"http://localhost:{port}/GetString_Many/");
1301 var t2 = client.GetStringAsync ($"http://localhost:{port}/GetString_Many/");
1302 Assert.IsTrue (Task.WaitAll (new [] { t1, t2 }, WaitTimeout));
1303 Assert.AreEqual ("hello", t1.Result, "#1");
1304 Assert.AreEqual ("hello", t2.Result, "#2");
1305 } finally {
1306 listener.Abort ();
1307 listener.Close ();
1311 [Test]
1312 #if FEATURE_NO_BSD_SOCKETS
1313 [ExpectedException (typeof (PlatformNotSupportedException))]
1314 #endif
1315 public void GetByteArray_ServerError ()
1317 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/GetByteArray_ServerError/");
1318 AddListenerContext (listener, l => {
1319 var response = l.Response;
1320 response.StatusCode = 500;
1321 l.Response.OutputStream.WriteByte (72);
1324 try {
1325 var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ();
1326 try {
1327 client.GetByteArrayAsync ($"http://localhost:{port}/GetByteArray_ServerError/").Wait (WaitTimeout);
1328 Assert.Fail ("#1");
1329 } catch (AggregateException e) {
1330 Assert.That (e.InnerException, Is.InstanceOf<HttpRequestException> (), $"#2: {e}");
1332 } finally {
1333 listener.Close ();
1337 [Test]
1338 #if FEATURE_NO_BSD_SOCKETS
1339 [ExpectedException (typeof (PlatformNotSupportedException))]
1340 #endif
1341 public void DisallowAutoRedirect ()
1343 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/DisallowAutoRedirect/");
1344 AddListenerContext (listener, l => {
1345 var request = l.Request;
1346 var response = l.Response;
1348 response.StatusCode = (int)HttpStatusCode.Moved;
1349 response.RedirectLocation = "http://xamarin.com/";
1352 try {
1353 var chandler = HttpClientTestHelpers.CreateHttpClientHandler ();
1354 chandler.AllowAutoRedirect = false;
1355 var client = new HttpClient (chandler);
1357 try {
1358 client.GetStringAsync ($"http://localhost:{port}/DisallowAutoRedirect/").Wait (WaitTimeout);
1359 Assert.Fail ("#1");
1360 } catch (AggregateException e) {
1361 Assert.That (e.InnerException, Is.InstanceOf<HttpRequestException> (), $"#2: {e}");
1363 } finally {
1364 listener.Abort ();
1365 listener.Close ();
1369 [Test]
1370 #if FEATURE_NO_BSD_SOCKETS
1371 [ExpectedException (typeof (PlatformNotSupportedException))]
1372 #endif
1373 public void RequestUriAfterRedirect ()
1375 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/RequestUriAfterRedirect/");
1376 var listener2 = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int redirectPort, "/RequestUriAfterRedirect/");
1378 AddListenerContext (listener, l => {
1379 var request = l.Request;
1380 var response = l.Response;
1382 response.StatusCode = (int)HttpStatusCode.Moved;
1383 response.RedirectLocation = $"http://localhost:{redirectPort}/RequestUriAfterRedirect/";
1386 AddListenerContext (listener2, l => {
1387 var response = l.Response;
1389 response.StatusCode = (int)HttpStatusCode.OK;
1390 response.OutputStream.WriteByte (0x68);
1391 response.OutputStream.WriteByte (0x65);
1392 response.OutputStream.WriteByte (0x6c);
1393 response.OutputStream.WriteByte (0x6c);
1394 response.OutputStream.WriteByte (0x6f);
1397 try {
1398 var chandler = HttpClientTestHelpers.CreateHttpClientHandler ();
1399 chandler.AllowAutoRedirect = true;
1400 var client = new HttpClient (chandler);
1402 var r = client.GetAsync ($"http://localhost:{port}/RequestUriAfterRedirect/");
1403 Assert.IsTrue (r.Wait (WaitTimeout), "#1");
1404 var resp = r.Result;
1405 Assert.AreEqual ($"http://localhost:{redirectPort}/RequestUriAfterRedirect/", resp.RequestMessage.RequestUri.AbsoluteUri, "#2");
1406 Assert.AreEqual ("hello", resp.Content.ReadAsStringAsync ().Result, "#3");
1407 } finally {
1408 listener.Abort ();
1409 listener.Close ();
1410 listener2.Abort ();
1411 listener2.Close ();
1415 [Test]
1416 #if FEATURE_NO_BSD_SOCKETS
1417 [ExpectedException (typeof (PlatformNotSupportedException))]
1418 #endif
1420 * Properties may only be modified before sending the first request.
1422 public void ModifyHandlerAfterFirstRequest ()
1424 var chandler = HttpClientTestHelpers.CreateHttpClientHandler ();
1425 chandler.AllowAutoRedirect = true;
1426 var client = new HttpClient (chandler, true);
1428 var listener = NetworkHelpers.CreateAndStartHttpListener("http://*:", out int port, "/ModifyHandlerAfterFirstRequest/");
1429 AddListenerContext (listener, l => {
1430 var response = l.Response;
1431 response.StatusCode = 200;
1432 response.OutputStream.WriteByte (55);
1435 try {
1436 client.GetStringAsync ($"http://localhost:{port}/ModifyHandlerAfterFirstRequest/").Wait (WaitTimeout);
1437 try {
1438 chandler.AllowAutoRedirect = false;
1439 Assert.Fail ("#1");
1440 } catch (InvalidOperationException) {
1443 } finally {
1444 listener.Abort ();
1445 listener.Close ();
1449 [Test]
1450 #if FEATURE_NO_BSD_SOCKETS
1451 // Using HttpClientHandler, which indirectly requires BSD sockets.
1452 [ExpectedException (typeof (PlatformNotSupportedException))]
1453 #endif
1455 * However, this policy is not enforced for custom handlers and there
1456 * is also no way a derived class could tell its HttpClientHandler parent
1457 * that it just sent a request.
1460 public void ModifyHandlerAfterFirstRequest_Mock ()
1462 var ch = new HttpClientHandlerMock ();
1463 ch.AllowAutoRedirect = true;
1465 var client = new HttpClient (ch);
1467 ch.OnSend = (l) => {
1468 return Task.FromResult (new HttpResponseMessage ());
1471 client.GetAsync ("http://xamarin.com").Wait (WaitTimeout);
1472 ch.AllowAutoRedirect = false;
1475 #if !FEATURE_NO_BSD_SOCKETS
1476 [Test]
1477 // https://github.com/mono/mono/issues/7355
1478 public void WildcardConnect ()
1480 if (HttpClientTestHelpers.UsingSocketsHandler)
1481 Assert.Ignore ("Throws System.NullReferenceException");
1483 try {
1484 using (var client = HttpClientTestHelpers.CreateHttpClientWithHttpClientHandler ()) {
1485 client.GetAsync ("http://255.255.255.255").Wait (WaitTimeout);
1487 } catch (AggregateException e) {
1488 Assert.That (e.InnerException, Is.InstanceOf<HttpRequestException> (), "#1");
1489 var rex = (HttpRequestException)e.InnerException;
1490 Assert.That (rex.InnerException, Is.InstanceOf<WebException> (), "#2");
1491 var wex = (WebException)rex.InnerException;
1492 Assert.That (wex.Status, Is.EqualTo (WebExceptionStatus.ConnectFailure), "#3");
1495 #endif
1497 void AddListenerContext (HttpListener l, Action<HttpListenerContext> contextAssert)
1499 l.BeginGetContext (ar => {
1500 var ctx = l.EndGetContext (ar);
1502 try {
1503 if (contextAssert != null)
1504 contextAssert (ctx);
1505 } finally {
1506 ctx.Response.Close ();
1508 }, null);