package net.i2p.i2ptunnel.irc; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import net.i2p.client.streaming.I2PSocket; import net.i2p.util.Log; /** * Thread to do outbound filtering. * Moved from I2PTunnelIRCClient.java * * @since 0.8.9 */ public class IrcOutboundFilter implements Runnable { private final Socket local; private final I2PSocket remote; private final StringBuffer expectedPong; private final Log _log; private final DCCHelper _dccHelper; public IrcOutboundFilter(Socket lcl, I2PSocket rem, StringBuffer pong, Log log) { this(lcl, rem, pong, log, null); } /** * @param helper may be null * @since 0.8.9 */ public IrcOutboundFilter(Socket lcl, I2PSocket rem, StringBuffer pong, Log log, DCCHelper helper) { local = lcl; remote = rem; expectedPong = pong; _log = log; _dccHelper = helper; } public void run() { // Todo: Don't use BufferedReader - IRC spec limits line length to 512 but... BufferedReader in; OutputStream output; try { in = new BufferedReader(new InputStreamReader(local.getInputStream(), "ISO-8859-1")); output=remote.getOutputStream(); } catch (IOException e) { if (_log.shouldLog(Log.WARN)) _log.warn("IrcOutboundFilter: no streams",e); return; } if (_log.shouldLog(Log.DEBUG)) _log.debug("IrcOutboundFilter: Running."); try { while(true) { try { String inmsg = in.readLine(); if(inmsg==null) break; if(inmsg.endsWith("\r")) inmsg=inmsg.substring(0,inmsg.length()-1); if (_log.shouldLog(Log.DEBUG)) _log.debug("out: [" + inmsg + "]"); String outmsg = IRCFilter.outboundFilter(inmsg, expectedPong, _dccHelper); if(outmsg!=null) { if(!inmsg.equals(outmsg)) { if (_log.shouldLog(Log.WARN)) { _log.warn("outbound FILTERED: "+outmsg); _log.warn(" - outbound was: "+inmsg); } } else { if (_log.shouldLog(Log.INFO)) _log.info("outbound: "+outmsg); } outmsg=outmsg+"\r\n"; // rfc1459 sec. 2.3 output.write(outmsg.getBytes("ISO-8859-1")); // save 250 ms in streaming // Check ready() so we don't split the initial handshake up into multiple streaming messages if (!in.ready()) output.flush(); } else { if (_log.shouldLog(Log.WARN)) _log.warn("outbound BLOCKED: "+"\""+inmsg+"\""); } } catch (IOException e1) { if (_log.shouldLog(Log.WARN)) _log.warn("IrcOutboundFilter: disconnected",e1); break; } } } catch (RuntimeException re) { _log.error("Error filtering outbound data", re); } finally { try { remote.close(); } catch (IOException e) {} } if (_log.shouldLog(Log.DEBUG)) _log.debug("IrcOutboundFilter: Done."); } }