All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rocks.xmpp.extensions.compress.CompressionManager Maven / Gradle / Ivy

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2016 Christian Schudt
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package rocks.xmpp.extensions.compress;

import rocks.xmpp.core.session.XmppSession;
import rocks.xmpp.core.stream.StreamFeatureNegotiator;
import rocks.xmpp.core.stream.StreamNegotiationException;
import rocks.xmpp.extensions.compress.model.StreamCompression;
import rocks.xmpp.extensions.compress.model.feature.CompressionFeature;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;

/**
 * Manages stream compression as described in XEP-0138: Stream Compression.
 * 
*

1. Introduction

*

XMPP Core [1] specifies the use of Transport Layer Security (TLS; see RFC 5246 [2]) for encryption of XML streams, and TLS includes the ability to compress encrypted traffic (see RFC 3749 [3]). However, not all computing platforms are able to implement TLS, and traffic compression may be desirable for communication by applications on such computing platforms. This document defines a mechanism for negotiating the compression of XML streams outside the context of TLS.

*
* If you enable this manager, stream compression will be used, if available. Note that stream compression should not be used, when you use TLS. * * @author Christian Schudt */ public final class CompressionManager extends StreamFeatureNegotiator { /** * The "zlib" compression method. * * @deprecated Use {@link CompressionMethod#ZLIB} */ @Deprecated public static final CompressionMethod ZLIB = CompressionMethod.ZLIB; /** * The "gzip" compression method. * * @deprecated Use {@link CompressionMethod#GZIP} */ @Deprecated public static final CompressionMethod GZIP = CompressionMethod.GZIP; /** * The "deflate" compression method. * * @deprecated Use {@link CompressionMethod#DEFLATE} */ @Deprecated public static final CompressionMethod DEFLATE = CompressionMethod.DEFLATE; private static final Logger logger = Logger.getLogger(CompressionManager.class.getName()); private final List compressionMethods = new CopyOnWriteArrayList<>(); private CompressionMethod negotiatedCompressionMethod; private CompressionManager(XmppSession xmppSession) { super(xmppSession, CompressionFeature.class); } @Override public final Status processNegotiation(Object element) throws StreamNegotiationException { if (compressionMethods.isEmpty()) { return Status.IGNORE; } if (element instanceof CompressionFeature) { List advertisedCompressionMethods = ((CompressionFeature) element).getMethods(); Map clientMethods = new LinkedHashMap<>(); for (CompressionMethod compressionMethod : compressionMethods) { clientMethods.put(compressionMethod.getName(), compressionMethod); } clientMethods.keySet().retainAll(advertisedCompressionMethods); if (!clientMethods.isEmpty()) { // Use the first configured compression method, which is also advertised by the server. CompressionMethod compressionMethod = clientMethods.values().iterator().next(); xmppSession.send(new StreamCompression.Compress(compressionMethod.getName())); negotiatedCompressionMethod = compressionMethod; return Status.INCOMPLETE; } else { return Status.IGNORE; } } else if (element == StreamCompression.COMPRESSED) { notifyFeatureNegotiated(); logger.fine("Stream is now compressed."); return Status.SUCCESS; } else if (element instanceof StreamCompression.Failure) { negotiatedCompressionMethod = null; // Failure of the negotiation SHOULD NOT be treated as an unrecoverable error logger.warning("Failure during compression negotiation: " + ((StreamCompression.Failure) element).getCondition()); return Status.IGNORE; } return Status.IGNORE; } /** * {@inheritDoc} * * @return True, because compression needs a stream restart after feature negotiation. */ public final boolean needsRestart() { return true; } @Override public final boolean canProcess(Object element) { return element instanceof StreamCompression; } /** * Gets the negotiated compression method. * * @return The negotiated compression method. */ public final CompressionMethod getNegotiatedCompressionMethod() { return negotiatedCompressionMethod; } /** * Gets the configured compression methods. * * @return The configured compression method. */ public final List getConfiguredCompressionMethods() { return compressionMethods; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy