Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Net.Http.Internal
{
// Wrapper around async result to store additional data. This is useful to pass data between BeginXYZ / EndXYZ.
internal class AsyncResultWithExtraData<T> : IAsyncResult
{
public AsyncResultWithExtraData(IAsyncResult inner, T extraData)
{
Inner = inner;
ExtraData = extraData;
}
public IAsyncResult Inner { get; private set; }
public T ExtraData { get; private set; }
public object AsyncState
{
get { return Inner.AsyncState; }
}
public Threading.WaitHandle AsyncWaitHandle
{
get { return Inner.AsyncWaitHandle; }
}
public bool CompletedSynchronously
{
get { return Inner.CompletedSynchronously; }
}
public bool IsCompleted
{
get { return Inner.IsCompleted; }
}
}
}

View File

@@ -0,0 +1,131 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
namespace System.Net.Http.Internal
{
/// <summary>
/// Stream that delegates to inner stream.
/// This is taken from System.Net.Http
/// </summary>
internal abstract class DelegatingStream : Stream
{
protected Stream _innerStream;
protected DelegatingStream(Stream innerStream)
{
if (innerStream == null)
{
throw new ArgumentNullException("innerStream");
}
_innerStream = innerStream;
}
public override bool CanRead
{
get { return _innerStream.CanRead; }
}
public override bool CanSeek
{
get { return _innerStream.CanSeek; }
}
public override bool CanWrite
{
get { return _innerStream.CanWrite; }
}
public override long Length
{
get { return _innerStream.Length; }
}
public override long Position
{
get { return _innerStream.Position; }
set { _innerStream.Position = value; }
}
public override int ReadTimeout
{
get { return _innerStream.ReadTimeout; }
set { _innerStream.ReadTimeout = value; }
}
public override bool CanTimeout
{
get { return _innerStream.CanTimeout; }
}
public override int WriteTimeout
{
get { return _innerStream.WriteTimeout; }
set { _innerStream.WriteTimeout = value; }
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_innerStream.Dispose();
}
base.Dispose(disposing);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _innerStream.Seek(offset, origin);
}
public override int Read(byte[] buffer, int offset, int count)
{
return _innerStream.Read(buffer, offset, count);
}
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return _innerStream.BeginRead(buffer, offset, count, callback, state);
}
public override int EndRead(IAsyncResult asyncResult)
{
return _innerStream.EndRead(asyncResult);
}
public override int ReadByte()
{
return _innerStream.ReadByte();
}
public override void Flush()
{
_innerStream.Flush();
}
public override void SetLength(long value)
{
_innerStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_innerStream.Write(buffer, offset, count);
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return _innerStream.BeginWrite(buffer, offset, count, callback, state);
}
public override void EndWrite(IAsyncResult asyncResult)
{
_innerStream.EndWrite(asyncResult);
}
public override void WriteByte(byte value)
{
_innerStream.WriteByte(value);
}
}
}

View File

@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net.Http.Internal;
using System.Runtime.Serialization;
using System.Text;
using System.Web.Http;
namespace System.Net.Http.Formatting.Internal
{
/// <summary>
/// NameValueCollection to represent form data and to generate form data output.
/// </summary>
[Serializable]
internal class HttpValueCollection : NameValueCollection
{
private HttpValueCollection()
: base(StringComparer.OrdinalIgnoreCase) // case-insensitive keys
{
}
// Use a builder function instead of a ctor to avoid virtual calls from the ctor.
public static NameValueCollection Create()
{
return new HttpValueCollection();
}
public static NameValueCollection Create(IEnumerable<KeyValuePair<string, string>> pairs)
{
var nvc = new HttpValueCollection();
// Ordering example:
// k=A&j=B&k=C --> k:[A,C];j=[B].
foreach (KeyValuePair<string, string> kv in pairs)
{
ThrowIfMaxHttpCollectionKeysExceeded(nvc.Count);
string key = kv.Key;
if (key == null)
{
key = string.Empty;
}
string value = kv.Value;
if (value == null)
{
value = string.Empty;
}
nvc.Add(key, value);
}
nvc.IsReadOnly = false;
return nvc;
}
private static void ThrowIfMaxHttpCollectionKeysExceeded(int count)
{
if (count >= MediaTypeFormatter.MaxHttpCollectionKeys)
{
throw Error.InvalidOperation(System.Net.Http.Properties.Resources.MaxHttpCollectionKeyLimitReached, MediaTypeFormatter.MaxHttpCollectionKeys, typeof(MediaTypeFormatter));
}
}
protected HttpValueCollection(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public override string ToString()
{
return ToString(true);
}
private string ToString(bool urlEncode)
{
if (Count == 0)
{
return String.Empty;
}
StringBuilder builder = new StringBuilder();
bool first = true;
foreach (string name in this)
{
string[] values = GetValues(name);
if (values == null || values.Length == 0)
{
first = AppendNameValuePair(builder, first, urlEncode, name, String.Empty);
}
else
{
foreach (string value in values)
{
first = AppendNameValuePair(builder, first, urlEncode, name, value);
}
}
}
return builder.ToString();
}
private static bool AppendNameValuePair(StringBuilder builder, bool first, bool urlEncode, string name, string value)
{
string effectiveName = name ?? String.Empty;
string encodedName = urlEncode ? UriQueryUtility.UrlEncode(effectiveName) : effectiveName;
string effectiveValue = value ?? String.Empty;
string encodedValue = urlEncode ? UriQueryUtility.UrlEncode(effectiveValue) : effectiveValue;
if (first)
{
first = false;
}
else
{
builder.Append("&");
}
builder.Append(encodedName);
if (!String.IsNullOrEmpty(encodedValue))
{
builder.Append("=");
builder.Append(encodedValue);
}
return first;
}
}
}

View File

@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
namespace System.Net.Http.Internal
{
/// <summary>
/// Stream that doesn't close the inner stream when closed. This is to work around a limitation
/// in the <see cref="System.Xml.XmlDictionaryReader"/> insisting of closing the inner stream.
/// The regular <see cref="System.Xml.XmlReader"/> does allow for not closing the inner stream but that
/// doesn't have the quota that we need for security reasons. Implementations of
/// <see cref="System.Net.Http.Formatting.MediaTypeFormatter"/>
/// should not close the input stream when reading or writing so hence this workaround.
/// </summary>
internal class NonClosingDelegatingStream : DelegatingStream
{
public NonClosingDelegatingStream(Stream innerStream)
: base(innerStream)
{
}
public override void Close()
{
}
}
}

View File

@@ -0,0 +1,360 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics.Contracts;
using System.Text;
namespace System.Net.Http.Internal
{
/// <summary>
/// Helpers for encoding, decoding, and parsing URI query components.
/// </summary>
internal static class UriQueryUtility
{
// The implementation below is ported from WebUtility for use in .Net 4
#region UrlEncode implementation
private static byte[] UrlEncode(byte[] bytes, int offset, int count, bool alwaysCreateNewReturnValue)
{
byte[] encoded = UrlEncode(bytes, offset, count);
return (alwaysCreateNewReturnValue && (encoded != null) && (encoded == bytes))
? (byte[])encoded.Clone()
: encoded;
}
private static byte[] UrlEncode(byte[] bytes, int offset, int count)
{
if (!ValidateUrlEncodingParameters(bytes, offset, count))
{
return null;
}
int cSpaces = 0;
int cUnsafe = 0;
// count them first
for (int i = 0; i < count; i++)
{
char ch = (char)bytes[offset + i];
if (ch == ' ')
cSpaces++;
else if (!IsUrlSafeChar(ch))
cUnsafe++;
}
// nothing to expand?
if (cSpaces == 0 && cUnsafe == 0)
return bytes;
// expand not 'safe' characters into %XX, spaces to +s
byte[] expandedBytes = new byte[count + cUnsafe * 2];
int pos = 0;
for (int i = 0; i < count; i++)
{
byte b = bytes[offset + i];
char ch = (char)b;
if (IsUrlSafeChar(ch))
{
expandedBytes[pos++] = b;
}
else if (ch == ' ')
{
expandedBytes[pos++] = (byte)'+';
}
else
{
expandedBytes[pos++] = (byte)'%';
expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf);
expandedBytes[pos++] = (byte)IntToHex(b & 0x0f);
}
}
return expandedBytes;
}
#endregion
#region UrlEncode public methods
public static string UrlEncode(string str)
{
if (str == null)
return null;
byte[] bytes = Encoding.UTF8.GetBytes(str);
return Encoding.ASCII.GetString(UrlEncode(bytes, 0, bytes.Length, false /* alwaysCreateNewReturnValue */));
}
public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count)
{
return UrlEncode(bytes, offset, count, true /* alwaysCreateNewReturnValue */);
}
#endregion
#region UrlDecode implementation
private static string UrlDecodeInternal(string value, Encoding encoding)
{
if (value == null)
{
return null;
}
int count = value.Length;
UrlDecoder helper = new UrlDecoder(count, encoding);
// go through the string's chars collapsing %XX and %uXXXX and
// appending each char as char, with exception of %XX constructs
// that are appended as bytes
for (int pos = 0; pos < count; pos++)
{
char ch = value[pos];
if (ch == '+')
{
ch = ' ';
}
else if (ch == '%' && pos < count - 2)
{
if (value[pos + 1] == 'u' && pos < count - 5)
{
int h1 = HexToInt(value[pos + 2]);
int h2 = HexToInt(value[pos + 3]);
int h3 = HexToInt(value[pos + 4]);
int h4 = HexToInt(value[pos + 5]);
if (h1 >= 0 && h2 >= 0 && h3 >= 0 && h4 >= 0)
{ // valid 4 hex chars
ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4);
pos += 5;
// only add as char
helper.AddChar(ch);
continue;
}
}
else
{
int h1 = HexToInt(value[pos + 1]);
int h2 = HexToInt(value[pos + 2]);
if (h1 >= 0 && h2 >= 0)
{ // valid 2 hex chars
byte b = (byte)((h1 << 4) | h2);
pos += 2;
// don't add as char
helper.AddByte(b);
continue;
}
}
}
if ((ch & 0xFF80) == 0)
helper.AddByte((byte)ch); // 7 bit have to go as bytes because of Unicode
else
helper.AddChar(ch);
}
return helper.GetString();
}
private static byte[] UrlDecodeInternal(byte[] bytes, int offset, int count)
{
if (!ValidateUrlEncodingParameters(bytes, offset, count))
{
return null;
}
int decodedBytesCount = 0;
byte[] decodedBytes = new byte[count];
for (int i = 0; i < count; i++)
{
int pos = offset + i;
byte b = bytes[pos];
if (b == '+')
{
b = (byte)' ';
}
else if (b == '%' && i < count - 2)
{
int h1 = HexToInt((char)bytes[pos + 1]);
int h2 = HexToInt((char)bytes[pos + 2]);
if (h1 >= 0 && h2 >= 0)
{ // valid 2 hex chars
b = (byte)((h1 << 4) | h2);
i += 2;
}
}
decodedBytes[decodedBytesCount++] = b;
}
if (decodedBytesCount < decodedBytes.Length)
{
byte[] newDecodedBytes = new byte[decodedBytesCount];
Array.Copy(decodedBytes, newDecodedBytes, decodedBytesCount);
decodedBytes = newDecodedBytes;
}
return decodedBytes;
}
#endregion
#region UrlDecode public methods
public static string UrlDecode(string str)
{
if (str == null)
return null;
return UrlDecodeInternal(str, Encoding.UTF8);
}
public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count)
{
return UrlDecodeInternal(bytes, offset, count);
}
#endregion
#region Helper methods
private static int HexToInt(char h)
{
return (h >= '0' && h <= '9') ? h - '0' :
(h >= 'a' && h <= 'f') ? h - 'a' + 10 :
(h >= 'A' && h <= 'F') ? h - 'A' + 10 :
-1;
}
private static char IntToHex(int n)
{
Contract.Assert(n < 0x10);
if (n <= 9)
return (char)(n + (int)'0');
else
return (char)(n - 10 + (int)'a');
}
// Set of safe chars, from RFC 1738.4 minus '+'
private static bool IsUrlSafeChar(char ch)
{
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
return true;
switch (ch)
{
case '-':
case '_':
case '.':
case '!':
case '*':
case '(':
case ')':
return true;
}
return false;
}
private static bool ValidateUrlEncodingParameters(byte[] bytes, int offset, int count)
{
if (bytes == null && count == 0)
return false;
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
if (offset < 0 || offset > bytes.Length)
{
throw new ArgumentOutOfRangeException("offset");
}
if (count < 0 || offset + count > bytes.Length)
{
throw new ArgumentOutOfRangeException("count");
}
return true;
}
#endregion
#region UrlDecoder nested class
// Internal class to facilitate URL decoding -- keeps char buffer and byte buffer, allows appending of either chars or bytes
private class UrlDecoder
{
private int _bufferSize;
// Accumulate characters in a special array
private int _numChars;
private char[] _charBuffer;
// Accumulate bytes for decoding into characters in a special array
private int _numBytes;
private byte[] _byteBuffer;
// Encoding to convert chars to bytes
private Encoding _encoding;
private void FlushBytes()
{
if (_numBytes > 0)
{
_numChars += _encoding.GetChars(_byteBuffer, 0, _numBytes, _charBuffer, _numChars);
_numBytes = 0;
}
}
internal UrlDecoder(int bufferSize, Encoding encoding)
{
_bufferSize = bufferSize;
_encoding = encoding;
_charBuffer = new char[bufferSize];
// byte buffer created on demand
}
internal void AddChar(char ch)
{
if (_numBytes > 0)
FlushBytes();
_charBuffer[_numChars++] = ch;
}
internal void AddByte(byte b)
{
if (_byteBuffer == null)
_byteBuffer = new byte[_bufferSize];
_byteBuffer[_numBytes++] = b;
}
internal String GetString()
{
if (_numBytes > 0)
FlushBytes();
if (_numChars > 0)
return new String(_charBuffer, 0, _numChars);
else
return String.Empty;
}
}
#endregion
}
}