Mercurial > hg > ucis.core
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"; |