00001 /******************************************************************************* 00002 00003 @file HttpServer.d 00004 00005 Copyright (c) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 4. Derivative works are permitted, but they must carry this notice 00027 in full and credit the original source. 00028 00029 00030 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00031 00032 00033 @version Initial version, April 2004 00034 @author Kris 00035 00036 00037 *******************************************************************************/ 00038 00039 module mango.http.server.HttpServer; 00040 00041 private import mango.io.Exception, 00042 mango.io.ServerSocket; 00043 00044 private import mango.io.model.IConduit; 00045 00046 private import mango.log.model.ILogger; 00047 00048 private import mango.utils.ServerThread, 00049 mango.utils.AbstractServer; 00050 00051 private import mango.http.server.HttpThread, 00052 mango.http.server.HttpBridge; 00053 00054 public import mango.http.server.model.IProvider; 00055 00056 private import mango.http.server.model.IProviderBridge; 00057 00058 /****************************************************************************** 00059 00060 Extends the AbstractServer to glue all the Http support together. 00061 One should subclass this to provide a secure (https) server. 00062 00063 ******************************************************************************/ 00064 00065 class HttpServer : AbstractServer 00066 { 00067 private IProvider provider; 00068 00069 /********************************************************************** 00070 00071 Construct this server with the requisite attribites. The 00072 IProvider represents a service handler, the binding addr 00073 is the local address we'll be listening on, and 'threads' 00074 represents the number of thread to initiate. 00075 00076 **********************************************************************/ 00077 00078 this (IProvider provider, InternetAddress bind, int threads, ILogger logger = null) 00079 { 00080 this (provider, bind, threads, 10, logger); 00081 } 00082 00083 /********************************************************************** 00084 00085 Construct this server with the requisite attribites. The 00086 IProvider represents a service handler, the binding addr 00087 is the local address we'll be listening on, and 'threads' 00088 represents the number of thread to initiate. Backlog is 00089 the number of "simultaneous" connection requests that a 00090 socket layer will buffer on our behalf. 00091 00092 **********************************************************************/ 00093 00094 this (IProvider provider, InternetAddress bind, int threads, int backlog, ILogger logger = null) 00095 { 00096 super (bind, threads, backlog, logger); 00097 this.provider = provider; 00098 } 00099 00100 /********************************************************************** 00101 00102 Return the protocol in use. 00103 00104 **********************************************************************/ 00105 00106 char[] getProtocol() 00107 { 00108 return "http"; 00109 } 00110 00111 /********************************************************************** 00112 00113 Return a text string identifying this server 00114 00115 **********************************************************************/ 00116 00117 override char[] toString() 00118 { 00119 return getProtocol()~"::"~provider.toString(); 00120 } 00121 00122 /********************************************************************** 00123 00124 Create a ServerSocket instance. Secure implementations 00125 would provide a SecureSocketServer, or something along 00126 those lines. 00127 00128 **********************************************************************/ 00129 00130 override ServerSocket createSocket (InternetAddress bind, int backlog) 00131 { 00132 return new ServerSocket (bind, backlog); 00133 } 00134 00135 /********************************************************************** 00136 00137 Create a ServerThread instance. This can be overridden to 00138 create other thread-types, perhaps with additional thread- 00139 level data attached. 00140 00141 **********************************************************************/ 00142 00143 override ServerThread createThread (ServerSocket socket) 00144 { 00145 return new HttpThread (this, socket); 00146 } 00147 00148 /********************************************************************** 00149 00150 Factory method for servicing a request. We just toss the 00151 request across our bridge, for the IProvider to handle. 00152 00153 **********************************************************************/ 00154 00155 override void service (ServerThread st, IConduit conduit) 00156 { 00157 HttpThread thread; 00158 IProviderBridge bridge; 00159 00160 // we know what this is because we created it (above) 00161 thread = cast(HttpThread) st; 00162 00163 // extract thread-local HttpBridge 00164 if ((bridge = thread.getBridge()) is null) 00165 { 00166 // create a new instance if it's the first service 00167 // request on this particular thread 00168 bridge = new HttpBridge (this, provider, thread); 00169 thread.setBridge (bridge); 00170 } 00171 00172 // process request 00173 bridge.cross (conduit); 00174 } 00175 } 00176