1 11 12 package org.jivesoftware.messenger.net; 13 14 import org.jivesoftware.messenger.*; 15 import org.jivesoftware.messenger.auth.UnauthorizedException; 16 import org.jivesoftware.messenger.interceptor.InterceptorManager; 17 import org.jivesoftware.messenger.interceptor.PacketRejectedException; 18 import org.jivesoftware.util.LocaleUtils; 19 import org.jivesoftware.util.Log; 20 import org.xmpp.packet.Packet; 21 22 import java.io.BufferedWriter ; 23 import java.io.IOException ; 24 import java.io.OutputStreamWriter ; 25 import java.io.Writer ; 26 import java.net.InetAddress ; 27 import java.net.Socket ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 32 39 public class SocketConnection implements Connection { 40 41 44 public static final String CHARSET = "UTF-8"; 45 46 private Map listeners = new HashMap (); 47 48 private Socket socket; 49 50 private Writer writer; 51 52 private PacketDeliverer deliverer; 53 54 private Session session; 55 private boolean secure; 56 private org.jivesoftware.util.XMLWriter xmlSerializer; 57 private boolean flashClient = false; 58 private int majorVersion = 1; 59 private int minorVersion = 0; 60 private String language = null; 61 62 70 public SocketConnection(PacketDeliverer deliverer, Socket socket, boolean isSecure) 71 throws IOException 72 { 73 if (socket == null) { 74 throw new NullPointerException ("Socket channel must be non-null"); 75 } 76 77 this.secure = isSecure; 78 this.socket = socket; 79 writer = new BufferedWriter (new OutputStreamWriter (socket.getOutputStream(), CHARSET)); 80 this.deliverer = deliverer; 81 xmlSerializer = new XMLSocketWriter(writer, socket); 82 } 83 84 public boolean validate() { 85 if (isClosed()) { 86 return false; 87 } 88 try { 89 synchronized (writer) { 90 SocketSendingTracker.getInstance().socketStartedSending(socket); 92 writer.write(" "); 93 writer.flush(); 94 } 95 } 96 catch (Exception e) { 97 Log.warn("Closing no longer valid connection" + "\n" + this.toString(), e); 98 close(); 99 } 100 finally { 101 SocketSendingTracker.getInstance().socketFinishedSending(socket); 103 } 104 return !isClosed(); 105 } 106 107 public void init(Session owner) { 108 session = owner; 109 } 110 111 public Object registerCloseListener(ConnectionCloseListener listener, Object handbackMessage) { 112 Object status = null; 113 if (isClosed()) { 114 listener.onConnectionClose(handbackMessage); 115 } 116 else { 117 status = listeners.put(listener, handbackMessage); 118 } 119 return status; 120 } 121 122 public Object removeCloseListener(ConnectionCloseListener listener) { 123 return listeners.remove(listener); 124 } 125 126 public InetAddress getInetAddress() { 127 return socket.getInetAddress(); 128 } 129 130 public Writer getWriter() { 131 return writer; 132 } 133 134 public boolean isClosed() { 135 if (session == null) { 136 return socket.isClosed(); 137 } 138 return session.getStatus() == Session.STATUS_CLOSED; 139 } 140 141 public boolean isSecure() { 142 return secure; 143 } 144 145 public int getMajorXMPPVersion() { 146 return majorVersion; 147 } 148 149 public int getMinorXMPPVersion() { 150 return minorVersion; 151 } 152 153 161 public void setXMPPVersion(int majorVersion, int minorVersion) { 162 this.majorVersion = majorVersion; 163 this.minorVersion = minorVersion; 164 } 165 166 public String getLanguage() { 167 return language; 168 } 169 170 175 public void setLanaguage(String language) { 176 this.language = language; 177 } 178 179 public boolean isFlashClient() { 180 return flashClient; 181 } 182 183 191 public void setFlashClient(boolean flashClient) { 192 this.flashClient = flashClient; 193 } 194 195 public void close() { 196 boolean wasClosed = false; 197 synchronized (this) { 198 if (!isClosed()) { 199 try { 200 if (session != null) { 201 session.setStatus(Session.STATUS_CLOSED); 202 } 203 synchronized (writer) { 204 try { 205 SocketSendingTracker.getInstance().socketStartedSending(socket); 207 writer.write("</stream:stream>"); 208 if (flashClient) { 209 writer.write('\0'); 210 } 211 writer.flush(); 212 } 213 catch (IOException e) {} 214 finally { 215 SocketSendingTracker.getInstance().socketFinishedSending(socket); 217 } 218 } 219 } 220 catch (Exception e) { 221 Log.error(LocaleUtils.getLocalizedString("admin.error.close") 222 + "\n" + this.toString(), e); 223 } 224 try { 225 socket.close(); 226 } 227 catch (Exception e) { 228 Log.error(LocaleUtils.getLocalizedString("admin.error.close") 229 + "\n" + this.toString(), e); 230 } 231 wasClosed = true; 232 } 233 } 234 if (wasClosed) { 235 notifyCloseListeners(); 236 } 237 } 238 239 public void deliver(Packet packet) throws UnauthorizedException, PacketException { 240 if (isClosed()) { 241 deliverer.deliver(packet); 242 } 243 else { 244 try { 245 InterceptorManager.getInstance().invokeInterceptors(packet, session, false, false); 247 boolean errorDelivering = false; 248 synchronized (writer) { 249 try { 250 xmlSerializer.write(packet.getElement()); 251 if (flashClient) { 252 writer.write('\0'); 253 } 254 xmlSerializer.flush(); 255 } 256 catch (IOException e) { 257 Log.debug("Error delivering packet" + "\n" + this.toString(), e); 258 errorDelivering = true; 259 } 260 } 261 if (errorDelivering) { 262 close(); 263 deliverer.deliver(packet); 266 } 267 else { 268 InterceptorManager.getInstance().invokeInterceptors(packet, session, false, true); 270 session.incrementServerPacketCount(); 271 } 272 } 273 catch (PacketRejectedException e) { 274 } 276 } 277 } 278 279 public void deliverRawText(String text) { 280 if (!isClosed()) { 281 boolean errorDelivering = false; 282 synchronized (writer) { 283 try { 284 SocketSendingTracker.getInstance().socketStartedSending(socket); 286 writer.write(text); 287 if (flashClient) { 288 writer.write('\0'); 289 } 290 writer.flush(); 291 } 292 catch (IOException e) { 293 Log.debug("Error delivering raw text" + "\n" + this.toString(), e); 294 errorDelivering = true; 295 } 296 finally { 297 SocketSendingTracker.getInstance().socketFinishedSending(socket); 299 } 300 } 301 if (errorDelivering) { 302 close(); 303 } 304 } 305 } 306 307 311 private void notifyCloseListeners() { 312 synchronized (listeners) { 313 Iterator itr = listeners.keySet().iterator(); 314 while (itr.hasNext()) { 315 ConnectionCloseListener listener = (ConnectionCloseListener)itr.next(); 316 listener.onConnectionClose(listeners.get(listener)); 317 } 318 } 319 } 320 321 public String toString() { 322 return super.toString() + " socket: " + socket + " session: " + session; 323 } 324 } | Popular Tags |