1 17 18 package org.apache.james.imapserver; 19 20 import org.apache.avalon.cornerstone.services.connection.ConnectionHandler; 21 import org.apache.avalon.excalibur.pool.Poolable; 22 import org.apache.avalon.framework.activity.Disposable; 23 import org.apache.avalon.framework.logger.AbstractLogEnabled; 24 import org.apache.avalon.framework.logger.Logger; 25 import org.apache.avalon.framework.logger.LogEnabled; 26 import org.apache.james.Constants; 27 import org.apache.james.imapserver.commands.ImapCommand; 28 import org.apache.james.imapserver.commands.ImapCommandFactory; 29 import org.apache.james.imapserver.commands.CommandParser; 30 import org.apache.james.imapserver.store.ImapMailbox; 31 import org.apache.james.services.MailRepository; 32 import org.apache.james.services.User; 33 import org.apache.james.services.UsersRepository; 34 import org.apache.james.util.InternetPrintWriter; 35 import org.apache.james.util.watchdog.Watchdog; 36 import org.apache.james.util.watchdog.WatchdogTarget; 37 38 import java.io.BufferedOutputStream ; 39 import java.io.BufferedReader ; 40 import java.io.IOException ; 41 import java.io.InputStreamReader ; 42 import java.io.OutputStream ; 43 import java.io.PrintWriter ; 44 import java.io.Writer ; 45 import java.io.Reader ; 46 import java.io.InputStream ; 47 import java.net.Socket ; 48 49 55 public class ImapHandler 56 extends AbstractLogEnabled 57 implements ConnectionHandler, Poolable, ImapConstants 58 { 59 60 private String softwaretype = "JAMES IMAP4rev1 Server " + Constants.SOFTWARE_VERSION; 61 private ImapRequestHandler requestHandler = new ImapRequestHandler(); 62 private ImapSession session; 63 64 67 private ImapHandlerConfigurationData theConfigData; 68 69 72 private MailRepository userInbox; 73 74 77 private Thread handlerThread; 78 79 83 private Socket socket; 84 85 88 private BufferedReader in; 89 90 93 private InputStream ins; 94 95 98 private PrintWriter out; 99 100 103 private OutputStream outs; 104 105 108 private Watchdog theWatchdog; 109 110 113 private WatchdogTarget theWatchdogTarget = new IMAPWatchdogTarget(); 114 115 120 void setConfigurationData( ImapHandlerConfigurationData theData ) 121 { 122 theConfigData = theData; 123 } 124 125 130 void setWatchdog( Watchdog theWatchdog ) 131 { 132 this.theWatchdog = theWatchdog; 133 } 134 135 141 WatchdogTarget getWatchdogTarget() 142 { 143 return theWatchdogTarget; 144 } 145 146 149 void idleClose() 150 { 151 if ( getLogger() != null ) { 153 getLogger().error( "IMAP Connection has idled out." ); 154 } 155 try { 156 if ( socket != null ) { 157 socket.close(); 158 } 159 } 160 catch ( Exception e ) { 161 } 163 finally { 164 socket = null; 165 } 166 167 synchronized ( this ) { 168 if ( handlerThread != null ) { 170 handlerThread.interrupt(); 171 handlerThread = null; 172 } 173 } 174 175 } 176 177 180 public void handleConnection( Socket connection ) 181 throws IOException 182 { 183 184 String remoteHost = ""; 185 String remoteIP = ""; 186 187 try { 188 this.socket = connection; 189 synchronized ( this ) { 190 handlerThread = Thread.currentThread(); 191 } 192 ins = socket.getInputStream(); 193 in = new BufferedReader ( new InputStreamReader ( socket.getInputStream(), "ASCII" ), 512 ); 194 remoteIP = socket.getInetAddress().getHostAddress(); 195 remoteHost = socket.getInetAddress().getHostName(); 196 } 197 catch ( IOException e ) { 198 if ( getLogger().isErrorEnabled() ) { 199 StringBuffer exceptionBuffer = 200 new StringBuffer ( 256 ) 201 .append( "Cannot open connection from " ) 202 .append( remoteHost ) 203 .append( " (" ) 204 .append( remoteIP ) 205 .append( "): " ) 206 .append( e.getMessage() ); 207 getLogger().error( exceptionBuffer.toString(), e ); 208 } 209 throw e; 210 } 211 212 if ( getLogger().isInfoEnabled() ) { 213 StringBuffer logBuffer = 214 new StringBuffer ( 128 ) 215 .append( "Connection from " ) 216 .append( remoteHost ) 217 .append( " (" ) 218 .append( remoteIP ) 219 .append( ") " ); 220 getLogger().info( logBuffer.toString() ); 221 } 222 223 try { 224 outs = new BufferedOutputStream ( socket.getOutputStream(), 1024 ); 225 out = new InternetPrintWriter( outs, true ); 226 ImapResponse response = new ImapResponse( outs ); 227 228 StringBuffer responseBuffer = 230 new StringBuffer ( 256 ) 231 .append( VERSION ) 232 .append( " Server " ) 233 .append( theConfigData.getHelloName() ) 234 .append( " ready" ); 235 response.okResponse( null, responseBuffer.toString() ); 236 237 session = new ImapSessionImpl( theConfigData.getImapHost(), 238 theConfigData.getUsersRepository(), 239 this, 240 socket.getInetAddress().getHostName(), 241 socket.getInetAddress().getHostAddress()); 242 243 theWatchdog.start(); 244 while ( requestHandler.handleRequest( ins, outs, session ) ) { 245 theWatchdog.reset(); 246 } 247 theWatchdog.stop(); 248 249 if ( getLogger().isInfoEnabled() ) { 251 StringBuffer logBuffer = 252 new StringBuffer ( 128 ) 253 .append( "Connection for " ) 254 .append( session.getUser().getUserName() ) 255 .append( " from " ) 256 .append( remoteHost ) 257 .append( " (" ) 258 .append( remoteIP ) 259 .append( ") closed." ); 260 getLogger().info( logBuffer.toString() ); 261 } 262 263 } 264 catch ( Exception e ) { 265 out.println( "Error closing connection." ); 266 out.flush(); 267 StringBuffer exceptionBuffer = 268 new StringBuffer ( 128 ) 269 .append( "Exception on connection from " ) 270 .append( remoteHost ) 271 .append( " (" ) 272 .append( remoteIP ) 273 .append( ") : " ) 274 .append( e.getMessage() ); 275 getLogger().error( exceptionBuffer.toString(), e ); 276 } 277 finally { 278 resetHandler(); 279 } 280 } 281 282 285 void resetHandler() 286 { 287 288 if ( theWatchdog != null ) { 289 if ( theWatchdog instanceof Disposable ) { 290 ( ( Disposable ) theWatchdog ).dispose(); 291 } 292 theWatchdog = null; 293 } 294 295 297 try { 298 if ( socket != null ) { 299 socket.close(); 300 socket = null; 301 } 302 } 303 catch ( IOException ioe ) { 304 } 306 finally { 307 socket = null; 308 } 309 310 try { 311 if ( in != null ) { 312 in.close(); 313 } 314 } 315 catch ( Exception e ) { 316 } 318 finally { 319 in = null; 320 } 321 322 try { 323 if ( out != null ) { 324 out.close(); 325 } 326 } 327 catch ( Exception e ) { 328 } 330 finally { 331 out = null; 332 } 333 334 try { 335 if ( outs != null ) { 336 outs.close(); 337 } 338 } 339 catch ( Exception e ) { 340 } 342 finally { 343 outs = null; 344 } 345 346 synchronized ( this ) { 347 handlerThread = null; 348 } 349 350 session = null; 352 353 theConfigData = null; 355 } 356 357 366 private void stat() 367 { 368 } 382 383 391 private final void logResponseString( String responseString ) 392 { 393 if ( getLogger().isDebugEnabled() ) { 394 getLogger().debug( "Sent: " + responseString ); 395 } 396 } 397 398 405 final void writeLoggedFlushedResponse( String responseString ) 406 { 407 out.println( responseString ); 408 out.flush(); 409 logResponseString( responseString ); 410 } 411 412 418 final void writeLoggedResponse( String responseString ) 419 { 420 out.println( responseString ); 421 logResponseString( responseString ); 422 } 423 424 429 private class IMAPWatchdogTarget 430 implements WatchdogTarget 431 { 432 433 436 public void execute() 437 { 438 ImapHandler.this.idleClose(); 439 } 440 441 } 442 443 } 444 445 | Popular Tags |