Skip to content

Commit

Permalink
yegor256#377: Changed the implementatin the TkProxy class.
Browse files Browse the repository at this point in the history
  • Loading branch information
bdragan committed Nov 4, 2015
1 parent ee9ff32 commit 1be6866
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 186 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>test</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
Expand Down Expand Up @@ -213,7 +213,7 @@
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/takes/rs/RsWithHeaders.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
@EqualsAndHashCode(callSuper = true)
public final class RsWithHeaders extends RsWrap {

/**
* Ctor.
* @param headers Headers
*/
public RsWithHeaders(final Iterable<? extends CharSequence> headers) {
this(new RsEmpty(), headers);
}

/**
* Ctor.
* @param res Original response
Expand Down
183 changes: 97 additions & 86 deletions src/main/java/org/takes/tk/TkProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,124 +23,135 @@
*/
package org.takes.tk;

import com.google.common.net.HostAndPort;
import com.jcabi.http.request.ApacheRequest;
import java.io.IOException;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.takes.Request;
import org.takes.Response;
import org.takes.Take;
import org.takes.rq.RqHeaders;
import org.takes.rq.RqHref;
import org.takes.rq.RqLengthAware;
import org.takes.rq.RqMethod;
import org.takes.rs.RsWithBody;
import org.takes.rs.RsWithHeaders;
import org.takes.rs.RsWithStatus;

/**
* Proxy take.
*
* <p>This take may transform the request before passing it
* to the original take and/or transform the response received
* from the original take.
*
* <p>If the request transformer is not provided, the original
* request is passed to the original take.
*
* <p>If the response transformer is not provided, the response
* received from the original take is returned.
* Take that proxies requests to another destination.
*
* <p>The class is immutable and thread-safe.
*
* @author Dragan Bozanovic ([email protected])
* @version $Id$
* @since 0.25
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
* @todo #377 We need the integration test for this class.
* The test should verify the different HTTP methods (GET, POST, etc),
* as well as the different combinations of request/response headers.
*/
@ToString
@EqualsAndHashCode(of = { "origin", "rqtransformer", "rstransformer" })
public final class TkProxy implements Take {

/**
* Original take.
*/
private final transient Take origin;
public class TkProxy implements Take {

/**
* Request transformer.
* Target host to which requests are forwarded.
*/
private final transient RqTransformer rqtransformer;

/**
* Response transformer.
*/
private final transient RsTransformer rstransformer;
private final transient HostAndPort host;

/**
* Ctor.
* @param take Original take
* @param rqtransformr Request transformer
* @param rstransformr Response transformer
* @param target Target to which requests are forwarded
*/
public TkProxy(final Take take, final RqTransformer rqtransformr,
final RsTransformer rstransformr) {
this.origin = take;
this.rqtransformer = rqtransformr;
this.rstransformer = rstransformr;
public TkProxy(final HostAndPort target) {
this.host = target;
}

/**
* Ctor.
* @param take Original take
* @param rqtransformr Request transformer
*/
public TkProxy(final Take take, final RqTransformer rqtransformr) {
this(take, rqtransformr, new RsTransformer() {
@Override
public Response transform(final Response response) {
return response;
@Override
public final Response act(final Request req) throws IOException {
final RqHref.Base base = new RqHref.Base(req);
final String home = new RqHref.Smart(base).home().bare();
final String dest = StringUtils.replace(
base.href().toString(),
home,
String.format("http://%s/", this.host.toString())
);
final String method = new RqMethod.Base(req).method();
com.jcabi.http.Request proxied = new ApacheRequest(dest)
.method(method);
final RqHeaders.Base headers = new RqHeaders.Base(req);
for (final String name : headers.names()) {
if ("content-length".equals(name.toLowerCase(Locale.ENGLISH))) {
continue;
}
if (isHost(name)) {
proxied = proxied.header(name, this.host.toString());
continue;
}
});
for (final String value : headers.header(name)) {
proxied = proxied.header(name, value);
}
}
if (Arrays.asList("POST", "PUT").contains(method)) {
proxied = proxied.body()
.set(IOUtils.toByteArray(new RqLengthAware(req).body()))
.back();
}
return this.response(home, dest, proxied.fetch());
}

/**
* Ctor.
* @param take Original take
* @param rstransformr Response transformer
* Creates the response received from the target host.
*
* @param home Home host
* @param dest Destination URL
* @param rsp Response received from the target host
* @return Response
*/
public TkProxy(final Take take, final RsTransformer rstransformr) {
this(take, new RqTransformer() {
@Override
public Request transform(final Request request) {
return request;
}
}, rstransformr);
}

@Override
public Response act(final Request req) throws IOException {
return this.rstransformer.transform(
this.origin.act(
this.rqtransformer.transform(req)
private Response response(final String home, final String dest,
final com.jcabi.http.Response rsp) {
final Collection<String> hdrs = new LinkedList<String>();
hdrs.add(
String.format(
"X-Takes-TkProxy: from %s to %s",
home, dest
)
);
for (final Map.Entry<String, List<String>> entry
: rsp.headers().entrySet()) {
for (final String value : entry.getValue()) {
final String val;
if (isHost(entry.getKey())) {
val = this.host.toString();
} else {
val = value;
}
hdrs.add(String.format("%s: %s", entry.getKey(), val));
}
}
return new RsWithStatus(
new RsWithBody(
new RsWithHeaders(hdrs),
rsp.binary()
),
rsp.status(),
rsp.reason()
);
}

/**
* Request transformer.
*/
public interface RqTransformer {

/**
* Transforms the original request.
* @param request Original request
* @return The transformed request
*/
Request transform(Request request);
}

/**
* Response transformer.
* Checks whether the provided argument is a "Host" header name.
* @param header Header name
* @return Returns {@code true} if {@code header} parameter is a "Host"
* header name, {@code false} otherwise
*/
public interface RsTransformer {

/**
* Transforms the original response.
* @param response Original response
* @return Transformed response
*/
Response transform(Response response);
private static boolean isHost(final String header) {
return "host".equals(header.toLowerCase(Locale.ENGLISH));
}
}
97 changes: 0 additions & 97 deletions src/test/java/org/takes/tk/TkProxyTest.java

This file was deleted.

0 comments on commit 1be6866

Please sign in to comment.