Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.x: Server side trailers #7647 #7649

Merged
merged 4 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.http;

/**
* Mutable trailers of a server response.
*/
public interface ServerResponseTrailers extends WritableHeaders<ServerResponseTrailers> {

/**
* Create a new instance of mutable server response trailers.
*
* @return new server response trailers
*/
static ServerResponseTrailers create() {
return new ServerResponseTrailersImpl(WritableHeaders.create());
}

/**
* Create a new instance of mutable server response trailers.
*
* @param existing trailers to add to these response trailers
* @return new server response trailers
*/
static ServerResponseTrailers create(Headers existing) {
return new ServerResponseTrailersImpl(WritableHeaders.create(existing));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.http;

import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

class ServerResponseTrailersImpl implements ServerResponseTrailers {
private final WritableHeaders<?> delegate;

ServerResponseTrailersImpl(WritableHeaders<?> delegate) {
this.delegate = delegate;
}

@Override
public List<String> all(HeaderName name, Supplier<List<String>> defaultSupplier) {
return delegate.all(name, defaultSupplier);
}

@Override
public boolean contains(HeaderName name) {
return delegate.contains(name);
}

@Override
public boolean contains(Header value) {
return delegate.contains(value);
}

@Override
public Header get(HeaderName name) {
return delegate.get(name);
}

@Override
public int size() {
return delegate.size();
}

@Override
public List<HttpMediaType> acceptedTypes() {
return delegate.acceptedTypes();
}

@Override
public ServerResponseTrailers setIfAbsent(Header header) {
delegate.setIfAbsent(header);
return this;
}

@Override
public ServerResponseTrailers add(Header header) {
delegate.add(header);
return this;
}

@Override
public ServerResponseTrailers remove(HeaderName name) {
delegate.remove(name);
return this;
}

@Override
public ServerResponseTrailers remove(HeaderName name, Consumer<Header> removedConsumer) {
delegate.remove(name, removedConsumer);
return this;
}

@Override
public ServerResponseTrailers set(Header header) {
delegate.set(header);
return this;
}

@Override
public ServerResponseTrailers clear() {
delegate.clear();
return this;
}

@Override
public ServerResponseTrailers from(Headers headers) {
delegate.from(headers);
return this;
}

@Override
public Iterator<Header> iterator() {
return delegate.iterator();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ protected WebClientServiceResponse doProceed(WebClientServiceRequest serviceRequ

Http2Headers http2Headers = prepareHeaders(serviceRequest.method(), headers, uri);

stream.write(http2Headers, entityBytes.length == 0);
stream.writeHeaders(http2Headers, entityBytes.length == 0);
stream.flowControl().inbound().incrementWindowSize(clientRequest().requestPrefetch());
whenSent.complete(serviceRequest);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected WebClientServiceResponse doProceed(WebClientServiceRequest serviceRequ
ClientUri uri = serviceRequest.uri();
Http2Headers http2Headers = prepareHeaders(serviceRequest.method(), headers, uri);

stream.write(http2Headers, false);
stream.writeHeaders(http2Headers, false);
whenSent.complete(serviceRequest);

stream.waitFor100Continue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Http2ClientStream implements Http2Stream, ReleasableResource {
private final Http2FrameListener recvListener = new Http2LoggingFrameListener("cl-recv");
private final Http2Settings settings = Http2Settings.create();
private final List<Http2FrameData> continuationData = new ArrayList<>();
private final CompletableFuture<Headers> trailers = new CompletableFuture<>();

private Http2StreamState state = Http2StreamState.IDLE;
private ReadState readState = ReadState.INIT;
Expand All @@ -80,7 +81,6 @@ class Http2ClientStream implements Http2Stream, ReleasableResource {
// streamId and buffer can only be created when we are locked in the stream id sequence
private int streamId;
private StreamBuffer buffer;
private final CompletableFuture<Headers> trailers = new CompletableFuture<>();

Http2ClientStream(Http2ClientConnection connection,
Http2Settings serverSettings,
Expand Down Expand Up @@ -253,7 +253,7 @@ void waitFor100Continue() {
}
}

void write(Http2Headers http2Headers, boolean endOfStream) {
void writeHeaders(Http2Headers http2Headers, boolean endOfStream) {
this.state = Http2StreamState.checkAndGetState(this.state, Http2FrameType.HEADERS, true, endOfStream, true);
this.readState = readState.check(http2Headers.httpHeaders().contains(HeaderValues.EXPECT_100)
? ReadState.CONTINUE_100_HEADERS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;

class HeadersTest {
class HeadersClientTest {

private static final Duration TIMEOUT = Duration.ofSeconds(10);
private static final Header INVALID_CONTENT_TYPE_VALUE =
Expand Down Expand Up @@ -168,7 +168,7 @@ public void testInvalidTextContentTypeStrict() {
@Test
public void testInvalidTextContentTypeRelaxed() {
WebClient client = WebClient.builder()
.from(HeadersTest.CLIENT.prototype())
.from(HeadersClientTest.CLIENT.prototype())
.mediaTypeParserMode(ParserMode.RELAXED)
.build();
try (HttpClientResponse res = client.method(Method.GET)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;

class HeadersTest {
class HeadersClientTest {

private static final System.Logger LOGGER = System.getLogger(HeadersTest.class.getName());
private static final System.Logger LOGGER = System.getLogger(HeadersClientTest.class.getName());
private static final Header BEFORE_HEADER = HeaderValues.create("test", "before");
private static final Header TRAILER_HEADER = HeaderValues.create("Trailer-header", "trailer-test");
private static final Duration TIMEOUT = Duration.ofSeconds(10);
Expand Down
Loading
Loading