Merge pull request #225 from mistoll/master
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.CORBA / CORBAServerChannel.cs
1 //
2 // System.Runtime.Remoting.Channels.CORBA.CORBAServerChannel.cs
3 //
4 // Author: Dietmar Maurer (dietmar@ximian.com)
5 //
6 // 2002 (C) Copyright, Ximian, Inc.
7 //
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Collections;
31 using System.Runtime.Remoting.Messaging;
32 using System.Text.RegularExpressions;
33 using System.Net.Sockets;
34 using System.Net;
35 using System.Threading;
36 using System.IO;
37
38 namespace System.Runtime.Remoting.Channels.CORBA
39 {
40         public class CORBAServerChannel : IChannelReceiver, IChannel
41         {
42                 int port = 0;
43                 string name = "simple";
44                 string host;
45                 int priority = 1;
46                 Thread server_thread = null;
47                 TcpListener listener;
48                 CORBAServerTransportSink sink;
49                 ChannelDataStore channel_data;
50                 
51                 void Init (IServerChannelSinkProvider provider) {
52                         if (provider == null) {
53                                 provider = new CORBAServerFormatterSinkProvider ();
54                         }
55                         
56                         IServerChannelSink next_sink = ChannelServices.CreateServerChannelSinkChain (provider, this);
57
58                         host = Dns.GetHostByName(Dns.GetHostName()).HostName;
59                         
60                         string [] uris = null;
61                         
62                         if (port != 0) {
63                                 uris = new String [1];
64                                 uris [0] = GetChannelUri ();
65                         }
66                         
67                         channel_data = new ChannelDataStore (uris);;
68
69                         sink = new CORBAServerTransportSink (next_sink);
70                         
71                         listener = new TcpListener (port);
72                         StartListening (null);
73                 }
74                 
75                 public CORBAServerChannel (int port)
76                 {
77                         this.port = port;
78                         Init (null);
79                 }
80
81                 public CORBAServerChannel (IDictionary properties,
82                                          IServerChannelSinkProvider serverSinkProvider)
83                 {
84                         port = (int)properties ["port"];
85                         Init (serverSinkProvider);
86                 }
87
88                 public CORBAServerChannel (string name, int port,
89                                             IServerChannelSinkProvider serverSinkProvider)
90                 {
91                         name = name;
92                         this.port = port;
93                         Init (serverSinkProvider);
94                 }
95                 
96                 public CORBAServerChannel (string name, int port)
97                 {
98                         name = name;
99                         this.port = port;
100                         Init (null);
101                 }
102                 
103                 public object ChannelData
104                 {
105                         get {
106                                 return channel_data;
107                         }
108                 }
109
110                 public string ChannelName
111                 {
112                         get {
113                                 return name;
114                         }
115                 }
116
117                 public int ChannelPriority
118                 {
119                         get {
120                                 return priority;
121                         }
122                 }
123
124                 string GetChannelUri ()
125                 {
126                         return "corba://" + host + ":" + port;
127                 }
128                 
129                 public string[] GetUrlsForUri (string uri)
130                 {
131                         string [] chnl_uris = channel_data.ChannelUris;
132                         
133                         if (uri.IndexOf ('/') != 0)
134                                 uri = "/" + uri;
135
136                         string [] result = new String [chnl_uris.Length];
137
138                         for (int i = 0; i < chnl_uris.Length; i++) {
139                                 result [i] = chnl_uris [i] + uri;
140                         }
141                         
142                         return result;
143                 }
144
145                 public string Parse (string url, out string objectURI)
146                 {
147                         int port;
148                         
149                         string host = CORBAChannel.ParseCORBAURL (url, out objectURI, out port);
150
151                         return GetChannelUri ();
152                 }
153
154                 void WaitForConnections ()
155                 {
156                         while (true) {
157                                 TcpClient client = listener.AcceptTcpClient ();
158
159                                 sink.InternalProcessMessage (client.GetStream ());
160
161                                 client.Close ();
162                         }
163                 }
164                 
165                 public void StartListening (object data)
166                 {
167                         if (server_thread == null) {
168                                 listener.Start ();
169                                 if (port == 0) {
170                                         port = ((IPEndPoint)listener.LocalEndpoint).Port;
171                                         channel_data.ChannelUris = new String [1];
172                                         channel_data.ChannelUris [0] = GetChannelUri ();
173                                 }
174
175                                 server_thread = new Thread (new ThreadStart (WaitForConnections));
176                                 server_thread.Start ();
177                         }
178                 }
179
180                 public void StopListening (object data)
181                 {
182                         if (server_thread != null) {
183                                 server_thread.Abort ();
184                                 server_thread = null;
185                                 listener.Stop ();
186                         }
187                 }
188         }
189 }