Skip to content

Commit

Permalink
netty more extractions are implemented (#997)
Browse files Browse the repository at this point in the history
Co-authored-by: sokomishalov <[email protected]>
  • Loading branch information
sokomishalov and sokomishalov authored May 3, 2021
1 parent c9d3feb commit c1ed50d
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.zalando.logbook;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.zalando.logbook.DefaultLogbook.SimpleCorrelation;
Expand All @@ -9,9 +10,11 @@
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.Locale;

import static java.time.Clock.fixed;
import static java.time.ZoneOffset.UTC;
import static java.util.Locale.US;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -26,6 +29,11 @@ final class CommonsLogFormatSinkTest {

private final HttpLogWriter writer = mock(HttpLogWriter.class);

@BeforeEach
void setUp() {
Locale.setDefault(US);
}

@Test
void shouldDelegateActive() {
final Sink unit = new CommonsLogFormatSink(writer);
Expand Down
43 changes: 33 additions & 10 deletions logbook-netty/src/main/java/org/zalando/logbook/netty/Request.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
package org.zalando.logbook.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.ssl.SslHandler;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;

import lombok.AllArgsConstructor;
import org.zalando.logbook.HttpHeaders;
import org.zalando.logbook.Origin;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;

import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
import static java.nio.charset.StandardCharsets.UTF_8;
import static lombok.AccessLevel.PRIVATE;
import static org.zalando.logbook.Origin.LOCAL;

@AllArgsConstructor(access = PRIVATE)
final class Request implements org.zalando.logbook.HttpRequest, HeaderSupport {
Expand Down Expand Up @@ -56,19 +65,34 @@ public String getMethod() {

@Override
public String getScheme() {
// TODO pick the real one
return "http";
final SslHandler handler = context.channel().pipeline().get(SslHandler.class);
return handler == null ? "http" : "https";
}

@Override
public String getHost() {
return request.headers().get(HOST, "unknown");
final String host = request.headers().get(HOST);
if (host == null) {
return extractAddress().map(InetSocketAddress::getHostString).orElse("unknown");
} else {
return stripPortIfNecessary(host);
}
}

@Override
public Optional<Integer> getPort() {
// TODO implement
return Optional.empty();
return extractAddress().map(InetSocketAddress::getPort);
}

private String stripPortIfNecessary(String host) {
final int separator = host.indexOf(":");
return separator == -1 ? host : host.substring(0, separator);
}

private Optional<InetSocketAddress> extractAddress() {
final Channel channel = context.channel();
final SocketAddress address = origin == LOCAL ? channel.remoteAddress() : channel.localAddress();
return address instanceof InetSocketAddress ? Optional.of((InetSocketAddress) address) : Optional.empty();
}

@Override
Expand All @@ -89,13 +113,12 @@ public HttpHeaders getHeaders() {
@Nullable
@Override
public String getContentType() {
return request.headers().get(CONTENT_TYPE);
return Objects.toString(HttpUtil.getMimeType(request), null);
}

@Override
public Charset getCharset() {
// TODO pick the real one
return StandardCharsets.UTF_8;
return HttpUtil.getCharset(request, UTF_8);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;

import io.netty.handler.codec.http.HttpUtil;
import lombok.AllArgsConstructor;
import org.zalando.logbook.HttpHeaders;
import org.zalando.logbook.Origin;
Expand Down Expand Up @@ -49,8 +51,7 @@ public String getContentType() {

@Override
public Charset getCharset() {
// TODO pick the real one
return StandardCharsets.UTF_8;
return HttpUtil.getCharset(response, StandardCharsets.UTF_8);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.zalando.logbook.netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.local.LocalAddress;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.ssl.SslHandler;
import org.junit.jupiter.api.Test;

import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.zalando.logbook.Origin.LOCAL;
import static org.zalando.logbook.Origin.REMOTE;

/**
* @author sokomishalov
*/
public class RequestUnitTest {

@Test
void shouldBeDefaultRequest() {
HttpRequest req = mock(HttpRequest.class);
when(req.uri()).thenReturn("/test");
when(req.headers()).thenReturn(new DefaultHttpHeaders().add(CONTENT_TYPE, "text/plain"));
when(req.method()).thenReturn(HttpMethod.GET);
when(req.protocolVersion()).thenReturn(HttpVersion.HTTP_1_1);

ChannelHandlerContext context = mock(ChannelHandlerContext.class);

when(context.channel()).thenReturn(mock(Channel.class));
when(context.channel().pipeline()).thenReturn(mock(ChannelPipeline.class));
when(context.channel().pipeline().get(SslHandler.class)).thenReturn(mock(SslHandler.class));

when(context.channel().remoteAddress()).thenReturn(LocalAddress.ANY);

Request remoteRequest = new Request(context, REMOTE, req);

assertThat(remoteRequest.getScheme()).isEqualTo("https");
assertThat(remoteRequest.getHost()).isEqualTo("unknown");
assertThat(remoteRequest.getPort()).isEmpty();
assertThat(remoteRequest.getContentType()).isEqualTo("text/plain");
assertThat(remoteRequest.getCharset()).isEqualTo(UTF_8);
assertThat(remoteRequest.getRemote()).isEqualTo("local:any");
assertThat(remoteRequest.getRequestUri()).isEqualTo("https://unknown/test");
assertThat(remoteRequest.getOrigin()).isEqualTo(REMOTE);
assertThat(remoteRequest.getMethod()).isEqualTo("GET");
assertThat(remoteRequest.getPath()).isEqualTo("/test");
assertThat(remoteRequest.getProtocolVersion()).isEqualTo("HTTP/1.1");


when(req.headers()).thenReturn(new DefaultHttpHeaders().add(HOST, "localhost"));
Request localRequest = new Request(context, LOCAL, req);

assertThat(localRequest.getHost()).isEqualTo("localhost");
}
}

0 comments on commit c1ed50d

Please sign in to comment.