Skip to content

Commit

Permalink
Merged branch 'jetty-11.0.x' into 'jetty-12.0.x'.
Browse files Browse the repository at this point in the history
Signed-off-by: Simone Bordet <[email protected]>
  • Loading branch information
sbordet committed Oct 18, 2023
2 parents 929eec9 + 5ea5d65 commit a9bcbc6
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.jetty.http3.ControlFlusher;
import org.eclipse.jetty.http3.DecoderStreamConnection;
import org.eclipse.jetty.http3.EncoderStreamConnection;
import org.eclipse.jetty.http3.Grease;
import org.eclipse.jetty.http3.HTTP3Configuration;
import org.eclipse.jetty.http3.HTTP3ErrorCode;
import org.eclipse.jetty.http3.InstructionFlusher;
Expand Down Expand Up @@ -63,7 +64,7 @@ public ClientHTTP3Session(HTTP3Configuration configuration, ClientQuicSession qu
if (LOG.isDebugEnabled())
LOG.debug("initializing HTTP/3 streams");

long encoderStreamId = getQuicSession().newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
long encoderStreamId = newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
QuicStreamEndPoint encoderEndPoint = openInstructionEndPoint(encoderStreamId);
InstructionFlusher encoderInstructionFlusher = new InstructionFlusher(quicSession, encoderEndPoint, EncoderStreamConnection.STREAM_TYPE);
encoder = new QpackEncoder(new InstructionHandler(encoderInstructionFlusher));
Expand All @@ -72,15 +73,15 @@ public ClientHTTP3Session(HTTP3Configuration configuration, ClientQuicSession qu
if (LOG.isDebugEnabled())
LOG.debug("created encoder stream #{} on {}", encoderStreamId, encoderEndPoint);

long decoderStreamId = getQuicSession().newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
long decoderStreamId = newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
QuicStreamEndPoint decoderEndPoint = openInstructionEndPoint(decoderStreamId);
InstructionFlusher decoderInstructionFlusher = new InstructionFlusher(quicSession, decoderEndPoint, DecoderStreamConnection.STREAM_TYPE);
decoder = new QpackDecoder(new InstructionHandler(decoderInstructionFlusher));
addBean(decoder);
if (LOG.isDebugEnabled())
LOG.debug("created decoder stream #{} on {}", decoderStreamId, decoderEndPoint);

long controlStreamId = getQuicSession().newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
long controlStreamId = newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
QuicStreamEndPoint controlEndPoint = openControlEndPoint(controlStreamId);
controlFlusher = new ControlFlusher(quicSession, controlEndPoint, true);
addBean(controlFlusher);
Expand All @@ -106,6 +107,11 @@ public HTTP3SessionClient getSessionClient()
return session;
}

public long newStreamId(StreamType streamType)
{
return getQuicSession().newStreamId(streamType);
}

@Override
protected void onStart()
{
Expand Down Expand Up @@ -171,21 +177,27 @@ public void onSettings(SettingsFrame frame)
{
if (key == SettingsFrame.MAX_TABLE_CAPACITY)
{
int maxTableCapacity = value.intValue();
int maxTableCapacity = (int)Math.min(value, Integer.MAX_VALUE);
encoder.setMaxTableCapacity(maxTableCapacity);
encoder.setTableCapacity(Math.min(maxTableCapacity, configuration.getMaxEncoderTableCapacity()));
}
else if (key == SettingsFrame.MAX_FIELD_SECTION_SIZE)
{
// Must cap the maxHeaderSize to avoid large allocations.
int maxHeadersSize = Math.min(value.intValue(), configuration.getMaxRequestHeadersSize());
int maxHeadersSize = (int)Math.min(value, configuration.getMaxResponseHeadersSize());
encoder.setMaxHeadersSize(maxHeadersSize);
}
else if (key == SettingsFrame.MAX_BLOCKED_STREAMS)
{
int maxBlockedStreams = value.intValue();
int maxBlockedStreams = (int)Math.min(value, Integer.MAX_VALUE);
encoder.setMaxBlockedStreams(maxBlockedStreams);
}
else
{
// SPEC: grease and unknown settings are ignored.
if (LOG.isDebugEnabled())
LOG.debug("ignored {} setting {}={}", Grease.isGreaseValue(key) ? "grease" : "unknown", key, value);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void onSettings(SettingsFrame frame)
@Override
public CompletableFuture<Stream> newRequest(HeadersFrame frame, Stream.Client.Listener listener)
{
long streamId = getProtocolSession().getQuicSession().newStreamId(StreamType.CLIENT_BIDIRECTIONAL);
long streamId = getProtocolSession().newStreamId(StreamType.CLIENT_BIDIRECTIONAL);
return newRequest(streamId, frame, listener);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.http3;

import java.util.concurrent.ThreadLocalRandom;

/**
* <p>A class to support GREASE (<a href="https://www.rfc-editor.org/rfc/rfc8701.txt">RFC 8701</a>) in HTTP/3.</p>
* <p>HTTP/3 GREASE values have the form {@code 0x1F * N + 0x21} with non negative values of {@code N}.</p>
*/
public class Grease
{
/**
* @param value the value to test
* @return whether the value is a GREASE value as defined by HTTP/3
*/
public static boolean isGreaseValue(long value)
{
if (value < 0)
return false;
return (value - 0x21) % 0x1F == 0;
}

/**
* @return a random grease value as defined by HTTP/3
*/
public static long generateGreaseValue()
{
// This constant avoids to overflow VarLenInt.
long n = ThreadLocalRandom.current().nextLong(0x210842108421084L);
return 0x1F * n + 0x21;
}

private Grease()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

package org.eclipse.jetty.http3;

import java.util.concurrent.ThreadLocalRandom;

public enum HTTP3ErrorCode
{
NO_ERROR(0x100),
Expand Down Expand Up @@ -45,9 +43,7 @@ public enum HTTP3ErrorCode
public static long randomReservedCode()
{
// SPEC: reserved errors have the form 0x1F * n + 0x21.
// This constant avoids to overflow VarLenInt, which is how an error code is encoded.
long n = ThreadLocalRandom.current().nextLong(0x210842108421084L);
return 0x1F * n + 0x21;
return Grease.generateGreaseValue();
}

public long code()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.IOException;
import java.nio.ByteBuffer;

import org.eclipse.jetty.http3.Grease;
import org.eclipse.jetty.http3.HTTP3ErrorCode;
import org.eclipse.jetty.http3.frames.FrameType;
import org.slf4j.Logger;
Expand Down Expand Up @@ -91,8 +92,9 @@ public void parse(ByteBuffer buffer)
return;
}

// SPEC: grease and unknown frame types are ignored.
if (LOG.isDebugEnabled())
LOG.debug("ignoring unknown frame type {}", Long.toHexString(frameType));
LOG.debug("ignoring {} frame type {}", Grease.isGreaseValue(frameType) ? "grease" : "unknown", Long.toHexString(frameType));

BodyParser.Result result = unknownBodyParser.parse(buffer);
if (result == BodyParser.Result.NO_FRAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.function.BooleanSupplier;
import java.util.function.UnaryOperator;

import org.eclipse.jetty.http3.Grease;
import org.eclipse.jetty.http3.HTTP3ErrorCode;
import org.eclipse.jetty.http3.frames.FrameType;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
Expand Down Expand Up @@ -138,8 +139,9 @@ public Result parse(ByteBuffer buffer)
return Result.NO_FRAME;
}

// SPEC: grease and unknown frame types are ignored.
if (LOG.isDebugEnabled())
LOG.debug("ignoring unknown frame type {}", Long.toHexString(frameType));
LOG.debug("ignoring {} frame type {}", Grease.isGreaseValue(frameType) ? "grease" : "unknown", Long.toHexString(frameType));

BodyParser.Result result = unknownBodyParser.parse(buffer);
if (result == BodyParser.Result.NO_FRAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.jetty.http3.ControlFlusher;
import org.eclipse.jetty.http3.DecoderStreamConnection;
import org.eclipse.jetty.http3.EncoderStreamConnection;
import org.eclipse.jetty.http3.Grease;
import org.eclipse.jetty.http3.HTTP3Configuration;
import org.eclipse.jetty.http3.HTTP3ErrorCode;
import org.eclipse.jetty.http3.InstructionFlusher;
Expand Down Expand Up @@ -62,7 +63,7 @@ public ServerHTTP3Session(HTTP3Configuration configuration, ServerQuicSession qu
if (LOG.isDebugEnabled())
LOG.debug("initializing HTTP/3 streams");

long encoderStreamId = getQuicSession().newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
long encoderStreamId = newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
QuicStreamEndPoint encoderEndPoint = openInstructionEndPoint(encoderStreamId);
InstructionFlusher encoderInstructionFlusher = new InstructionFlusher(quicSession, encoderEndPoint, EncoderStreamConnection.STREAM_TYPE);
encoder = new QpackEncoder(new InstructionHandler(encoderInstructionFlusher));
Expand All @@ -71,15 +72,15 @@ public ServerHTTP3Session(HTTP3Configuration configuration, ServerQuicSession qu
if (LOG.isDebugEnabled())
LOG.debug("created encoder stream #{} on {}", encoderStreamId, encoderEndPoint);

long decoderStreamId = getQuicSession().newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
long decoderStreamId = newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
QuicStreamEndPoint decoderEndPoint = openInstructionEndPoint(decoderStreamId);
InstructionFlusher decoderInstructionFlusher = new InstructionFlusher(quicSession, decoderEndPoint, DecoderStreamConnection.STREAM_TYPE);
decoder = new QpackDecoder(new InstructionHandler(decoderInstructionFlusher));
addBean(decoder);
if (LOG.isDebugEnabled())
LOG.debug("created decoder stream #{} on {}", decoderStreamId, decoderEndPoint);

long controlStreamId = getQuicSession().newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
long controlStreamId = newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
QuicStreamEndPoint controlEndPoint = openControlEndPoint(controlStreamId);
controlFlusher = new ControlFlusher(quicSession, controlEndPoint, configuration.isUseOutputDirectByteBuffers());
addBean(controlFlusher);
Expand All @@ -105,6 +106,11 @@ public HTTP3SessionServer getSessionServer()
return session;
}

public long newStreamId(StreamType streamType)
{
return getQuicSession().newStreamId(streamType);
}

@Override
protected void onStart()
{
Expand Down Expand Up @@ -170,21 +176,27 @@ public void onSettings(SettingsFrame frame)
{
if (key == SettingsFrame.MAX_TABLE_CAPACITY)
{
int maxTableCapacity = value.intValue();
int maxTableCapacity = (int)Math.min(value, Integer.MAX_VALUE);
encoder.setMaxTableCapacity(maxTableCapacity);
encoder.setTableCapacity(Math.min(maxTableCapacity, configuration.getMaxEncoderTableCapacity()));
}
else if (key == SettingsFrame.MAX_FIELD_SECTION_SIZE)
{
// Must cap the maxHeaderSize to avoid large allocations.
int maxHeadersSize = Math.min(value.intValue(), configuration.getMaxResponseHeadersSize());
int maxHeadersSize = (int)Math.min(value, configuration.getMaxResponseHeadersSize());
encoder.setMaxHeadersSize(maxHeadersSize);
}
else if (key == SettingsFrame.MAX_BLOCKED_STREAMS)
{
int maxBlockedStreams = value.intValue();
int maxBlockedStreams = (int)Math.min(value, Integer.MAX_VALUE);
encoder.setMaxBlockedStreams(maxBlockedStreams);
}
else
{
// SPEC: grease and unknown settings are ignored.
if (LOG.isDebugEnabled())
LOG.debug("ignored {} setting {}={}", Grease.isGreaseValue(key) ? "grease" : "unknown", key, value);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,12 @@ void setFile(ZonedDateTime now)
File file = new File(_filename);
_filename = file.getCanonicalPath();
file = new File(_filename);
File dir = new File(file.getParent());
if (!dir.isDirectory() || !dir.canWrite())
File dir = file.getParentFile();
if (!dir.exists())
throw new IOException("Log directory does not exist. Path=" + dir);
else if (!dir.isDirectory())
throw new IOException("Path for Log directory is not a directory. Path=" + dir);
else if (!dir.canWrite())
throw new IOException("Cannot write log directory " + dir);

// Is this a rollover file?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
import org.junit.jupiter.api.extension.ExtendWith;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@ExtendWith(WorkDirExtension.class)
public class RolloverFileOutputStreamTest
Expand Down Expand Up @@ -182,6 +185,25 @@ public void testMidnightRolloverCalcSydneyDSTEnd()
assertSequence(midnight, expected);
}

@Test
public void testMissingDirectory()
{
String templateString = "missingDir/test-rofos-yyyy_mm_dd.log";
Throwable error;
try (RolloverFileOutputStream ignored = new RolloverFileOutputStream(templateString))
{
throw new IllegalStateException();
}
catch (Throwable t)
{
error = t;
}
assertNotNull(error);
assertThat(error, instanceOf(IOException.class));
error.getMessage();
assertThat(error.getMessage(), containsString("Log directory does not exist."));
}

@Test
public void testFileHandling() throws Exception
{
Expand Down

0 comments on commit a9bcbc6

Please sign in to comment.