~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to src/core/NU-SimiasAspService/.svn/text-base/XSPApplicationHost.cs.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
****************************************************************************
2
 
 |
3
 
 | Copyright (c) 2007 Novell, Inc.
4
 
 | All Rights Reserved.
5
 
 |
6
 
 | This program is free software; you can redistribute it and/or
7
 
 | modify it under the terms of version 2 of the GNU General Public License as
8
 
 | published by the Free Software Foundation.
9
 
 |
10
 
 | This program is distributed in the hope that it will be useful,
11
 
 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 | GNU General Public License for more details.
14
 
 |
15
 
 | You should have received a copy of the GNU General Public License
16
 
 | along with this program; if not, contact Novell, Inc.
17
 
 |
18
 
 | To contact Novell about this file by physical or electronic mail,
19
 
 | you may find current contact information at www.novell.com 
20
 
 |
21
 
 | Authors:
22
 
 |      Gonzalo Paniagua Javier (gonzalo@ximian.com)
23
 
 |      Lluis Sanchez Gual (lluis@ximian.com)
24
 
 |***************************************************************************/
25
 
 
26
 
using System;
27
 
using System.IO;
28
 
using System.Net;
29
 
using System.Net.Sockets;
30
 
using System.Text;
31
 
using System.Web;
32
 
 
33
 
namespace Mono.ASPNET
34
 
{
35
 
        //
36
 
        // XSPWebSource: Provides methods to get objects and types specific
37
 
        // to XSP.
38
 
        //
39
 
        public class XSPWebSource: IWebSource
40
 
        {
41
 
                IPEndPoint bindAddress;
42
 
                
43
 
                public XSPWebSource (IPAddress address, int port)
44
 
                {
45
 
                        SetListenAddress (address, port);
46
 
                }
47
 
                
48
 
                public void SetListenAddress (int port)
49
 
                {
50
 
                        SetListenAddress (IPAddress.Any, port);
51
 
                }
52
 
 
53
 
                public void SetListenAddress (IPAddress address, int port) 
54
 
                {
55
 
                        SetListenAddress (new IPEndPoint (address, port));
56
 
                }
57
 
                
58
 
                public void SetListenAddress (IPEndPoint bindAddress)
59
 
                {
60
 
                        if (bindAddress == null)
61
 
                                throw new ArgumentNullException ("bindAddress");
62
 
 
63
 
                        this.bindAddress = bindAddress;
64
 
                }
65
 
                
66
 
                public Socket CreateSocket ()
67
 
                {
68
 
                        Socket listen_socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
69
 
                        listen_socket.Bind (bindAddress);
70
 
                        return listen_socket;
71
 
                } 
72
 
 
73
 
                public IWorker CreateWorker (Socket client, ApplicationServer server)
74
 
                {
75
 
                        return new XSPWorker (client, client.LocalEndPoint, server);
76
 
                }
77
 
                
78
 
                public Type GetApplicationHostType ()
79
 
                {
80
 
                        return typeof (XSPApplicationHost);
81
 
                }
82
 
                
83
 
                public IRequestBroker CreateRequestBroker ()
84
 
                {
85
 
                        return new XSPRequestBroker ();
86
 
                }
87
 
        }
88
 
        
89
 
        //
90
 
        // XSPRequestBroker: The request broker for XSP. Provides some
91
 
        // additional methods to the BaseRequestBroker from which inherits.
92
 
        //
93
 
        public class XSPRequestBroker: BaseRequestBroker
94
 
        {
95
 
                public bool IsConnected (int requestId)
96
 
                {
97
 
                        return ((XSPWorker)GetWorker (requestId)).IsConnected ();
98
 
                }
99
 
        }
100
 
        
101
 
        //
102
 
        // XSPApplicationHost: The application host for XSP.
103
 
        //
104
 
        public class XSPApplicationHost : BaseApplicationHost
105
 
        {
106
 
                public void ProcessRequest (int reqId, string localEPAddr, int localEPPort, string remoteEPAdds,
107
 
                                        int remoteEPPort, string verb, string path, string pathInfo,
108
 
                                        string queryString, string protocol, byte [] inputBuffer, string redirect)
109
 
                {
110
 
                        XSPRequestBroker broker = (XSPRequestBroker) RequestBroker;
111
 
                        IPEndPoint localEP = new IPEndPoint (IPAddress.Parse (localEPAddr), localEPPort);
112
 
                        IPEndPoint remoteEP = new IPEndPoint (IPAddress.Parse (remoteEPAdds), remoteEPPort);
113
 
                        XSPWorkerRequest mwr = new XSPWorkerRequest (reqId, broker, this, localEP, remoteEP, verb, path,
114
 
                                                                pathInfo, queryString, protocol, inputBuffer);
115
 
 
116
 
                        if (redirect != null) {
117
 
                                Redirect (mwr, redirect);
118
 
                                return;
119
 
                        }
120
 
 
121
 
                        ProcessRequest (mwr);
122
 
                }
123
 
 
124
 
                static string content301 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
125
 
                                "<html><head>\n<title>301 Moved Permanently</title>\n</head><body>\n" +
126
 
                                "<h1>Moved Permanently</h1>\n" +
127
 
                                "<p>The document has moved to <a href='http://{0}{1}'>http://{0}{1}</a>.</p>\n" +
128
 
                                "</body></html>\n";
129
 
 
130
 
                static void Redirect (XSPWorkerRequest wr, string location)
131
 
                {
132
 
                        string host = wr.GetKnownRequestHeader (HttpWorkerRequest.HeaderHost);
133
 
                        wr.SendStatus (301, "Moved Permanently");
134
 
                        wr.SendUnknownResponseHeader ("Connection", "close");
135
 
                        wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
136
 
                        wr.SendUnknownResponseHeader ("Location", String.Format ("http://{0}{1}", host, location));
137
 
                        Encoding enc = Encoding.ASCII;
138
 
                        wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
139
 
                        string content = String.Format (content301, host, location);
140
 
                        byte [] contentBytes = enc.GetBytes (content);
141
 
                        wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
142
 
                        wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
143
 
                        wr.FlushResponse (true);
144
 
                        wr.CloseConnection ();
145
 
                }
146
 
 
147
 
                static string GetValueFromHeader (string header, string attr)
148
 
                {
149
 
                        int where = header.IndexOf (attr + '=');
150
 
                        if (where == -1)
151
 
                                return null;
152
 
 
153
 
                        where += attr.Length + 1;
154
 
                        int max = header.Length;
155
 
                        if (where >= max)
156
 
                                return String.Empty;
157
 
 
158
 
                        char ending = header [where];
159
 
                        if (ending != '"')
160
 
                                ending = ' ';
161
 
 
162
 
                        int end = header.Substring (where + 1).IndexOf (ending);
163
 
                        if (end == -1)
164
 
                                return (ending == '"') ? null : header.Substring (where);
165
 
 
166
 
                        return header.Substring (where, end);
167
 
                }
168
 
        }
169
 
        
170
 
        //
171
 
        // XSPWorker: The worker that do the initial processing of XSP
172
 
        // requests.
173
 
        //
174
 
        internal class XSPWorker: IWorker
175
 
        {
176
 
                ApplicationServer server;
177
 
                LingeringNetworkStream stream;
178
 
                RequestData rdata;
179
 
                IPEndPoint remoteEP;
180
 
                IPEndPoint localEP;
181
 
 
182
 
                public XSPWorker (Socket client, EndPoint localEP, ApplicationServer server)
183
 
                {
184
 
                        stream = new LingeringNetworkStream (client, true);
185
 
                        this.server = server;
186
 
 
187
 
                        try {
188
 
                                remoteEP = (IPEndPoint) client.RemoteEndPoint;
189
 
                        } catch { }
190
 
                        this.localEP = (IPEndPoint) localEP;
191
 
                }
192
 
 
193
 
                public void Run (object state)
194
 
                {
195
 
                        int requestId = -1;
196
 
                        XSPRequestBroker broker = null;
197
 
                        
198
 
                        try {
199
 
                                if (remoteEP == null)
200
 
                                        return;
201
 
 
202
 
                                InitialWorkerRequest ir = new InitialWorkerRequest (stream);
203
 
                                ir.ReadRequestData ();
204
 
                                RequestData rdata = ir.RequestData;
205
 
                                string vhost = null; // TODO: read the headers in InitialWorkerRequest
206
 
                                int port = ((IPEndPoint) localEP).Port;
207
 
                                
208
 
                                VPathToHost vapp = server.GetApplicationForPath (vhost, port, rdata.Path, true);
209
 
                                XSPApplicationHost host = null;
210
 
                                if (vapp != null)
211
 
                                        host = (XSPApplicationHost) vapp.AppHost;
212
 
 
213
 
                                if (host == null) {
214
 
                                        byte [] nf = HttpErrors.NotFound (rdata.Path);
215
 
                                        stream.Write (nf, 0, nf.Length);
216
 
                                        stream.Close ();
217
 
                                        return;
218
 
                                }
219
 
                                
220
 
                                broker = (XSPRequestBroker) vapp.RequestBroker;
221
 
                                requestId = broker.RegisterRequest (this);
222
 
                                
223
 
                                string redirect;
224
 
                                vapp.Redirect (rdata.Path, out redirect);
225
 
                                host.ProcessRequest (requestId, localEP.Address.ToString(), localEP.Port,
226
 
                                                remoteEP.Address.ToString(), remoteEP.Port, rdata.Verb,
227
 
                                                rdata.Path, rdata.PathInfo, rdata.QueryString,
228
 
                                                rdata.Protocol, rdata.InputBuffer, redirect);
229
 
                        } catch (Exception e) {
230
 
                                Console.WriteLine (e);
231
 
                                try {
232
 
                                        if (!(e is IOException)) {
233
 
                                                byte [] error = HttpErrors.ServerError ();
234
 
                                                stream.Write (error, 0, error.Length);
235
 
                                        }
236
 
                                        stream.Close ();
237
 
                                } catch {}
238
 
                        } finally {
239
 
                                if (requestId != -1)
240
 
                                        broker.UnregisterRequest (requestId);
241
 
                        }
242
 
                }
243
 
 
244
 
                public int Read (byte[] buffer, int position, int size)
245
 
                {
246
 
                        return stream.Read (buffer, position, size);
247
 
                }
248
 
                
249
 
                public void Write (byte[] buffer, int position, int size)
250
 
                {
251
 
                        stream.Write (buffer, position, size);
252
 
                }
253
 
                
254
 
                public void Close ()
255
 
                {
256
 
                        stream.Close ();
257
 
                }
258
 
                
259
 
                public bool IsConnected ()
260
 
                {
261
 
                        return stream.Connected;
262
 
                }
263
 
 
264
 
                public void Flush ()
265
 
                {
266
 
                        stream.Flush ();
267
 
                }
268
 
        }
269
 
}