https://kotlinlang.org logo
#http4k
Title
# http4k
a

Andrew Worley

06/02/2020, 12:29 PM
Hi guys, we're currently trying to use http4k as a reverse proxy, and wanted to pass an incoming request to a client (which client depends on matching the path in the request), and then return the response from the client to the originating requestor. We're having some trouble with tests at the moment - we wanted to create a fake server in our test (to simulate the service we proxy to), and capture the request that it receives, so assert that our proxy passed on the request correctly. The issue that we're having is when trying to call bodyString() on the captured request, this just hangs. We think it's something to do with the body already being consumed, but wondered if you could help explain what we're doing wrong here? I'll post the example test and HttpHandler code. Thanks in advance!
d

dave

06/02/2020, 12:56 PM
Yep - it definitely looks to be stream related. If you substitute Undertow for Jetty you can see that the stream has been consumed (it throws up)
whilst we try to explain it, you can make the test pass by using this line in the mock backend
Copy code
capturedRequest = request.body(request.bodyString())
a

Andrew Worley

06/02/2020, 1:13 PM
Ok brill thanks @dave - we changed to Undertow and saw the same as you (reassuring), and copying the body has made the test work for now
s

s4nchez

06/02/2020, 2:58 PM
@Andrew Worley for a bit more context Your test is capturing the request while it's handled by server, but trying to manipulate (i.e. read its body) after the request has effectively finished, so it relies on what that specific implementation of InputStream will allow you to do. Both servers break in this case because any data transfer should already have happened by then. Unfortunately, jetty's implementation of InputStream in this case will hang when you try to access it, perhaps because they've never envision it to be used in such way. TL;DR different backends handle streaming in different ways, and if you need to inspect a request body after the streaming has happened, you need to consume the request stream before it gets discarded by the server.
a

Andrew Worley

06/02/2020, 4:01 PM
Ok cool - thanks guys, makes sense. From looking at Request/Response/HttpMessage it looks like only the Body is a stream - am I right in thinking that it should be safe to inspect other properties (headers, status, etc.) after the request has finished being processed, or would you recommend against doing that?
s

s4nchez

06/02/2020, 4:44 PM
@Andrew Worley yes, all the other properties are safe. You can also "materialise" the stream by doing something like
capturedRequest = request.body(request.bodyString())
as well, and then it'll be fully safe.
a

Andrew Worley

06/02/2020, 4:45 PM
Cool - thanks @s4nchez!
10 Views