Skip to content

Commit 73e3530

Browse files
Only compare header size vs. max allowed frame size if the latter is limited
Closes #407, references #362. [#160628331]
1 parent ff7a9d6 commit 73e3530

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/main/java/com/rabbitmq/client/impl/AMQCommand.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ public void transmit(AMQChannel channel) throws IOException {
107107
Frame headerFrame = this.assembler.getContentHeader().toFrame(channelNumber, body.length);
108108

109109
int frameMax = connection.getFrameMax();
110-
int bodyPayloadMax = (frameMax == 0) ? body.length : frameMax
111-
- EMPTY_FRAME_SIZE;
110+
boolean cappedFrameMax = frameMax > 0;
111+
int bodyPayloadMax = cappedFrameMax ? frameMax - EMPTY_FRAME_SIZE : body.length;
112112

113-
if (headerFrame.size() > frameMax) {
114-
throw new IllegalArgumentException("Content headers exceeded max frame size: " +
115-
headerFrame.size() + " > " + frameMax);
113+
if (cappedFrameMax && headerFrame.size() > frameMax) {
114+
String msg = String.format("Content headers exceeded max frame size: %d > %d", headerFrame.size(), frameMax);
115+
throw new IllegalArgumentException(msg);
116116
}
117117
connection.writeFrame(m.toFrame(channelNumber));
118118
connection.writeFrame(headerFrame);

src/test/java/com/rabbitmq/client/test/functional/FrameMax.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.concurrent.ExecutorService;
3131
import java.util.concurrent.TimeoutException;
3232

33+
import com.rabbitmq.client.impl.AMQBasicProperties;
3334
import com.rabbitmq.client.test.TestUtils;
3435
import org.junit.Test;
3536

@@ -104,9 +105,10 @@ public FrameMax() {
104105
closeChannel();
105106
closeConnection();
106107
ConnectionFactory cf = new GenerousConnectionFactory();
108+
cf.setRequestedFrameMax(8192);
107109
connection = cf.newConnection();
108110
openChannel();
109-
basicPublishVolatile(new byte[connection.getFrameMax()], "void");
111+
basicPublishVolatile(new byte[connection.getFrameMax() * 2], "void");
110112
expectError(AMQP.FRAME_ERROR);
111113
}
112114

@@ -123,7 +125,9 @@ public FrameMax() {
123125

124126
// create headers with zero-length value to calculate maximum header value size before exceeding frame_max
125127
headers.put(headerName, LongStringHelper.asLongString(new byte[0]));
126-
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder().headers(headers).build();
128+
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
129+
.headers(headers)
130+
.build();
127131
Frame minimalHeaderFrame = properties.toFrame(0, 0);
128132
int maxHeaderValueSize = FRAME_MAX - minimalHeaderFrame.size();
129133

@@ -151,6 +155,33 @@ public FrameMax() {
151155
}
152156

153157

158+
// see rabbitmq/rabbitmq-java-client#407
159+
@Test public void unlimitedFrameMaxWithHeaders()
160+
throws IOException, TimeoutException {
161+
closeChannel();
162+
closeConnection();
163+
ConnectionFactory cf = newConnectionFactory();
164+
cf.setRequestedFrameMax(0);
165+
connection = cf.newConnection();
166+
openChannel();
167+
168+
Map<String, Object> headers = new HashMap<String, Object>();
169+
headers.put("h1", LongStringHelper.asLongString(new byte[250]));
170+
headers.put("h1", LongStringHelper.asLongString(new byte[500]));
171+
headers.put("h1", LongStringHelper.asLongString(new byte[750]));
172+
headers.put("h1", LongStringHelper.asLongString(new byte[5000]));
173+
headers.put("h1", LongStringHelper.asLongString(new byte[50000]));
174+
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
175+
.headers(headers)
176+
.build();
177+
basicPublishVolatile(new byte[500000], "", "", properties);
178+
}
179+
180+
@Override
181+
protected boolean isAutomaticRecoveryEnabled() {
182+
return false;
183+
}
184+
154185
/* ConnectionFactory that uses MyFrameHandler rather than
155186
* SocketFrameHandler. */
156187
private static class MyConnectionFactory extends ConnectionFactory {

0 commit comments

Comments
 (0)