Skip to content

Commit

Permalink
Response#end should throw ISE if used inside headers end handler
Browse files Browse the repository at this point in the history
See #4326

This aligns behaviors of Http 1 and Http2 servers.

Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
  • Loading branch information
tsegismont committed Nov 23, 2022
1 parent 5826991 commit 9dc5b15
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 13 deletions.
Expand Up @@ -36,8 +36,8 @@
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.http.impl.headers.HeadersMultiMap;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.impl.future.PromiseInternal;
import io.vertx.core.impl.VertxInternal;
import io.vertx.core.impl.future.PromiseInternal;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.net.NetSocket;
Expand All @@ -48,10 +48,9 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Map;
import java.util.Set;

import static io.vertx.core.http.HttpHeaders.SET_COOKIE;
import static io.vertx.core.http.HttpHeaders.*;

/**
*
Expand Down Expand Up @@ -399,6 +398,7 @@ private void end(Buffer chunk, PromiseInternal<Void> listener) {
if (written) {
throw new IllegalStateException(RESPONSE_WRITTEN);
}
written = true;
ByteBuf data = chunk.getByteBuf();
bytesWritten += data.readableBytes();
HttpObject msg;
Expand All @@ -411,7 +411,6 @@ private void end(Buffer chunk, PromiseInternal<Void> listener) {
msg = new AssembledLastHttpContent(data, trailingHeaders);
}
conn.writeToChannel(msg, listener);
written = true;
conn.responseComplete();
if (bodyEndHandler != null) {
bodyEndHandler.handle(null);
Expand Down Expand Up @@ -690,6 +689,7 @@ private void checkHeadWritten() {
}

private void prepareHeaders(long contentLength) {
headWritten = true;
if (version == HttpVersion.HTTP_1_0 && keepAlive) {
headers.set(HttpHeaders.CONNECTION, HttpHeaders.KEEP_ALIVE);
} else if (version == HttpVersion.HTTP_1_1 && !keepAlive) {
Expand Down Expand Up @@ -717,7 +717,6 @@ private void prepareHeaders(long contentLength) {
// TODO : DONE SOMEWHERE ELSE FROM EVENT LOOP
reportResponseBegin();
}
headWritten = true;
}

private void setCookies() {
Expand Down
81 changes: 73 additions & 8 deletions src/test/java/io/vertx/core/http/HttpTest.java
Expand Up @@ -17,14 +17,27 @@
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http2.Http2Exception;
import io.vertx.codegen.annotations.Nullable;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Future;
import io.vertx.core.*;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.VertxException;
import io.vertx.core.VertxOptions;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.dns.AddressResolverOptions;
import io.vertx.core.http.impl.HttpServerRequestInternal;
import io.vertx.core.http.impl.ServerCookie;
import io.vertx.core.impl.Utils;
import io.vertx.core.net.*;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetServerOptions;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.SocketAddress;
import io.vertx.core.net.impl.HAProxyMessageCompletionHandler;
import io.vertx.core.streams.Pump;
import io.vertx.core.streams.ReadStream;
Expand All @@ -39,24 +52,49 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.IntStream;

import static io.vertx.core.http.HttpMethod.PUT;
import static io.vertx.core.http.HttpMethod.*;
import static io.vertx.test.core.TestUtils.*;
import static java.util.Collections.singletonList;
import static java.util.Collections.*;

/**
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
Expand Down Expand Up @@ -6705,4 +6743,31 @@ private void testResponseEndFutureCompletes(final Function<HttpServerResponse, F
.onComplete(onSuccess(nothing -> complete()));
await();
}

@Test
public void shouldThrowISEIfSendingResponseFromHeadersEndHandler() throws Exception {
AtomicBoolean flag = new AtomicBoolean();
waitFor(3);
server.requestHandler(req -> {
HttpServerResponse resp = req.response();
resp.headersEndHandler(v -> {
if (flag.compareAndSet(false, true)) {
try {
resp.end("bar");
} catch (IllegalStateException e) {
complete();
}
}
});
resp.end("foo");
complete();
}
);
startServer(testAddress);
client.request(requestOptions)
.compose(HttpClientRequest::send)
.compose(HttpClientResponse::end)
.onComplete(onSuccess(nothing -> complete()));
await();
}
}

0 comments on commit 9dc5b15

Please sign in to comment.