All pastes #803488 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-12-01 08:15 UTC
rendered paste body
public class WebServer
	{
		
		public const string STATUS_CODE_OK = " 200 OK";
		public const string STATUS_CODE_NOT_FOUND = " 404 Not Found";
		public const string STATUS_CODE_CONTINUE = " 100 Continue";
		public const string STATUS_CODE_SWITCHING_PROTICOLS = " 101 Switching Protocols";
		public const string STATUS_CODE_NON_AUTHORITATIVE_INFO = " 203 Non-Authoritative Information";
		public const string STATUS_CODE_NO_CONENT = " 204 No Content";
		public const string STATUS_CODE_RESET_CONENT = " 205 Reset Content";
		public const string STATUS_CODE_TEMPORARY_REDIRECT = " 307 Temporary Redirect";
		public const string STATUS_CODE_BAD_REQUEST = " 400 Bad Request";
		public const string STATUS_CODE_UNAUTHORIZED = " 401 Unauthorized";
		public const string STATUS_CODE_FORBIDDEN = " 403 Forbidden";

		private byte[] _buffer;
		private TcpListener _listener;
		private string _lastPageRequest;
		private Dictionary<string, string> _mimeTypes;

		/// <summary>
		/// The last requested url
		/// </summary>
		public string LastPageRequest 
		{ 
			get 
			{ 
				if( _lastPageRequest == string.Empty ) 
					_lastPageRequest = "http://localhost.:1980/home.html?page=1"; 
				
				return _lastPageRequest; 
			} 
		}

		public WebServer()
		{
			_mimeTypes = LoadMimeTypes();

			try
			{
				_listener = new TcpListener(IPAddress.Loopback, 1980);
				_listener.Start(5000);

				Thread th = new Thread(new ThreadStart(StartListen));
				th.Start();
			}
			catch (Exception e)
			{
				Trace.HandleException(e);
			}
		}

		private Dictionary<string, string> LoadMimeTypes()
		{
			//Create the dictionary for the mimetypes
			Dictionary<string, string> mimeTypes = new Dictionary<string, string>();

			//Check if our mimetypes.dat file exists
			if (File.Exists(Path.Combine(Core.BaseDirectory, "mimetypes.dat")))
			{
				//Create a reader for the mimetype data
				StreamReader reader = File.OpenText(Path.Combine(Core.BaseDirectory, "mimetypes.dat"));

				//While the reader has not reached the end of the file.
				while (!reader.EndOfStream)
				{
					//Read a line of data
					string line = reader.ReadLine();
					//Split it into 2 strings
					string[] pair = line.Split('|');

					//If it isnt 2 strings we dont want to use it
					if (pair.Length != 2)
						continue;

					//If the mimeType dictionary doesnt contain the key for we add it.
					if( !mimeTypes.ContainsKey(pair[0]) )
						mimeTypes.Add(pair[0], pair[1]);
				}

				//Close the reader
				reader.Close();
			}

			//Return the mimetypes
			return mimeTypes;
		}

		public string GetMimeType(string fileName)
		{
			if (_mimeTypes.ContainsKey(Path.GetExtension(fileName).Trim()))
				return _mimeTypes[Path.GetExtension(fileName)];
			else
				return "";
		}

		/// <summary>
		/// Closes the listener socket
		/// </summary>
		public void Close()
		{
			if( _listener != null )
				_listener.Stop();
		}

		/// <summary>
		/// Sends the specified message to the browser
		/// </summary>
		/// <param name="message"></param>
		/// <param name="socket"></param>
		public void SendToBrowser(string message, ref Socket socket)
		{
			SendToBrowser(Encoding.ASCII.GetBytes(message), ref socket);
		}

		/// <summary>
		/// Sends the specified message to the browser
		/// </summary>
		/// <param name="buffer"></param>
		/// <param name="socket"></param>
		public void SendToBrowser(Byte[] buffer, ref Socket socket)
		{
			int resp = 0;

			try
			{
				if( socket.Connected )
				{
					if( ( resp = socket.Send(buffer, buffer.Length, 0) ) == -1 )
						socket.Close();					
				}
			}
			catch
			{
				socket.Close();	
			}
		}

		public void SendHeader(string httpVersion, string mimeHeader, int length, string statusCode, ref Socket socket)
		{
			string header = "";

			// if Mime type is not provided set default to text/html
			if (mimeHeader.Length == 0)
				mimeHeader = "text/html";  // Default Mime Type is text/html

			//Build the header to send to the browser
			header += httpVersion + statusCode + "\r\n";
			header += "Server: ConnectUO Desktop-b\r\n";
			header += "Content-Type: " + mimeHeader + "\r\n";
			header += "Accept-Ranges: bytes\r\n";
			header += "Content-Length: " + length + "\r\n\r\n";

			//Send the header to the browser
			SendToBrowser(header, ref socket);
		}

		private void StartListen()
		{
			int startPos = 0;
			string request;

			while( true )
			{
				Socket socket = null;

				try
				{
					socket = _listener.AcceptSocket();

					if (!socket.RemoteEndPoint.ToString().Contains("127.0.0.1"))
						socket.Close();

					if (socket.Connected)
					{
						if (_buffer == null)
							_buffer = new byte[1024];

						int i = socket.Receive(_buffer, _buffer.Length, 0);

						string httpRequest = Encoding.ASCII.GetString(_buffer);
						startPos = httpRequest.IndexOf("HTTP", 1);
						string ver = httpRequest.Substring(startPos, 8);
						request = httpRequest.Substring(5, startPos - 5);
						request = request.Trim();

						if (request.Length <= 1)
							request = "home.html?page=1";
						
						if (IsTemplateFileRequest(request))
						{	
							string[] split = request.Split('?');
							string ext = Path.GetExtension(split[0]);

							string getData = split.Length > 1 ? split[1].Trim() : "";
                            getData = Uri.UnescapeDataString(getData);						
                             
                            ext.Trim();

							if (ext.Contains(".html"))
							{
								string output = PageCompiler.CompileCode(Path.Combine(Templates.CurrentTemplate.RootDirectory, split[0]), getData);

								SendHeader(ver, GetMimeType(split[0]), output.Length, STATUS_CODE_OK, ref socket);
								SendToBrowser(output, ref socket);
							}
							else
							{
								FileStream fs = new FileStream(Path.Combine(Templates.CurrentTemplate.RootDirectory, split[0]), FileMode.Open);
								byte[] send = new byte[fs.Length];

								fs.Read(send, 0, send.Length);
								fs.Close();

								SendHeader(ver, GetMimeType(split[0]), send.Length, STATUS_CODE_OK, ref socket);
								SendToBrowser(send, ref socket);
							}
						}
						else
						{
							HandleRequest(request, ref socket);
						}

						_lastPageRequest = "http://localhost.:1980/" + request;
						socket.Close();
					}
				}
				catch
				{
					if (socket != null && socket.Connected)
						socket.Close();
				}
			}
		}

        private bool IsTemplateFileRequest(string request)
        {
            return Templates.CurrentTemplate.ContainsFile(request);
        }

		private void HandleRequest(string request, ref Socket socket)
		{
			string orig = request;
			string[] strings = request.Split(new char[] { '?' }, 2);

			if( strings.Length > 1 )
				request = strings[1].Trim();
			else
				request = "";

			strings[0] = strings[0].Trim();

			PageHandler handler;

			if( PageHandlers.Handlers.TryGetValue( strings[0], out handler ) )
			{				
				if( handler.Validate( request ) )
					handler.OnRequest( request, handler.Compiler, ref socket );
			}
		}
	}