comparison Net/HTTP.cs @ 10:7269e91c6e26

HTTPServer: added support for HTTPS
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 18 Jan 2013 18:24:20 +0100
parents 4b78cc5f116b
children ba8f94212c6e
comparison
equal deleted inserted replaced
9:9533a87363f3 10:7269e91c6e26
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
3 using System.IO; 3 using System.IO;
4 using System.Net; 4 using System.Net;
5 using System.Net.Security;
5 using System.Net.Sockets; 6 using System.Net.Sockets;
7 using System.Security.Cryptography.X509Certificates;
6 using System.Text; 8 using System.Text;
7 using UCIS.Net; 9 using UCIS.Net;
8 using UCIS.Util; 10 using UCIS.Util;
9 using HTTPHeader = System.Collections.Generic.KeyValuePair<string, string>; 11 using HTTPHeader = System.Collections.Generic.KeyValuePair<string, string>;
10 12
11 namespace UCIS.Net.HTTP { 13 namespace UCIS.Net.HTTP {
12 public class HTTPServer : TCPServer.IModule, IDisposable { 14 public class HTTPServer : TCPServer.IModule, IDisposable {
13 public IHTTPContentProvider ContentProvider { get; set; } 15 public IHTTPContentProvider ContentProvider { get; set; }
14 public Boolean ServeFlashPolicyFile { get; set; } 16 public Boolean ServeFlashPolicyFile { get; set; }
17 public X509Certificate SSLCertificate { get; set; }
15 private Socket Listener = null; 18 private Socket Listener = null;
16 19
17 public HTTPServer() { } 20 public HTTPServer() { }
18 21
19 public void Listen(int port) { 22 public void Listen(int port) {
29 } 32 }
30 33
31 private void AcceptCallback(IAsyncResult ar) { 34 private void AcceptCallback(IAsyncResult ar) {
32 try { 35 try {
33 Socket socket = Listener.EndAccept(ar); 36 Socket socket = Listener.EndAccept(ar);
34 new HTTPContext(this, socket); 37 if (SSLCertificate != null) {
38 SslStream ssl = new SslStream(new NetworkStream(socket, true));
39 ssl.BeginAuthenticateAsServer(SSLCertificate, SslAuthenticationCallback, new Object[] { socket, ssl });
40 } else {
41 new HTTPContext(this, socket);
42 }
35 } catch (Exception) { } 43 } catch (Exception) { }
36 try { 44 try {
37 Listener.BeginAccept(AcceptCallback, null); 45 Listener.BeginAccept(AcceptCallback, null);
38 } catch (Exception) { } 46 } catch (Exception) { }
39 } 47 }
40 48
49 private void SslAuthenticationCallback(IAsyncResult ar) {
50 Object[] args = (Object[])ar.AsyncState;
51 Socket socket = (Socket)args[0];
52 SslStream ssl = (SslStream)args[1];
53 try {
54 ssl.EndAuthenticateAsServer(ar);
55 new HTTPContext(this, ssl, socket);
56 } catch (Exception) { }
57 }
58
41 public void Dispose() { 59 public void Dispose() {
42 if (Listener != null) Listener.Close(); 60 if (Listener != null) Listener.Close();
43 } 61 }
44 62
45 bool TCPServer.IModule.Accept(TCPStream stream) { 63 bool TCPServer.IModule.Accept(TCPStream stream) {
64 82
65 private StreamWriter Writer; 83 private StreamWriter Writer;
66 private PrebufferingStream Reader; 84 private PrebufferingStream Reader;
67 private List<HTTPHeader> RequestHeaders; 85 private List<HTTPHeader> RequestHeaders;
68 private HTTPConnectionState State = HTTPConnectionState.Starting; 86 private HTTPConnectionState State = HTTPConnectionState.Starting;
87
69 88
70 private enum HTTPConnectionState { 89 private enum HTTPConnectionState {
71 Starting = 0, 90 Starting = 0,
72 ReceivingRequest = 1, 91 ReceivingRequest = 1,
73 ProcessingRequest = 2, 92 ProcessingRequest = 2,
74 SendingHeaders = 3, 93 SendingHeaders = 3,
75 SendingContent = 4, 94 SendingContent = 4,
76 Closed = 5, 95 Closed = 5,
77 } 96 }
78 97
79 public HTTPContext(HTTPServer server, TCPStream stream) { 98 public HTTPContext(HTTPServer server, TCPStream stream) : this(server, stream, stream.Socket) { }
99 public HTTPContext(HTTPServer server, Socket socket) : this(server, null, socket) { }
100 public HTTPContext(HTTPServer server, Stream stream, Socket socket) {
80 this.Server = server; 101 this.Server = server;
81 this.TCPStream = stream; 102 this.Socket = socket;
82 this.Socket = stream.Socket; 103 if (socket != null) {
83 this.LocalEndPoint = Socket.LocalEndPoint; 104 this.LocalEndPoint = socket.LocalEndPoint;
84 this.RemoteEndPoint = Socket.RemoteEndPoint; 105 this.RemoteEndPoint = socket.RemoteEndPoint;
106 if (stream == null) stream = new NetworkStream(socket, true);
107 }
85 Init(stream); 108 Init(stream);
86 }
87
88 public HTTPContext(HTTPServer server, Socket socket) {
89 this.Server = server;
90 this.TCPStream = null;
91 this.Socket = socket;
92 this.LocalEndPoint = socket.LocalEndPoint;
93 this.RemoteEndPoint = socket.RemoteEndPoint;
94 Init(new NetworkStream(socket, true));
95 } 109 }
96 110
97 private void Init(Stream Stream) { 111 private void Init(Stream Stream) {
98 Writer = new StreamWriter(Stream, Encoding.ASCII); 112 Writer = new StreamWriter(Stream, Encoding.ASCII);
99 Writer.NewLine = "\r\n"; 113 Writer.NewLine = "\r\n";