// Copyright (c) 2007-Present Pivotal Software, Inc. All rights reserved.
//
// This software, the RabbitMQ Java client library, is triple-licensed under the
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
// please see LICENSE-APACHE2.
//
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
// either express or implied. See the LICENSE file for specific language governing
// rights and limitations of this software.
//
// If you have any questions regarding licensing, please contact us at
// info@rabbitmq.com.
package com.rabbitmq.client.test.functional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.test.TestUtils;
import org.junit.Test;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MalformedFrameException;
import com.rabbitmq.client.Method;
import com.rabbitmq.client.impl.AMQCommand;
import com.rabbitmq.client.impl.SocketFrameHandler;
/**
* Check that protocol negotiation works
*/
public class ConnectionOpen {
@Test public void correctProtocolHeader() throws IOException {
ConnectionFactory factory = TestUtils.connectionFactory();
SocketFrameHandler fh = new SocketFrameHandler(factory.getSocketFactory().createSocket("localhost", AMQP.PROTOCOL.PORT));
fh.sendHeader();
AMQCommand command = new AMQCommand();
while (!command.handleFrame(fh.readFrame())) { }
Method m = command.getMethod();
// System.out.println(m.getClass());
assertTrue("First command must be Connection.start",
m instanceof AMQP.Connection.Start);
AMQP.Connection.Start start = (AMQP.Connection.Start) m;
assertTrue("Version in Connection.start is <= what we sent",
start.getVersionMajor() < AMQP.PROTOCOL.MAJOR ||
(start.getVersionMajor() == AMQP.PROTOCOL.MAJOR &&
start.getVersionMinor() <= AMQP.PROTOCOL.MINOR));
}
@Test public void crazyProtocolHeader() throws IOException {
ConnectionFactory factory = TestUtils.connectionFactory();
// keep the frame handler's socket
Socket fhSocket = factory.getSocketFactory().createSocket("localhost", AMQP.PROTOCOL.PORT);
SocketFrameHandler fh = new SocketFrameHandler(fhSocket);
fh.sendHeader(100, 3); // major, minor
DataInputStream in = fh.getInputStream();
// we should get a valid protocol header back
byte[] header = new byte[4];
in.read(header);
// The protocol header is "AMQP" plus a version that the server
// supports. We can really only test for the first bit.
assertEquals("AMQP", new String(header));
in.read(header);
assertEquals(in.available(), 0);
// At this point the socket should have been closed. We can
// directly test for this, but since Socket.isClosed is purported to be
// unreliable, we can also test whether trying to read more bytes
// gives an error.
if (!fhSocket.isClosed()) {
fh.setTimeout(500);
// NB the frame handler will return null if the socket times out
try {
fh.readFrame();
fail("Expected socket read to fail due to socket being closed");
} catch (MalformedFrameException mfe) {
fail("Expected nothing, rather than a badly-formed something");
} catch (IOException ioe) {
}
}
}
@Test public void frameMaxLessThanFrameMinSize() throws IOException, TimeoutException {
ConnectionFactory factory = TestUtils.connectionFactory();
factory.setRequestedFrameMax(100);
try {
factory.newConnection();
}
catch (IOException ioe) {
return;
}
fail("Broker should have closed the connection since our frame max < frame_min_size");
}
}