How to get the full URL from an Http4s Request - scala

I'm trying to obtain the beginning of the URL that a client used to access a webserver in Http4s. I.e. given a Request[F] I want to obtain the string "http://localhost:8080" or "https://my-app.company.com" depending on where the server is deployed.
In a server implementation with Http4s, when receiving a Request via something like
HttpRoutes.of[IO] {
case req =>
println(req.uri)
???
}
I only ever seem to get a relative URI, e.g. / or /foo/bar - the scheme and authority fields on the Uri are both None.
It looks like I can pull the localhost:8080 part from the Host header on the request, but I have no solution for the scheme (http:// or https://).
How can I fill in the correct value for request.uri.scheme? And is there a more appropriate way to obtain the host?
FWIW I'm using http4s 0.22

You can't get it while using Blaze as an HTTP server. There are workarounds. You can catch bound of a server:
By port:
[io-compute-4] INFO org.http4s.blaze.channel.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:8080
By schema:
[io-compute-4] INFO org.http4s.blaze.server.BlazeServerBuilder - http4s v1.0.0-M33 on blaze v1.0.0-M33 started at http://[::]:8080/
Or you can map 8080 to HTTP and 8081 to HTTPS and make pattern matching on it.
A bad workaround would be to add it as an HTTP header and read it via Headers
It legacy practice but many legacy software companies are still using this approach.

Related

Vertx reverse proxy redirect handling

I'm pretty new to Vertx, I'm building a reverse proxy on Quarkus.
I need to handle a redirect response from my Apache to my Quarkus reverse proxy, so that my Client doesn't get redirected directly to the Apache server (bypassing the proxy).
Resource is located in custom.url/myResource/index.php
My reverse proxy is running on localhost:8080
Basically what happens is:
Browser sends a GET request on localhost:8080/myResource, Quarkus is listening on 8080 so he receives the request, remaps the url tocustom.url/myResource and forwards to Apache.
Apache creates a redirect response, because a slash was missing at the end of the url, so he sends a 301 response with the Location header set to custom.url/myResource/ (with slash at the end) to the Quarkus reverse proxy.
Quarkus will forward the redirect response (301 custom.url/myResource/) to the Client, so he will make a GET call straight to custom.url/myResource/ bypassing the Reverse Proxy.
This behavior is not acceptable, since I can't allow the client to know the resource address of my backend service.
Code snippet
Route route = this.proxyRouter.route(method, path)
.handler(CorsHandler.create("*"))
.handler(LoggerHandler.create())
.handler(ctx ->{ //need to create an handler to handle this behaviour })
.handler(ProxyHandler.create(myProxy);
What i have to do is basically setting the Location header of the response to the correct path, including the slash.
I tried to get the request.absoluteURI() hostname, the response subdomain (with the slash) and merge them together.
request URI: localhost:8080/myResource -> localhost:8080 (1)
response Location: custom.url/myResource/ -> /myResource/ (2)
So i get the wanted Location header merging (1) and (2): localhost:8080/myResource/
Logically this works, but I don't know where and if I'm able to do this inside the handler, or if I need to do it some other way. I tried to implement this logic inside the handler, but I'm only able to get the request URI, there was no way to find the 301 response.
Need help plz.

In Mirth (nextgen-connect) how do I configure the HTTP URL of an HTTP Listener

The manual says this about the HTTP URL value of an http listener:
"Displays the generated HTTP URL for the HTTP Listener. This is not an actual
configurable setting, but is instead displayed for copy/paste convenience. Note
that the host in the URL will be the same as the host you used to connect to
the Administrator. The actual host that connecting clients use may be different
due to differing networking environments."
When I have used the feature in the past its value has always begun "http://localhost:" which would be great except this time it is auto-generating " http://'domainName':${Incoming_Pathology_Source_Port}/${Incoming_Pathology_Source_BaseContextPath}/"
For the first time, we are deploying Mirth inside a Kubernetes cluster, 'a different working environment'. (nginx accepts https and we want it pass the messages on as http to Mirth).
Is there any way I can take control of the URL or must I change the configuration of the cluster in some way.
All help/suggestions welcome.

Custom endpoint path for AWS API Gateway WebSocket

I have created an API Gateway with Websocket protocol.
After I deploy the API, I get a WebSocket URL and a connection URL.
e.g.
WebSocket URL: wss://xxxx.execute-api.us-west-2.amazonaws.com/test
Connection URL: https://xxxx.execute-api.us-west-2.amazonaws.com/test/#connections
Now everything is fine, I am able to connect to the API, and send and receive messages.
But when I try to access a different path, I get an HTTP 403 error.
e.g. If I try to connect to wss://xxxx.execute-api.us-west-2.amazonaws.com/test/some/path
, I get 403 error.
Is it possible to configure API gateway in such a way that it accepts connections to all paths and passes on the path, i.e. /some/path in my case, to the $connect route handler?
This is not yet supported by AWS. See the article and comments here https://medium.com/#lancers/using-parameter-mapping-in-websocket-api-67b414376d5e
There is a workaround with using an additional server, author of the article proposes the following:
you may put your own server that accepts an URI with path parameters, then return 302 to redirect the client to the WebSocket API endpoint with query string instead.

How to get server name without using Host header from http request

In my Play 2.5.x (Scala) web application I am using following technique to get absolute URL of the route (server name + uri):
controllers.routes.MyController.MyRoute.absoluteURL()
I recently found out that it uses Host header in the incoming http request to return absolute url. Use of Host header is not recommended as it's quite easy to do Host header injection attack.
Is there a secure way of getting the server name ?
Have a look at Play! implementation of CSRF attack protection and the Allowed Hosts configuration.
You can specify known hosts with the latter and it will reject requests from unknown hosts.

Accessing couchdb futon thru https

I've got a problem accessing futon interface when it is proxied using nginx.
This config works fine when http protocol is used, but when I try to use
https, I constantly receive no_db_file errors (but operations succeed,
e.g. I can create databases, insert values, etc.)
location / {
proxy_pass http://127.0.0.1:5984;
}
What can I do to make it work correctly using https protocol?
I have used Apache proxying to proxy https to http to do https on CouchDB: http://wiki.apache.org/couchdb/Apache_As_a_Reverse_Proxy
I have found that a trailing slash on the URL affects whether or not https proxying works. Maybe it affects Nginx the same way?
That's not bad! At least you have a working link between nginx and CouchDB.
no_db_file is CouchDB's 404 response when a database (the first thing after the slash) is not there. Check the logs and see what path CouchDB actually received in the query. It may be one of the AJAX calls that Futon does; but whatever it is, the logs will say.