Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.

Customize handling of http 502#12

Merged
osklyarenko merged 10 commits into
verygoodsecurity:vgs-editionfrom
viacheslav-fomin-main:feature/custom-message-invalid-cert
Jun 1, 2017
Merged

Customize handling of http 502#12
osklyarenko merged 10 commits into
verygoodsecurity:vgs-editionfrom
viacheslav-fomin-main:feature/custom-message-invalid-cert

Conversation

@viacheslav-fomin-main
Copy link
Copy Markdown
Collaborator

@viacheslav-fomin-main viacheslav-fomin-main commented May 30, 2017

Prerequisite to https://github.com/verygoodsecurity/vault/pull/1380.

Adds ability to set up a custom http response on upstream server connection failure.

FullHttpResponse response = ProxyUtils.createFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, body);
HttpResponseStatus status = HttpResponseStatus.BAD_GATEWAY;

if (cause instanceof SSLHandshakeException) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the check may be improved

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of doing this can we implement a method which can be overridden? this way implementors would be able to customize the message based on their own logic. if the writeBadGateway was protected for instance we could override it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjallday hm, great idea!

@viacheslav-fomin-main
Copy link
Copy Markdown
Collaborator Author

@mjallday we can not just simply override writeBadRequest method as we do not inherit it. But your idea is implemented, the code is more complex though.

@@ -0,0 +1,37 @@
package org.littleshoot.proxy;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in this class is copied from writeBadRequest method of ClientToProxyConnection class

@viacheslav-fomin-main viacheslav-fomin-main changed the title Adds custom message when there is a problem with upstream server cert Adds ability to set up a custom http response on upstream server connection failure May 31, 2017
Copy link
Copy Markdown

@pgyschuk pgyschuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@viacheslav-fomin-main
Copy link
Copy Markdown
Collaborator Author

@mjallday we need to come up with versioning system here..

* @param httpRequest the HttpRequest that is resulting in the Bad Gateway response
* @return true if the connection will be kept open, or false if it will be disconnected
*/
private boolean writeBadGateway(HttpRequest httpRequest) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viacheslav-fomin-main i see that the respondWithShortCircuitResponse method calls currentFilters.proxyToClientResponse.

i'm wondering if it's possible for us to implement similar functionality in that method without making this change.

e.g.

@Override
public HttpObject handleProxyToClientResponse(HttpObject httpObject) {
  if (httpObect.statusCode() == HttpResponseStatus.BAD_GATEWAY) {
    // logic here
  }
}

import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;

public interface ServerConnectionFailureHttpResponseComposer {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsure about the naming on this. it seems wrong to limit it to just server connection failures. how about just HttpResponseComposer?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it should contain failure in it as it expects throwable cause.. it can not be used for constructing OK response.. so FailureHttpResponseComposer? @mjallday

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

javadoc is missing

**************************************************************************/

/**
* Tells the client that something went wrong trying to proxy its request. If the Bad Gateway is a response to
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should keep this comment i believe.

*
* @param unrecoverableFailureHttpResponseComposer
* @return
*/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls provide a proper javadoc

* @return true if the connection will be kept open, or false if it will be disconnected
*/
@Override
public FullHttpResponse compose(HttpRequest httpRequest, Throwable cause) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should unit test for this component.

}

public FullHttpResponse compose(HttpRequest httpRequest) {
return this.compose(httpRequest, null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a leaky abstraction to me. let's just stick to compose(httpRequest, null); and not expose this method

}

return respondWithShortCircuitResponse(response);
private boolean writeBadGateway (HttpRequest httpRequest) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spacing

// don't allow any body content in response to a HEAD request
response.content().clear();
}
return response;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the following part will be common between various implementations

    FullHttpResponse response = ProxyUtils.createFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, body);

    if (ProxyUtils.isHEAD(httpRequest)) {
      // don't allow any body content in response to a HEAD request
      response.content().clear();
    }
    return response;

so we should abstract it away

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/src/main/java/org/littleshoot/proxy/BadGatewayFailureHttpResponseComposer.java b/src/main/java/org/littleshoot/proxy/BadGatewayFailureHttpResponseComposer.java
index 26bcd78..b7e8abd 100644
--- a/src/main/java/org/littleshoot/proxy/BadGatewayFailureHttpResponseComposer.java
+++ b/src/main/java/org/littleshoot/proxy/BadGatewayFailureHttpResponseComposer.java
@@ -20,7 +20,7 @@ public final class BadGatewayFailureHttpResponseComposer implements ServerConnec
    */
   @Override
   public FullHttpResponse compose(HttpRequest httpRequest, Throwable cause) {
-    String body = "Bad Gateway: " + httpRequest.getUri();
+    String body = provideCustomMessage(httpRequest, cause);
 
     FullHttpResponse response = ProxyUtils.createFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, body);
 
@@ -31,6 +31,10 @@ public final class BadGatewayFailureHttpResponseComposer implements ServerConnec
     return response;
   }
 
+  protected String provideCustomMessage(HttpRequest httpRequest, Throwable cause) {
+    return "Bad Gateway: " + httpRequest.getUri();
+  }
+
   public FullHttpResponse compose(HttpRequest httpRequest) {
     return this.compose(httpRequest, null);
   }

Copy link
Copy Markdown

@osklyarenko osklyarenko Jun 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this way you custom implementation would be a specialization of the default impl provided by BadGatewayFailureHttpResponseComposer.

@osklyarenko osklyarenko changed the title Adds ability to set up a custom http response on upstream server connection failure Customize handling of http 501 Jun 1, 2017
@osklyarenko osklyarenko changed the title Customize handling of http 501 Customize handling of http 502 Jun 1, 2017
@osklyarenko osklyarenko self-requested a review June 1, 2017 10:27
Copy link
Copy Markdown

@osklyarenko osklyarenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls provide a better abstraction and add missing tests.


FullHttpResponse response = ProxyUtils.createFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY, body);

if (ProxyUtils.isHEAD(httpRequest)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not tested.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

badgatewaytest
well, it is tested by the original littleproxy tests.. but okay, lets add additional test
@osklyarenko

@osklyarenko osklyarenko merged commit 24f8ac9 into verygoodsecurity:vgs-edition Jun 1, 2017
@osklyarenko osklyarenko added this to the Enhancements to HTTPS proxy milestone Jun 13, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants