// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_0
+
+#if NET_2_0 && SECURITY_DEP
+
using System.IO;
using System.Net.Sockets;
+using System.Reflection;
using System.Text;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using Mono.Security.Protocol.Tls;
+
namespace System.Net {
sealed class HttpConnection
{
const int BufferSize = 8192;
Socket sock;
- NetworkStream stream;
+ Stream stream;
EndPointListener epl;
MemoryStream ms;
byte [] buffer;
HttpListenerContext context;
- bool secure;
StringBuilder current_line;
ListenerPrefix prefix;
RequestStream i_stream;
bool chunked;
int chunked_uses;
bool context_bound;
+ bool secure;
+ AsymmetricAlgorithm key;
- public HttpConnection (Socket sock, EndPointListener epl, bool secure)
+ public HttpConnection (Socket sock, EndPointListener epl, bool secure, X509Certificate2 cert, AsymmetricAlgorithm key)
{
this.sock = sock;
- stream = new NetworkStream (sock, false);
this.epl = epl;
this.secure = secure;
+ this.key = key;
+ if (secure == false) {
+ stream = new NetworkStream (sock, false);
+ } else {
+#if EMBEDDED_IN_1_0
+ throw new NotImplementedException ();
+#else
+ SslServerStream ssl_stream = new SslServerStream (new NetworkStream (sock, false), cert, false, false);
+ ssl_stream.PrivateKeyCertSelectionDelegate += OnPVKSelection;
+ stream = ssl_stream;
+#endif
+ }
Init ();
}
+ AsymmetricAlgorithm OnPVKSelection (X509Certificate certificate, string targetHost)
+ {
+ return key;
+ }
+
+
void Init ()
{
context_bound = false;
{
if (buffer == null)
buffer = new byte [BufferSize];
- stream.BeginRead (buffer, 0, BufferSize, OnRead, this);
+ try {
+ stream.BeginRead (buffer, 0, BufferSize, OnRead, this);
+ } catch {
+ sock.Close (); // stream disposed
+ }
}
public RequestStream GetRequestStream (bool chunked, long contentlength)
if (chunked) {
this.chunked = true;
context.Response.SendChunked = true;
- i_stream = new ChunkedInputStream (context, sock, buffer, position, length);
+ i_stream = new ChunkedInputStream (context, stream, buffer, position, length - position);
} else {
- i_stream = new RequestStream (sock, buffer, position, length, contentlength);
+ i_stream = new RequestStream (stream, buffer, position, length - position, contentlength);
}
}
return i_stream;
if (o_stream == null) {
HttpListener listener = context.Listener;
bool ign = (listener == null) ? true : listener.IgnoreWriteExceptions;
- o_stream = new ResponseStream (sock, context.Response, ign);
+ o_stream = new ResponseStream (stream, context.Response, ign);
}
return o_stream;
}
try {
nread = stream.EndRead (ares);
ms.Write (buffer, 0, nread);
- } catch {
+ } catch (Exception e) {
+ //Console.WriteLine (e);
if (ms.Length > 0)
SendError ();
sock.Close ();
return;
}
- Socket s = sock;
- sock = null;
- s.Shutdown (SocketShutdown.Both);
- s.Close ();
+ if (context.Response.Headers ["connection"] == "close") {
+ Socket s = sock;
+ sock = null;
+ try {
+ s.Shutdown (SocketShutdown.Both);
+ } finally {
+ s.Close ();
+ }
+ } else {
+ Init ();
+ BeginReadRequest ();
+ return;
+ }
+
if (context_bound)
epl.UnbindContext (context);
}