use of org.eclipse.jetty.http.MetaData in project jetty.project by eclipse.
the class HeadersBodyParser method emptyBody.
@Override
protected void emptyBody(ByteBuffer buffer) {
if (hasFlag(Flags.END_HEADERS)) {
MetaData metaData = headerBlockParser.parse(BufferUtil.EMPTY_BUFFER, 0);
onHeaders(0, 0, false, metaData);
} else {
headerBlockFragments.setStreamId(getStreamId());
headerBlockFragments.setEndStream(isEndStream());
if (hasFlag(Flags.PRIORITY))
connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_headers_priority_frame");
}
}
use of org.eclipse.jetty.http.MetaData in project jetty.project by eclipse.
the class Request method getLocales.
/* ------------------------------------------------------------ */
/*
* @see javax.servlet.ServletRequest#getLocales()
*/
@Override
public Enumeration<Locale> getLocales() {
MetaData.Request metadata = _metaData;
if (metadata == null)
return Collections.enumeration(__defaultLocale);
List<String> acceptable = metadata.getFields().getQualityCSV(HttpHeader.ACCEPT_LANGUAGE);
// handle no locale
if (acceptable.isEmpty())
return Collections.enumeration(__defaultLocale);
List<Locale> locales = acceptable.stream().map(language -> {
language = HttpFields.stripParameters(language);
String country = "";
int dash = language.indexOf('-');
if (dash > -1) {
country = language.substring(dash + 1).trim();
language = language.substring(0, dash).trim();
}
return new Locale(language, country);
}).collect(Collectors.toList());
return Collections.enumeration(locales);
}
use of org.eclipse.jetty.http.MetaData in project jetty.project by eclipse.
the class Request method findServerName.
/* ------------------------------------------------------------ */
private String findServerName() {
MetaData.Request metadata = _metaData;
// Return host from header field
HttpField host = metadata == null ? null : metadata.getFields().getField(HttpHeader.HOST);
if (host != null) {
if (!(host instanceof HostPortHttpField) && host.getValue() != null && !host.getValue().isEmpty())
host = new HostPortHttpField(host.getValue());
if (host instanceof HostPortHttpField) {
HostPortHttpField authority = (HostPortHttpField) host;
metadata.getURI().setAuthority(authority.getHost(), authority.getPort());
return authority.getHost();
}
}
// Return host from connection
String name = getLocalName();
if (name != null)
return name;
// Return the local host
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (java.net.UnknownHostException e) {
LOG.ignore(e);
}
return null;
}
use of org.eclipse.jetty.http.MetaData in project jetty.project by eclipse.
the class FlowControlStrategyTest method testFlowControlWhenServerResetsStream.
@Test
public void testFlowControlWhenServerResetsStream() throws Exception {
// On server, don't consume the data and immediately reset.
start(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
MetaData.Request request = (MetaData.Request) frame.getMetaData();
if (HttpMethod.GET.is(request.getMethod()))
return new Stream.Listener.Adapter();
return new Stream.Listener.Adapter() {
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
// Fail the callback to enlarge the session window.
// More data frames will be discarded because the
// stream is reset, and automatically consumed to
// keep the session window large for other streams.
callback.failed(new Throwable());
stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
}
};
}
});
Session session = newClient(new Session.Listener.Adapter());
MetaData.Request metaData = newRequest("POST", new HttpFields());
HeadersFrame frame = new HeadersFrame(metaData, null, false);
FuturePromise<Stream> streamPromise = new FuturePromise<>();
final CountDownLatch resetLatch = new CountDownLatch(1);
session.newStream(frame, streamPromise, new Stream.Listener.Adapter() {
@Override
public void onReset(Stream stream, ResetFrame frame) {
resetLatch.countDown();
}
});
Stream stream = streamPromise.get(5, TimeUnit.SECONDS);
// Perform a big upload that will stall the flow control windows.
ByteBuffer data = ByteBuffer.allocate(5 * FlowControlStrategy.DEFAULT_WINDOW_SIZE);
final CountDownLatch dataLatch = new CountDownLatch(1);
stream.data(new DataFrame(stream.getId(), data, true), new Callback() {
@Override
public InvocationType getInvocationType() {
return InvocationType.NON_BLOCKING;
}
@Override
public void failed(Throwable x) {
dataLatch.countDown();
}
});
Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
}
use of org.eclipse.jetty.http.MetaData in project jetty.project by eclipse.
the class FlowControlStrategyTest method testServerTwoDataFramesWithStalledStream.
// TODO
// Since we changed the API to disallow consecutive data() calls without waiting
// for the callback, it is now not possible to have DATA1, DATA2 in the queue for
// the same stream. Perhaps this test should just be deleted.
@Ignore
@Test
public void testServerTwoDataFramesWithStalledStream() throws Exception {
// Frames in queue = DATA1, DATA2.
// Server writes part of DATA1, then stalls.
// A window update unstalls the session, verify that the data is correctly sent.
Random random = new Random();
final byte[] chunk1 = new byte[1024];
random.nextBytes(chunk1);
final byte[] chunk2 = new byte[2048];
random.nextBytes(chunk2);
// Two SETTINGS frames: the initial after the preface,
// and the explicit where we set the stream window size to zero.
final AtomicReference<CountDownLatch> settingsLatch = new AtomicReference<>(new CountDownLatch(2));
final CountDownLatch dataLatch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter() {
@Override
public void onSettings(Session session, SettingsFrame frame) {
settingsLatch.get().countDown();
}
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(chunk1), false), Callback.NOOP);
stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(chunk2), true), Callback.NOOP);
dataLatch.countDown();
return null;
}
});
Session session = newClient(new Session.Listener.Adapter());
Map<Integer, Integer> settings = new HashMap<>();
settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, 0);
session.settings(new SettingsFrame(settings, false), Callback.NOOP);
Assert.assertTrue(settingsLatch.get().await(5, TimeUnit.SECONDS));
byte[] content = new byte[chunk1.length + chunk2.length];
final ByteBuffer buffer = ByteBuffer.wrap(content);
MetaData.Request metaData = newRequest("GET", new HttpFields());
HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
final CountDownLatch responseLatch = new CountDownLatch(1);
session.newStream(requestFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter() {
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
buffer.put(frame.getData());
callback.succeeded();
if (frame.isEndStream())
responseLatch.countDown();
}
});
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
// Now we have the 2 DATA frames queued in the server.
// Unstall the stream window.
settingsLatch.set(new CountDownLatch(1));
settings.clear();
settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, chunk1.length / 2);
session.settings(new SettingsFrame(settings, false), Callback.NOOP);
Assert.assertTrue(settingsLatch.get().await(5, TimeUnit.SECONDS));
Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
// Check that the data is sent correctly.
byte[] expected = new byte[content.length];
System.arraycopy(chunk1, 0, expected, 0, chunk1.length);
System.arraycopy(chunk2, 0, expected, chunk1.length, chunk2.length);
Assert.assertArrayEquals(expected, content);
}
Aggregations