mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Fix WHOIS issues
[1] Web whois should redirect to www.registry.google. whois.registry.google also points to the proxy IP, so redirecting to whois.registry.google just makes it loop. Also allow HEAD in web whois request in case that is used in monitoring. [2] Separately, there's a bug introduced in [] where exception handling of inbound messages is moved to HttpsRelayServiceHandler. However the quota handlers are installed behind the HttpServiceServiceHandler in the channel pipeline, therefore the exception thrown in quota handlers never got processed. This results in hung connection when quota exceeded. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=208651011
This commit is contained in:
parent
0e64015cdf
commit
2e2898e17c
4 changed files with 20 additions and 8 deletions
|
@ -79,10 +79,7 @@ public abstract class QuotaHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
static class OverQuotaException extends Exception {
|
static class OverQuotaException extends Exception {
|
||||||
OverQuotaException(String protocol, String userId) {
|
OverQuotaException(String protocol, String userId) {
|
||||||
super(
|
super(String.format("Quota exceeded for: PROTOCOL: %s, USER ID: %s", protocol, userId));
|
||||||
String.format(
|
|
||||||
"\nPROTOCOL: %s\nUSER ID: %s\nQuota exceeded, terminating connection.",
|
|
||||||
protocol, userId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package google.registry.proxy.handler;
|
||||||
import static google.registry.proxy.Protocol.PROTOCOL_KEY;
|
import static google.registry.proxy.Protocol.PROTOCOL_KEY;
|
||||||
|
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
|
import google.registry.proxy.handler.QuotaHandler.OverQuotaException;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -70,6 +71,17 @@ public class RelayHandler<I> extends SimpleChannelInboundHandler<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
|
if (cause instanceof OverQuotaException) {
|
||||||
|
logger.atWarning().withCause(cause).log(
|
||||||
|
"Channel %s closed due to quota exceeded", ctx.channel());
|
||||||
|
ChannelFuture unusedFuture = ctx.close();
|
||||||
|
} else {
|
||||||
|
ctx.fireExceptionCaught(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void writeToRelayChannel(
|
public static void writeToRelayChannel(
|
||||||
Channel channel, Channel relayChannel, Object msg, boolean retry) {
|
Channel channel, Channel relayChannel, Object msg, boolean retry) {
|
||||||
ChannelFuture unusedFuture =
|
ChannelFuture unusedFuture =
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static io.netty.handler.codec.http.HttpHeaderNames.LOCATION;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE;
|
import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderValues.TEXT_PLAIN;
|
import static io.netty.handler.codec.http.HttpHeaderValues.TEXT_PLAIN;
|
||||||
import static io.netty.handler.codec.http.HttpMethod.GET;
|
import static io.netty.handler.codec.http.HttpMethod.GET;
|
||||||
|
import static io.netty.handler.codec.http.HttpMethod.HEAD;
|
||||||
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
|
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
|
||||||
import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
|
import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
|
||||||
import static io.netty.handler.codec.http.HttpResponseStatus.FOUND;
|
import static io.netty.handler.codec.http.HttpResponseStatus.FOUND;
|
||||||
|
@ -32,6 +33,7 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
@ -39,6 +41,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
import io.netty.handler.codec.http.FullHttpResponse;
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpUtil;
|
import io.netty.handler.codec.http.HttpUtil;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
@ -75,6 +78,7 @@ public class WebWhoisRedirectHandler extends SimpleChannelInboundHandler<HttpReq
|
||||||
|
|
||||||
private static final String HSTS_HEADER_NAME = "Strict-Transport-Security";
|
private static final String HSTS_HEADER_NAME = "Strict-Transport-Security";
|
||||||
private static final Duration HSTS_MAX_AGE = Duration.ofDays(365);
|
private static final Duration HSTS_MAX_AGE = Duration.ofDays(365);
|
||||||
|
private static final ImmutableList<HttpMethod> ALLOWED_METHODS = ImmutableList.of(GET, HEAD);
|
||||||
|
|
||||||
private final boolean isHttps;
|
private final boolean isHttps;
|
||||||
private final String redirectHost;
|
private final String redirectHost;
|
||||||
|
@ -87,8 +91,7 @@ public class WebWhoisRedirectHandler extends SimpleChannelInboundHandler<HttpReq
|
||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) {
|
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) {
|
||||||
FullHttpResponse response;
|
FullHttpResponse response;
|
||||||
// We only support GET, any other HTTP method should result in 405 error.
|
if (!ALLOWED_METHODS.contains(msg.method())) {
|
||||||
if (!msg.method().equals(GET)) {
|
|
||||||
response = new DefaultFullHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED);
|
response = new DefaultFullHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED);
|
||||||
} else if (Strings.isNullOrEmpty(msg.headers().get(HOST))) {
|
} else if (Strings.isNullOrEmpty(msg.headers().get(HOST))) {
|
||||||
response = new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST);
|
response = new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST);
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class WebWhoisRedirectHandlerTest {
|
||||||
// HTTP redirect tests.
|
// HTTP redirect tests.
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_http_notGet() {
|
public void testSuccess_http_methodNotAllowed() {
|
||||||
setupChannel(false);
|
setupChannel(false);
|
||||||
request = makeHttpPostRequest("", TARGET_HOST, "/");
|
request = makeHttpPostRequest("", TARGET_HOST, "/");
|
||||||
// No inbound message passed to the next handler.
|
// No inbound message passed to the next handler.
|
||||||
|
@ -156,7 +156,7 @@ public class WebWhoisRedirectHandlerTest {
|
||||||
// HTTPS redirect tests.
|
// HTTPS redirect tests.
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_https_notGet() {
|
public void testSuccess_https_methodNotAllowed() {
|
||||||
setupChannel(true);
|
setupChannel(true);
|
||||||
request = makeHttpPostRequest("", TARGET_HOST, "/");
|
request = makeHttpPostRequest("", TARGET_HOST, "/");
|
||||||
// No inbound message passed to the next handler.
|
// No inbound message passed to the next handler.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue