Added some XML documentation comments

This commit is contained in:
sta
2013-02-21 16:23:25 +09:00
parent a9d5e06166
commit 8232c95cd8
16 changed files with 988 additions and 368 deletions

View File

@@ -1,6 +1,6 @@
//
// ChunkStream.cs
// Copied from System.Net.ChunkStream
// Copied from System.Net.ChunkStream.cs
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
@@ -28,7 +28,7 @@
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
@@ -39,6 +39,7 @@ namespace WebSocketSharp.Net {
class ChunkStream {
enum State {
None,
Body,
BodyFinished,
@@ -46,8 +47,9 @@ namespace WebSocketSharp.Net {
}
class Chunk {
public byte [] Bytes;
public int Offset;
public int Offset;
public Chunk (byte [] chunk)
{
@@ -63,19 +65,29 @@ namespace WebSocketSharp.Net {
}
}
internal WebHeaderCollection headers;
int chunkSize;
int chunkRead;
State state;
//byte [] waitBuffer;
#region Private Fields
int chunkRead;
List<Chunk> chunks;
int chunkSize;
bool gotit;
StringBuilder saved;
bool sawCR;
bool gotit;
int trailerState;
ArrayList chunks;
bool sawCR;
State state;
int trailerState;
#endregion
#region Internal Fields
internal WebHeaderCollection headers;
#endregion
#region Constructors
public ChunkStream (byte [] buffer, int offset, int size, WebHeaderCollection headers)
: this (headers)
: this (headers)
{
Write (buffer, offset, size);
}
@@ -84,122 +96,26 @@ namespace WebSocketSharp.Net {
{
this.headers = headers;
saved = new StringBuilder ();
chunks = new ArrayList ();
chunks = new List<Chunk> ();
chunkSize = -1;
}
public void ResetBuffer ()
{
chunkSize = -1;
chunkRead = 0;
chunks.Clear ();
}
public void WriteAndReadBack (byte [] buffer, int offset, int size, ref int read)
{
if (offset + read > 0)
Write (buffer, offset, offset+read);
read = Read (buffer, offset, size);
}
#endregion
public int Read (byte [] buffer, int offset, int size)
{
return ReadFromChunks (buffer, offset, size);
}
#region Properties
int ReadFromChunks (byte [] buffer, int offset, int size)
{
int count = chunks.Count;
int nread = 0;
for (int i = 0; i < count; i++) {
Chunk chunk = (Chunk) chunks [i];
if (chunk == null)
continue;
if (chunk.Offset == chunk.Bytes.Length) {
chunks [i] = null;
continue;
}
nread += chunk.Read (buffer, offset + nread, size - nread);
if (nread == size)
break;
}
return nread;
}
public void Write (byte [] buffer, int offset, int size)
{
InternalWrite (buffer, ref offset, size);
}
void InternalWrite (byte [] buffer, ref int offset, int size)
{
if (state == State.None) {
state = GetChunkSize (buffer, ref offset, size);
if (state == State.None)
return;
saved.Length = 0;
sawCR = false;
gotit = false;
}
if (state == State.Body && offset < size) {
state = ReadBody (buffer, ref offset, size);
if (state == State.Body)
return;
}
if (state == State.BodyFinished && offset < size) {
state = ReadCRLF (buffer, ref offset, size);
if (state == State.BodyFinished)
return;
sawCR = false;
}
if (state == State.Trailer && offset < size) {
state = ReadTrailer (buffer, ref offset, size);
if (state == State.Trailer)
return;
saved.Length = 0;
sawCR = false;
gotit = false;
}
if (offset < size)
InternalWrite (buffer, ref offset, size);
public int ChunkLeft {
get { return chunkSize - chunkRead; }
}
public bool WantMore {
get { return (chunkRead != chunkSize || chunkSize != 0 || state != State.None); }
}
public int ChunkLeft {
get { return chunkSize - chunkRead; }
}
State ReadBody (byte [] buffer, ref int offset, int size)
{
if (chunkSize == 0)
return State.BodyFinished;
#endregion
int diff = size - offset;
if (diff + chunkRead > chunkSize)
diff = chunkSize - chunkRead;
#region Private Methods
byte [] chunk = new byte [diff];
Buffer.BlockCopy (buffer, offset, chunk, 0, diff);
chunks.Add (new Chunk (chunk));
offset += diff;
chunkRead += diff;
return (chunkRead == chunkSize) ? State.BodyFinished : State.Body;
}
State GetChunkSize (byte [] buffer, ref int offset, int size)
{
char c = '\0';
@@ -207,7 +123,7 @@ namespace WebSocketSharp.Net {
c = (char) buffer [offset++];
if (c == '\r') {
if (sawCR)
ThrowProtocolViolation ("2 CR found");
ThrowProtocolViolation ("2 CR found.");
sawCR = true;
continue;
@@ -223,12 +139,12 @@ namespace WebSocketSharp.Net {
saved.Append (c);
if (saved.Length > 20)
ThrowProtocolViolation ("chunk size too long.");
ThrowProtocolViolation ("Chunk size too long.");
}
if (!sawCR || c != '\n') {
if (offset < size)
ThrowProtocolViolation ("Missing \\n");
ThrowProtocolViolation ("Missing \\n.");
try {
if (saved.Length > 0) {
@@ -256,31 +172,102 @@ namespace WebSocketSharp.Net {
return State.Body;
}
static string RemoveChunkExtension (string input)
void InternalWrite (byte [] buffer, ref int offset, int size)
{
int idx = input.IndexOf (';');
if (idx == -1)
return input;
return input.Substring (0, idx);
if (state == State.None) {
state = GetChunkSize (buffer, ref offset, size);
if (state == State.None)
return;
saved.Length = 0;
sawCR = false;
gotit = false;
}
if (state == State.Body && offset < size) {
state = ReadBody (buffer, ref offset, size);
if (state == State.Body)
return;
}
if (state == State.BodyFinished && offset < size) {
state = ReadCRLF (buffer, ref offset, size);
if (state == State.BodyFinished)
return;
sawCR = false;
}
if (state == State.Trailer && offset < size) {
state = ReadTrailer (buffer, ref offset, size);
if (state == State.Trailer)
return;
saved.Length = 0;
sawCR = false;
gotit = false;
}
if (offset < size)
InternalWrite (buffer, ref offset, size);
}
State ReadBody (byte [] buffer, ref int offset, int size)
{
if (chunkSize == 0)
return State.BodyFinished;
int diff = size - offset;
if (diff + chunkRead > chunkSize)
diff = chunkSize - chunkRead;
byte [] chunk = new byte [diff];
Buffer.BlockCopy (buffer, offset, chunk, 0, diff);
chunks.Add (new Chunk (chunk));
offset += diff;
chunkRead += diff;
return (chunkRead == chunkSize) ? State.BodyFinished : State.Body;
}
State ReadCRLF (byte [] buffer, ref int offset, int size)
{
if (!sawCR) {
if ((char) buffer [offset++] != '\r')
ThrowProtocolViolation ("Expecting \\r");
ThrowProtocolViolation ("Expecting \\r.");
sawCR = true;
if (offset == size)
return State.BodyFinished;
}
if (sawCR && (char) buffer [offset++] != '\n')
ThrowProtocolViolation ("Expecting \\n");
ThrowProtocolViolation ("Expecting \\n.");
return State.None;
}
int ReadFromChunks (byte [] buffer, int offset, int size)
{
int count = chunks.Count;
int nread = 0;
for (int i = 0; i < count; i++) {
var chunk = chunks [i];
if (chunk == null)
continue;
if (chunk.Offset == chunk.Bytes.Length) {
chunks [i] = null;
continue;
}
nread += chunk.Read (buffer, offset + nread, size - nread);
if (nread == size)
break;
}
return nread;
}
State ReadTrailer (byte [] buffer, ref int offset, int size)
{
char c = '\0';
@@ -292,9 +279,10 @@ namespace WebSocketSharp.Net {
offset++;
return State.None;
}
offset--;
}
int st = trailerState;
string stString = "\r\n\r";
while (offset < size && st < 4) {
@@ -325,7 +313,7 @@ namespace WebSocketSharp.Net {
return State.Trailer;
}
StringReader reader = new StringReader (saved.ToString ());
var reader = new StringReader (saved.ToString ());
string line;
while ((line = reader.ReadLine ()) != null && line != "")
headers.Add (line);
@@ -333,10 +321,50 @@ namespace WebSocketSharp.Net {
return State.None;
}
static string RemoveChunkExtension (string input)
{
int idx = input.IndexOf (';');
if (idx == -1)
return input;
return input.Substring (0, idx);
}
static void ThrowProtocolViolation (string message)
{
WebException we = new WebException (message, null, WebExceptionStatus.ServerProtocolViolation, null);
var we = new WebException (message, null, WebExceptionStatus.ServerProtocolViolation, null);
throw we;
}
#endregion
#region Public Methods
public int Read (byte [] buffer, int offset, int size)
{
return ReadFromChunks (buffer, offset, size);
}
public void ResetBuffer ()
{
chunkSize = -1;
chunkRead = 0;
chunks.Clear ();
}
public void Write (byte [] buffer, int offset, int size)
{
InternalWrite (buffer, ref offset, size);
}
public void WriteAndReadBack (byte [] buffer, int offset, int size, ref int read)
{
if (offset + read > 0)
Write (buffer, offset, offset + read);
read = Read (buffer, offset, size);
}
#endregion
}
}

View File

@@ -1,6 +1,6 @@
//
// ChunkedInputStream.cs
// Copied from System.Net.ChunkedInputStream
// Copied from System.Net.ChunkedInputStream.cs
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
@@ -25,21 +25,15 @@
// 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;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace WebSocketSharp.Net {
class ChunkedInputStream : RequestStream
{
HttpListenerContext context;
ChunkStream decoder;
bool disposed;
bool no_more_data;
class ChunkedInputStream : RequestStream {
class ReadBufferState {
@@ -60,6 +54,17 @@ namespace WebSocketSharp.Net {
}
}
#region Fields
HttpListenerContext context;
ChunkStream decoder;
bool disposed;
bool no_more_data;
#endregion
#region Constructor
public ChunkedInputStream (
HttpListenerContext context, Stream stream, byte [] buffer, int offset, int length)
: base (stream, buffer, offset, length)
@@ -69,15 +74,23 @@ namespace WebSocketSharp.Net {
decoder = new ChunkStream (coll);
}
#endregion
#region Property
public ChunkStream Decoder {
get { return decoder; }
set { decoder = value; }
}
#endregion
#region Private Method
void OnRead (IAsyncResult base_ares)
{
ReadBufferState rb = (ReadBufferState) base_ares.AsyncState;
HttpStreamAsyncResult ares = rb.Ares;
var rb = (ReadBufferState) base_ares.AsyncState;
var ares = rb.Ares;
try {
int nread = base.EndRead (base_ares);
decoder.Write (ares.Buffer, ares.Offset, nread);
@@ -90,6 +103,7 @@ namespace WebSocketSharp.Net {
ares.Complete ();
return;
}
ares.Offset = 0;
ares.Count = Math.Min (8192, decoder.ChunkLeft + 6);
base.BeginRead (ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
@@ -99,6 +113,10 @@ namespace WebSocketSharp.Net {
}
}
#endregion
#region Public Methods
public override IAsyncResult BeginRead (
byte [] buffer, int offset, int count, AsyncCallback cback, object state)
{
@@ -110,18 +128,19 @@ namespace WebSocketSharp.Net {
int len = buffer.Length;
if (offset < 0 || offset > len)
throw new ArgumentOutOfRangeException ("offset exceeds the size of buffer");
throw new ArgumentOutOfRangeException ("'offset' exceeds the size of buffer.");
if (count < 0 || offset > len - count)
throw new ArgumentOutOfRangeException ("offset+size exceeds the size of buffer");
throw new ArgumentOutOfRangeException ("'offset' + 'count' exceeds the size of buffer.");
HttpStreamAsyncResult ares = new HttpStreamAsyncResult ();
var ares = new HttpStreamAsyncResult ();
ares.Callback = cback;
ares.State = state;
if (no_more_data) {
ares.Complete ();
return ares;
}
int nread = decoder.Read (buffer, offset, count);
offset += nread;
count -= nread;
@@ -131,16 +150,18 @@ namespace WebSocketSharp.Net {
ares.Complete ();
return ares;
}
if (!decoder.WantMore) {
no_more_data = nread == 0;
ares.Count = nread;
ares.Complete ();
return ares;
}
ares.Buffer = new byte [8192];
ares.Offset = 0;
ares.Count = 8192;
ReadBufferState rb = new ReadBufferState (buffer, offset, count, ares);
var rb = new ReadBufferState (buffer, offset, count, ares);
rb.InitialCount += nread;
base.BeginRead (ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
return ares;
@@ -159,23 +180,25 @@ namespace WebSocketSharp.Net {
if (disposed)
throw new ObjectDisposedException (GetType ().ToString ());
HttpStreamAsyncResult my_ares = ares as HttpStreamAsyncResult;
if (ares == null)
throw new ArgumentException ("Invalid IAsyncResult", "ares");
throw new ArgumentException ("Invalid IAsyncResult.", "ares");
if (!ares.IsCompleted)
ares.AsyncWaitHandle.WaitOne ();
if (my_ares.Error != null)
var ares_ = ares as HttpStreamAsyncResult;
if (ares_.Error != null)
throw new HttpListenerException (400, "I/O operation aborted.");
return my_ares.Count;
return ares_.Count;
}
public override int Read ([In,Out] byte [] buffer, int offset, int count)
{
IAsyncResult ares = BeginRead (buffer, offset, count, null, null);
var ares = BeginRead (buffer, offset, count, null, null);
return EndRead (ares);
}
#endregion
}
}

View File

@@ -1,12 +1,12 @@
//
// HttpListenerPrefixCollection.cs
// Copied from System.Net.HttpListenerPrefixCollection
// Copied from System.Net.HttpListenerPrefixCollection.cs
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
// Copyright (c) 2012 sta.blockhead (sta.blockhead@gmail.com)
// Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -31,38 +31,104 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
namespace WebSocketSharp.Net {
/// <summary>
/// Provides the collection used to store the URI prefixes for the <see cref="HttpListener"/>.
/// </summary>
public class HttpListenerPrefixCollection : ICollection<string>, IEnumerable<string>, IEnumerable
{
#region Fields
HttpListener listener;
List<string> prefixes;
#endregion
#region Private Constructor
private HttpListenerPrefixCollection ()
{
prefixes = new List<string> ();
}
#endregion
#region Internal Constructor
internal HttpListenerPrefixCollection (HttpListener listener)
: this ()
{
this.listener = listener;
}
#endregion
#region Properties
/// <summary>
/// Gets the number of prefixes contained in the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <value>
/// A <see cref="int"/> that contains the number of prefixes.
/// </value>
public int Count {
get { return prefixes.Count; }
}
/// <summary>
/// Gets a value indicating whether access to the <see cref="HttpListenerPrefixCollection"/> is read-only.
/// </summary>
/// <value>
/// Always returns <c>false</c>.
/// </value>
public bool IsReadOnly {
get { return false; }
}
/// <summary>
/// Gets a value indicating whether access to the <see cref="HttpListenerPrefixCollection"/> is synchronized.
/// </summary>
/// <value>
/// Always returns <c>false</c>.
/// </value>
public bool IsSynchronized {
get { return false; }
}
#endregion
#region Explicit Interface Implementation
/// <summary>
/// Gets an object that can be used to iterate through the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <returns>
/// An object that implements the <see cref="IEnumerator"/> interface and provides access to
/// the URI prefix strings in the <see cref="HttpListenerPrefixCollection"/>.
/// </returns>
IEnumerator IEnumerable.GetEnumerator ()
{
return prefixes.GetEnumerator ();
}
#endregion
#region Public Methods
/// <summary>
/// Adds the specified <paramref name="uriPrefix"/> to the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <param name="uriPrefix">
/// A <see cref="string"/> that contains a URI prefix to add.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="uriPrefix"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public void Add (string uriPrefix)
{
listener.CheckDisposed ();
@@ -75,6 +141,12 @@ namespace WebSocketSharp.Net {
EndPointManager.AddPrefix (uriPrefix, listener);
}
/// <summary>
/// Removes all URI prefixes from the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public void Clear ()
{
listener.CheckDisposed ();
@@ -83,34 +155,96 @@ namespace WebSocketSharp.Net {
EndPointManager.RemoveListener (listener);
}
/// <summary>
/// Returns a value indicating whether the <see cref="HttpListenerPrefixCollection"/> contains
/// the specified <paramref name="uriPrefix"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the <see cref="HttpListenerPrefixCollection"/> contains the specified <paramref name="uriPrefix"/>;
/// otherwise, <c>false</c>.
/// </returns>
/// <param name="uriPrefix">
/// A <see cref="string"/> that contains a URI prefix to test.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="uriPrefix"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public bool Contains (string uriPrefix)
{
listener.CheckDisposed ();
if (uriPrefix == null)
throw new ArgumentNullException ("uriPrefix");
return prefixes.Contains (uriPrefix);
}
public void CopyTo (string [] array, int offset)
{
listener.CheckDisposed ();
prefixes.CopyTo (array, offset);
}
/// <summary>
/// Copies the contents of the <see cref="HttpListenerPrefixCollection"/> to the specified <see cref="Array"/>.
/// </summary>
/// <param name="array">
/// An <see cref="Array"/> that receives the URI prefix strings in the <see cref="HttpListenerPrefixCollection"/>.
/// </param>
/// <param name="offset">
/// An <see cref="int"/> that contains the zero-based index in <paramref name="array"/> at which copying begins.
/// </param>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public void CopyTo (Array array, int offset)
{
listener.CheckDisposed ();
((ICollection) prefixes).CopyTo (array, offset);
}
/// <summary>
/// Copies the contents of the <see cref="HttpListenerPrefixCollection"/> to the specified array of <see cref="string"/>.
/// </summary>
/// <param name="array">
/// An array of <see cref="string"/> that receives the URI prefix strings in the <see cref="HttpListenerPrefixCollection"/>.
/// </param>
/// <param name="offset">
/// An <see cref="int"/> that contains the zero-based index in <paramref name="array"/> at which copying begins.
/// </param>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public void CopyTo (string [] array, int offset)
{
listener.CheckDisposed ();
prefixes.CopyTo (array, offset);
}
/// <summary>
/// Gets an object that can be used to iterate through the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <returns>
/// An object that implements the IEnumerator&lt;string&gt; interface and provides access to
/// the URI prefix strings in the <see cref="HttpListenerPrefixCollection"/>.
/// </returns>
public IEnumerator<string> GetEnumerator ()
{
return prefixes.GetEnumerator ();
}
IEnumerator IEnumerable.GetEnumerator ()
{
return prefixes.GetEnumerator ();
}
/// <summary>
/// Removes the specified <paramref name="uriPrefix"/> from the list of prefixes in the <see cref="HttpListenerPrefixCollection"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="uriPrefix"/> was found in the <see cref="HttpListenerPrefixCollection"/>
/// and removed; otherwise, <c>false</c>.
/// </returns>
/// <param name="uriPrefix">
/// A <see cref="string"/> that contains a URI prefix to remove.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="uriPrefix"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ObjectDisposedException">
/// The <see cref="HttpListener"/> associated with this <see cref="HttpListenerPrefixCollection"/> is closed.
/// </exception>
public bool Remove (string uriPrefix)
{
listener.CheckDisposed ();
@@ -123,5 +257,7 @@ namespace WebSocketSharp.Net {
return result;
}
#endregion
}
}

View File

@@ -1,6 +1,6 @@
//
// HttpStreamAsyncResult.cs
// Copied from System.Net.HttpStreamAsyncResult
// Copied from System.Net.HttpStreamAsyncResult.cs
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
@@ -28,24 +28,33 @@
//
using System;
using System.Net;
using System.Threading;
namespace WebSocketSharp.Net {
class HttpStreamAsyncResult : IAsyncResult
{
class HttpStreamAsyncResult : IAsyncResult {
#region Private Fields
bool completed;
ManualResetEvent handle;
object locker = new object ();
#endregion
#region Internal Fields
internal AsyncCallback Callback;
internal int Count;
internal byte [] Buffer;
internal Exception Error;
internal int Offset;
internal object State;
internal int SynchRead;
internal int SyncRead;
#endregion
#region Properties
public object AsyncState {
get { return State; }
@@ -63,7 +72,7 @@ namespace WebSocketSharp.Net {
}
public bool CompletedSynchronously {
get { return (SynchRead == Count); }
get { return (SyncRead == Count); }
}
public bool IsCompleted {
@@ -74,6 +83,10 @@ namespace WebSocketSharp.Net {
}
}
#endregion
#region Public Methods
public void Complete ()
{
lock (locker) {
@@ -94,5 +107,7 @@ namespace WebSocketSharp.Net {
Error = e;
Complete ();
}
#endregion
}
}

View File

@@ -1,6 +1,6 @@
//
// ListenerPrefix.cs
// Copied from System.ListenerPrefix
// Copied from System.ListenerPrefix.cs
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
@@ -35,21 +35,36 @@ namespace WebSocketSharp.Net {
sealed class ListenerPrefix {
IPAddress [] addresses;
string host;
string original;
string path;
ushort port;
bool secure;
#region Private Fields
IPAddress [] addresses;
string host;
string original;
string path;
ushort port;
bool secure;
#endregion
#region Public Field
public HttpListener Listener;
#endregion
#region Constructor
// Must be called after calling ListenerPrefix.CheckUri.
public ListenerPrefix (string prefix)
{
original = prefix;
Parse (prefix);
}
#endregion
#region Properties
public IPAddress [] Addresses {
get { return addresses; }
set { addresses = value; }
@@ -71,19 +86,18 @@ namespace WebSocketSharp.Net {
get { return secure; }
}
#endregion
#region Private Method
void Parse (string uri)
{
int default_port = (uri.StartsWith ("http://")) ? 80 : -1;
if (default_port == -1) {
default_port = (uri.StartsWith ("https://")) ? 443 : -1;
int default_port = (uri.StartsWith ("http://")) ? 80 : 443;
if (default_port == 443)
secure = true;
}
int length = uri.Length;
int start_host = uri.IndexOf (':') + 3;
if (start_host >= length)
throw new ArgumentException ("No host specified.");
int colon = uri.IndexOf (':', start_host, length - start_host);
int root;
if (colon > 0) {
@@ -95,15 +109,21 @@ namespace WebSocketSharp.Net {
root = uri.IndexOf ('/', start_host, length - start_host);
host = uri.Substring (start_host, root - start_host);
path = uri.Substring (root);
port = (ushort) default_port;
}
if (path.Length != 1)
path = path.Substring (0, path.Length - 1);
}
#endregion
#region public Methods
public static void CheckUri (string uri)
{
if (uri == null)
throw new ArgumentNullException ("uriPrefix");
throw new ArgumentNullException ("uri");
int default_port = (uri.StartsWith ("http://")) ? 80 : -1;
if (default_port == -1)
@@ -140,13 +160,13 @@ namespace WebSocketSharp.Net {
}
if (uri [uri.Length - 1] != '/')
throw new ArgumentException ("The prefix must end with '/'");
throw new ArgumentException ("The prefix must end with '/'.");
}
// Equals and GetHashCode are required to detect duplicates in HttpListenerPrefixCollection.
public override bool Equals (object o)
{
ListenerPrefix other = o as ListenerPrefix;
var other = o as ListenerPrefix;
if (other == null)
return false;
@@ -162,5 +182,7 @@ namespace WebSocketSharp.Net {
{
return original;
}
#endregion
}
}

View File

@@ -1,6 +1,6 @@
//
// RequestStream.cs
// Copied from System.Net.RequestStream
// Copied from System.Net.RequestStream.cs
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
@@ -29,27 +29,31 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace WebSocketSharp.Net {
class RequestStream : Stream
{
byte [] buffer;
int offset;
int length;
long remaining_body;
bool disposed;
System.IO.Stream stream;
class RequestStream : Stream {
internal RequestStream (System.IO.Stream stream, byte [] buffer, int offset, int length)
#region Fields
byte [] buffer;
bool disposed;
int length;
int offset;
long remaining_body;
Stream stream;
#endregion
#region Constructors
internal RequestStream (Stream stream, byte [] buffer, int offset, int length)
: this (stream, buffer, offset, length, -1)
{
}
internal RequestStream (System.IO.Stream stream, byte [] buffer, int offset, int length, long contentlength)
internal RequestStream (Stream stream, byte [] buffer, int offset, int length, long contentlength)
{
this.stream = stream;
this.buffer = buffer;
@@ -58,6 +62,10 @@ namespace WebSocketSharp.Net {
this.remaining_body = contentlength;
}
#endregion
#region Properties
public override bool CanRead {
get { return true; }
}
@@ -79,33 +87,30 @@ namespace WebSocketSharp.Net {
set { throw new NotSupportedException (); }
}
#endregion
public override void Close ()
{
disposed = true;
}
#region Private Method
public override void Flush ()
{
}
// Returns 0 if we can keep reading from the base stream,
// > 0 if we read something from the buffer.
// -1 if we had a content length set and we finished reading that many bytes.
int FillFromBuffer (byte [] buffer, int off, int count)
int FillFromBuffer (byte [] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException ("buffer");
if (off < 0)
if (offset < 0)
throw new ArgumentOutOfRangeException ("offset", "< 0");
if (count < 0)
throw new ArgumentOutOfRangeException ("count", "< 0");
int len = buffer.Length;
if (off > len)
throw new ArgumentException ("destination offset is beyond array size");
if (off > len - count)
throw new ArgumentException ("Reading would overrun buffer");
if (offset > len)
throw new ArgumentException ("Destination offset is beyond array size.");
if (offset > len - count)
throw new ArgumentException ("Reading would overrun buffer.");
if (this.remaining_body == 0)
return -1;
@@ -120,21 +125,98 @@ namespace WebSocketSharp.Net {
if (this.offset > this.buffer.Length - size) {
size = Math.Min (size, this.buffer.Length - this.offset);
}
if (size == 0)
return 0;
Buffer.BlockCopy (this.buffer, this.offset, buffer, off, size);
Buffer.BlockCopy (this.buffer, this.offset, buffer, offset, size);
this.offset += size;
this.length -= size;
if (this.remaining_body > 0)
remaining_body -= size;
return size;
}
#endregion
#region Public Methods
public override IAsyncResult BeginRead (
byte [] buffer, int offset, int count, AsyncCallback cback, object state)
{
if (disposed)
throw new ObjectDisposedException (GetType ().ToString ());
int nread = FillFromBuffer (buffer, offset, count);
if (nread > 0 || nread == -1) {
var ares = new HttpStreamAsyncResult ();
ares.Buffer = buffer;
ares.Offset = offset;
ares.Count = count;
ares.Callback = cback;
ares.State = state;
ares.SyncRead = nread;
ares.Complete ();
return ares;
}
// Avoid reading past the end of the request to allow
// for HTTP pipelining
if (remaining_body >= 0 && count > remaining_body)
count = (int) Math.Min (Int32.MaxValue, remaining_body);
return stream.BeginRead (buffer, offset, count, cback, state);
}
public override IAsyncResult BeginWrite (
byte [] buffer, int offset, int count, AsyncCallback cback, object state)
{
throw new NotSupportedException ();
}
public override void Close ()
{
disposed = true;
}
public override int EndRead (IAsyncResult ares)
{
if (disposed)
throw new ObjectDisposedException (GetType ().ToString ());
if (ares == null)
throw new ArgumentNullException ("ares");
if (ares is HttpStreamAsyncResult) {
var ares_ = (HttpStreamAsyncResult) ares;
if (!ares.IsCompleted)
ares.AsyncWaitHandle.WaitOne ();
return ares_.SyncRead;
}
// Close on exception?
int nread = stream.EndRead (ares);
if (remaining_body > 0 && nread > 0)
remaining_body -= nread;
return nread;
}
public override void EndWrite (IAsyncResult async_result)
{
throw new NotSupportedException ();
}
public override void Flush ()
{
}
public override int Read ([In,Out] byte[] buffer, int offset, int count)
{
if (disposed)
throw new ObjectDisposedException (typeof (RequestStream).ToString ());
throw new ObjectDisposedException (GetType () .ToString ());
// Call FillFromBuffer to check for buffer boundaries even when remaining_body is 0
int nread = FillFromBuffer (buffer, offset, count);
@@ -147,54 +229,7 @@ namespace WebSocketSharp.Net {
nread = stream.Read (buffer, offset, count);
if (nread > 0 && remaining_body > 0)
remaining_body -= nread;
return nread;
}
public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
AsyncCallback cback, object state)
{
if (disposed)
throw new ObjectDisposedException (typeof (RequestStream).ToString ());
int nread = FillFromBuffer (buffer, offset, count);
if (nread > 0 || nread == -1) {
HttpStreamAsyncResult ares = new HttpStreamAsyncResult ();
ares.Buffer = buffer;
ares.Offset = offset;
ares.Count = count;
ares.Callback = cback;
ares.State = state;
ares.SynchRead = nread;
ares.Complete ();
return ares;
}
// Avoid reading past the end of the request to allow
// for HTTP pipelining
if (remaining_body >= 0 && count > remaining_body)
count = (int) Math.Min (Int32.MaxValue, remaining_body);
return stream.BeginRead (buffer, offset, count, cback, state);
}
public override int EndRead (IAsyncResult ares)
{
if (disposed)
throw new ObjectDisposedException (typeof (RequestStream).ToString ());
if (ares == null)
throw new ArgumentNullException ("async_result");
if (ares is HttpStreamAsyncResult) {
HttpStreamAsyncResult r = (HttpStreamAsyncResult) ares;
if (!ares.IsCompleted)
ares.AsyncWaitHandle.WaitOne ();
return r.SynchRead;
}
// Close on exception?
int nread = stream.EndRead (ares);
if (remaining_body > 0 && nread > 0)
remaining_body -= nread;
return nread;
}
@@ -213,15 +248,6 @@ namespace WebSocketSharp.Net {
throw new NotSupportedException ();
}
public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count,
AsyncCallback cback, object state)
{
throw new NotSupportedException ();
}
public override void EndWrite (IAsyncResult async_result)
{
throw new NotSupportedException ();
}
#endregion
}
}