-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proxy fail with nothing when use BodyHandler before the router #26
Comments
Closing as outdated, can't reproduce with 4.5.7 |
Sorry @tsegismont, class SimpleProxy(private val authorizationHandler: AuthorizationHandler) {
@SuppressWarnings
fun onStart(@Observes router: Router, vertx: Vertx) {
val proxyClient: HttpClient = vertx.createHttpClient(HttpClientOptions().setTrustAll(false))
val proxy: HttpProxy = HttpProxy.reverseProxy(proxyClient)
proxy.origin(ORIGIN_PORT, ORIGIN_HOST)
router
.route()
.path("/authorize/*")
.handler(BodyHandler.create())
.handler(ProxyHandler.create(proxy))
}
companion object {
const val ORIGIN_PORT = 8888
const val ORIGIN_HOST = "localhost"
}
} It always throws "Uncaught exception received by Vert.x: java.lang.IllegalStateException: Request has already been read" |
In fact, the body handler shouldn't be added before the |
Hi @tsegismont ,
It seems the only way to declare bodyHandler is inside interceptor as in sample below override fun handleProxyRequest(context: ProxyContext): Future<ProxyResponse> {
// Rewrite uri to remove useless part
context.request().uri = context.request().uri.substringAfter("/authorize")
val originalRequest = context.request().proxiedRequest()
originalRequest.bodyHandler { requestBody ->
if (requestBody.length() > 0) {
try {
checkAuthorization(context, requestBody)
} catch (e: UnauthorizedException) {
sendErrorResponse(context, e)
}
} else {
// Continue the interception chain
context.sendRequest()
}
}
return context.sendRequest()
}
|
I don't understand why you want to add the |
I'm trying to set up an authorization process that requires scanning the body (for example: as a manager I can ask for my coworkers' salary, but I can't see all other salaries). And I want to do that in front of backend, I can't modify. |
Do you mean, scanning the body of the request? |
Exactly, I need to scan values used in the body to authorize or not |
Then you should use a Something like this should do the trick: HttpProxy httpProxy = HttpProxy.reverseProxy(proxyClient);
httpProxy.addInterceptor(new ProxyInterceptor() {
@Override
public Future<ProxyResponse> handleProxyRequest(ProxyContext context) {
ProxyRequest proxyRequest = context.request();
Collector<Buffer, Buffer, Buffer> collector = Collector.of(Buffer::buffer, Buffer::appendBuffer, Buffer::appendBuffer);
return proxyRequest.getBody().stream().collect(collector).compose(body -> {
if (isValid(body)) { // Validate the body content here
return context.sendRequest();
}
ProxyResponse proxyResponse = proxyRequest.response().setStatusCode(403);
return Future.succeededFuture(proxyResponse);
});
}
}); |
Thanks @tsegismont, override fun handleProxyRequest(context: ProxyContext): Future<ProxyResponse> {
return context.request()
.proxiedRequest()
.resume()
.body()
.compose { buffer ->
// Reset body for proxy use ?
context.request().body = Body.body(buffer)
isValid(context, buffer)
context.sendRequest()
}
.onFailure { // Catch unauthorized
sendErrorResponse(context, it)
}
} It seems to work ... I only have "java.lang.IllegalStateException: Request has already been read" when target backend is out. |
It's a new method in Vert.x 4.5.8 that allows to collect all the elements in the stream.
Can you try:
If you need to inspect the backend reponse, I would suggest to override |
Hi @tsegismont,
I think since the request was not sent to the backend proxyRequest.response() returns null, I fixed this with return context.request()
.proxiedRequest()
.response()
.setStatusCode(403)
.send() Everything is fine as long as the target backend is present ... or the strange exception "Request has already been read" appears. I think a "Target unreachable" or "Bad gateway" would be less confusing. Due to my misunderstanding, I spent a few days thinking that body manipulation was the cause when the problem was that the target was unreachable.
Already done ;) |
Ok, thanks for all the details. Would you mind creating a separate bug report for the exception logged when the backend is absent. A small reproducer to go with it would be great. |
Yes I'll prepare it asap. |
Questions
if i add a BodyHandler before proxyRouter ,it can not get anything but wait always
the origin server is :
the proxy server is :
if i remove the BodyHandler it can proxy correct
Version
vertx version :4.1.5
OS version: Win10
JVM version:1.8
The text was updated successfully, but these errors were encountered: