System.Net.Http/ByteArrayContent.cs
System.Net.Http/ClientCertificateOption.cs
System.Net.Http/DelegatingHandler.cs
+System.Net.Http/FormUrlEncodedContent.cs
System.Net.Http/HttpClient.cs
System.Net.Http/HttpClientHandler.cs
System.Net.Http/HttpCompletionOption.cs
System.Net.Http/HttpRequestException.cs
System.Net.Http/HttpRequestMessage.cs
System.Net.Http/HttpResponseMessage.cs
+System.Net.Http/MessageProcessingHandler.cs
System.Net.Http/StreamContent.cs
System.Net.Http/StringContent.cs
System.Net.Http.Headers/AuthenticationHeaderValue.cs
this.count = count;
}
+ protected override Task<Stream> CreateContentReadStreamAsync ()
+ {
+ return Task.FromResult<Stream> (new MemoryStream (content, offset, count));
+ }
+
protected override Task SerializeToStreamAsync (Stream stream, TransportContext context)
{
return stream.WriteAsync (content, offset, count);
protected internal override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
{
- throw new NotImplementedException ();
+ return InnerHandler.SendAsync (request, cancellationToken);
}
}
}
--- /dev/null
+//
+// FormUrlEncodedContent.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections.Generic;
+using System.Net.Http.Headers;
+using System.Text;
+
+namespace System.Net.Http
+{
+ public class FormUrlEncodedContent : ByteArrayContent
+ {
+ public FormUrlEncodedContent (IEnumerable<KeyValuePair<string, string>> nameValueCollection)
+ : base (EncodeContent (nameValueCollection))
+ {
+ Headers.ContentType = new MediaTypeHeaderValue ("application/x-www-form-urlencoded");
+ }
+
+ static byte[] EncodeContent (IEnumerable<KeyValuePair<string, string>> nameValueCollection)
+ {
+ if (nameValueCollection == null)
+ throw new ArgumentNullException ("nameValueCollection");
+
+ //
+ // Serialization as application/x-www-form-urlencoded
+ //
+ // Element nodes selected for inclusion are encoded as EltName=value{sep}, where = is a literal
+ // character, {sep} is the separator character from the separator attribute on submission,
+ // EltName represents the element local name, and value represents the contents of the text node.
+ //
+ // The encoding of EltName and value are as follows: space characters are replaced by +, and then
+ // non-ASCII and reserved characters (as defined by [RFC 2396] as amended by subsequent documents
+ // in the IETF track) are escaped by replacing the character with one or more octets of the UTF-8
+ // representation of the character, with each octet in turn replaced by %HH, where HH represents
+ // the uppercase hexadecimal notation for the octet value and % is a literal character. Line breaks
+ // are represented as "CR LF" pairs (i.e., %0D%0A).
+ //
+ var sb = new List<byte> ();
+ foreach (var item in nameValueCollection) {
+ if (sb.Count != 0)
+ sb.Add ((byte) '&');
+
+ var data = SerializeValue (item.Key);
+ if (data != null)
+ sb.AddRange (data);
+ sb.Add ((byte) '=');
+
+ data = SerializeValue (item.Value);
+ if (data != null)
+ sb.AddRange (data);
+ }
+
+ return sb.ToArray ();
+ }
+
+ static byte[] SerializeValue (string value)
+ {
+ if (value == null)
+ return null;
+
+ value = Uri.EscapeDataString (value).Replace ("%20", "+");
+ return Encoding.ASCII.GetBytes (value);
+ }
+ }
+}
using System.Threading;
using System.Net.Http.Headers;
using System.Threading.Tasks;
+using System.IO;
namespace System.Net.Http
{
cancellation_token = null;
}
}
+
+ public async Task<byte[]> GetByteArrayAsync (string requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsByteArrayAsync ();
+ }
+
+ public async Task<byte[]> GetByteArrayAsync (Uri requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsByteArrayAsync ();
+ }
+
+ public async Task<Stream> GetStreamAsync (string requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsStreamAsync ();
+ }
+
+ public async Task<Stream> GetStreamAsync (Uri requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsStreamAsync ();
+ }
+
+ public async Task<string> GetStringAsync (string requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsStringAsync ();
+ }
+
+ public async Task<string> GetStringAsync (Uri requestUri)
+ {
+ var resp = await GetAsync (requestUri, HttpCompletionOption.ResponseContentRead).ConfigureAwait (false);
+ return await resp.Content.ReadAsStringAsync ();
+ }
}
}
bool useCookies;
bool useDefaultCredentials;
bool useProxy;
+ ClientCertificateOption certificate;
public HttpClientHandler ()
{
}
}
+ public ClientCertificateOption ClientCertificateOptions {
+ get {
+ return certificate;
+ }
+ set {
+ certificate = value;
+ }
+ }
+
public CookieContainer CookieContainer {
get {
return cookieContainer ?? (cookieContainer = new CookieContainer ());
return proxy;
}
set {
+ if (!UseProxy)
+ throw new InvalidOperationException ();
+
proxy = value;
}
}
public abstract class HttpContent : IDisposable
{
MemoryStream buffer;
+ Stream stream;
bool disposed;
HttpContentHeaders headers;
return SerializeToStreamAsync (stream, context);
}
+ protected async virtual Task<Stream> CreateContentReadStreamAsync ()
+ {
+ await LoadIntoBufferAsync ();
+ return buffer;
+ }
+
public void Dispose ()
{
Dispose (true);
buffer.Seek (0, SeekOrigin.Begin);
}
- public Task<Stream> ReadAsStreamAsync ()
+ public async Task<Stream> ReadAsStreamAsync ()
{
- // TODO:
- throw new NotImplementedException ();
+ if (disposed)
+ throw new ObjectDisposedException (GetType ().ToString ());
+
+ if (stream == null)
+ stream = await CreateContentReadStreamAsync ().ConfigureAwait (false);
+
+ return stream;
}
public async Task<byte[]> ReadAsByteArrayAsync ()
--- /dev/null
+//
+// MessageProcessingHandler.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Net.Http
+{
+ public abstract class MessageProcessingHandler : DelegatingHandler
+ {
+ protected MessageProcessingHandler ()
+ {
+ }
+
+ protected MessageProcessingHandler (HttpMessageHandler innerHandler)
+ : base (innerHandler)
+ {
+ }
+
+ protected abstract HttpRequestMessage ProcessRequest (HttpRequestMessage request, CancellationToken cancellationToken);
+ protected abstract HttpResponseMessage ProcessResponse (HttpResponseMessage response, CancellationToken cancellationToken);
+
+ protected internal sealed override async Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ request = ProcessRequest (request, cancellationToken);
+ return ProcessResponse (await base.SendAsync (request, cancellationToken).ConfigureAwait (false), cancellationToken);
+ }
+ }
+}
this.bufferSize = bufferSize;
}
+ protected override Task<Stream> CreateContentReadStreamAsync ()
+ {
+ return Task.FromResult (content);
+ }
+
protected override void Dispose (bool disposing)
{
if (disposing) {
System.Net.Http/ByteArrayContentTest.cs
+System.Net.Http/FormUrlEncodedContentTest.cs
System.Net.Http/HttpClientHandlerTest.cs
System.Net.Http/HttpClientTest.cs
System.Net.Http/HttpMethodTest.cs
[TestFixture]
public class HttpClientHandlerTest
{
+ class Proxy : IWebProxy
+ {
+ public ICredentials Credentials {
+ get {
+ throw new NotImplementedException ();
+ }
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public Uri GetProxy (Uri destination)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool IsBypassed (Uri host)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
[Test]
public void Properties_Defaults ()
{
Assert.IsTrue (h.UseCookies, "#12");
Assert.IsFalse (h.UseDefaultCredentials, "#13");
Assert.IsTrue (h.UseProxy, "#14");
+ Assert.AreEqual (ClientCertificateOption.Manual, h.ClientCertificateOptions, "#15");
}
[Test]
} catch (ArgumentOutOfRangeException) {
}
+ h.UseProxy = false;
+ try {
+ h.Proxy = new Proxy ();
+ Assert.Fail ("#3");
+ } catch (InvalidOperationException) {
+ }
}
}
}
}
[Test]
- [Ignore]
public void Send ()
{
var mh = new HttpMessageHandlerMock ();
}
[Test]
- [Ignore]
public void Send_Complete_Default ()
{
var listener = CreateListener (l => {
}
[Test]
- [Ignore]
public void Send_Complete_ClientHandlerSettings ()
{
var listener = CreateListener (l => {
}
[Test]
- [Ignore]
public void Send_Complete_CustomHeaders ()
{
var listener = CreateListener (l => {
}
[Test]
- [Ignore]
public void Send_InvalidHandler ()
{
var mh = new HttpMessageHandlerMock ();
ms.Seek (0, SeekOrigin.Begin);
var sc = new StreamContent (ms);
- sc.LoadIntoBufferAsync (400).Wait ();
+ Assert.IsTrue (sc.LoadIntoBufferAsync (400).Wait (200));
}
[Test]
var res = sc.ReadAsStringAsync ().Result;
Assert.AreEqual ("M7", res, "#1");
}
+
+ [Test]
+ public void ReadAsStream ()
+ {
+ var ms = new MemoryStream ();
+ ms.WriteByte (77);
+ ms.WriteByte (55);
+ ms.Seek (0, SeekOrigin.Begin);
+
+ var sc = new StreamContent (ms);
+ var res = sc.ReadAsStreamAsync ().Result;
+ Assert.AreEqual (77, res.ReadByte (), "#1");
+ }
}
}