2005-04-15 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / Mono.Security / Test / tools / tlstest / tlsasync.cs
1 //
2 // tlsasync.cs: Multi-sessions TLS/SSL Test Program with async streams
3 //      based on tlstest.cs and tlsmulti.cs
4 //
5 // Author:
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // Copyright (C) 2004-2005 Novell (http://www.novell.com)
9 //
10
11 using System;
12 using System.Collections;
13 using System.Globalization;
14 using System.IO;
15 using System.Net;
16 using System.Net.Sockets;
17 using System.Reflection;
18 using System.Security.Cryptography.X509Certificates;
19 using System.Text;
20 using System.Threading;
21
22 using Mono.Security.Protocol.Tls;
23
24 public class State {
25
26         static ArrayList handleList = new ArrayList ();
27
28         private int id;
29         private HttpWebRequest request;
30         private ManualResetEvent handle;
31         private Stream stream;
32         private byte[] buffer;
33         private MemoryStream memory;
34
35         public State (int id, HttpWebRequest req)
36         {
37                 this.id = id;
38                 request = req;
39                 handle = new ManualResetEvent (false);
40                 handleList.Add (handle);
41         }
42
43         public int Id {
44                 get { return id; }
45         }
46
47         public HttpWebRequest Request {
48                 get { return request; }
49         }
50
51         public Stream Stream {
52                 get { return stream; }
53                 set { stream = value; }
54         }
55
56         public byte[] Buffer {
57                 get {
58                         if (buffer == null)
59                                 buffer = new byte [256]; // really small on purpose
60                         return buffer;
61                 }
62         }
63
64         public Stream Memory {
65                 get {
66                         if (memory == null)
67                                 memory = new MemoryStream ();
68                         return memory;
69                 }
70         }
71
72         public void Complete ()
73         {
74                 handle.Set ();
75         }
76
77         static public void WaitAll ()
78         {
79                 if (handleList.Count > 0) {
80                         WaitHandle[] handles = (WaitHandle[]) handleList.ToArray (typeof (WaitHandle));
81                         WaitHandle.WaitAll (handles);
82                         handleList.Clear ();
83                 }
84         }
85 }
86
87 public class MultiTest {
88
89         static bool alone;
90
91         public static void Main (string[] args) 
92         {
93                 if (args.Length == 0) {
94                         Console.WriteLine ("usage: mono tlsaync.exe url1 [url ...]");
95                         return;
96                 } else if (args.Length > 64) {
97                         Console.WriteLine ("WaitHandle has a limit of 64 handles so you cannot process {0} URLs.", args.Length);
98                         return;
99                 }
100
101                 alone = (args.Length == 1);
102                 ServicePointManager.CertificatePolicy = new TestCertificatePolicy ();
103
104                 int id = 1;
105                 foreach (string url in args) {
106                         Console.WriteLine ("GET #{0} at {1}", id, url);
107                         HttpWebRequest wreq = (HttpWebRequest) WebRequest.Create (url);
108                         State s = new State (id++, wreq);
109                         wreq.BeginGetResponse (new AsyncCallback (ResponseCallback), s);
110                 }
111
112                 State.WaitAll ();
113         }
114
115         private static void ResponseCallback (IAsyncResult result)
116         {
117                 State state = ((State) result.AsyncState);
118                 HttpWebResponse response = (HttpWebResponse) state.Request.EndGetResponse (result);
119                 state.Stream = response.GetResponseStream ();
120                 state.Stream.BeginRead (state.Buffer, 0, state.Buffer.Length, new AsyncCallback (StreamCallBack), state);
121         }
122
123         private static void StreamCallBack (IAsyncResult result)
124         {
125                 State state = ((State) result.AsyncState);
126                 int length = state.Stream.EndRead (result);
127                 if (length > 0) {
128                         state.Memory.Write (state.Buffer, 0, length);
129                         state.Stream.BeginRead (state.Buffer, 0, state.Buffer.Length, new AsyncCallback (StreamCallBack), state);
130                 } else {
131                         state.Stream.Close ();
132                         if (alone) {
133                                 state.Memory.Position = 0;
134                                 StreamReader sr = new StreamReader (state.Memory, Encoding.UTF8);
135                                 Console.WriteLine (sr.ReadToEnd ());
136                         }
137                         Console.WriteLine ("END #{0}", state.Id);
138                         state.Complete ();
139                 }
140         }
141
142         public class TestCertificatePolicy : ICertificatePolicy {
143
144                 public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
145                 {
146                         // whatever the reason we do not stop the SSL connection
147                         return true;
148                 }
149         }
150 }