change host name to 0.0.0.0 in ktor - kotlin

I want to change host in ktor in a EngineMain project. by default ktor uses 127.0.0.1 host in HOCON file but I want to change it to 0.0.0.0. the problem is when I add host attribute in deployment tag in HOCON file and change it to 0.0.0.0, it's still using the default host (127.0.0.1). I tried other hosts and ktor use them correctly but when I change it to 0.0.0.0 it uses the default host.
how can I fix it?
HOCON file (image)
UPDATE
I realized that my code has no problem I tested my code on another computer and it hosted on 0.0.0.0 but I still have trouble with it I don't know what is hosting me on 127.0.0.1.

i found a solution will it work for you give it a try
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(ContentNegotiation) {
gson {
setPrettyPrinting()
}
}
routing {
get("/") {
call.respondText("Hello, World!", contentType = ContentType.Text.Plain)
}
}
}.start(wait = true)

Related

heroku deploy issue says ktor env

i got the same problem every time i try to deploy to heruko
https://prnt.sc/IeH3wooTqqAj
a screenshot from the terminal
1- https://prnt.sc/fqpj3f2lQTz8
2- https://prnt.sc/-710l_bznc2B
this is my application.kt
fun main() {
embeddedServer(Netty, port = 8087, host = "0.0.0.0") {
module {
module()
}
}.start(wait = true)
}
Suppress("unused")
fun Application.module() {
configureKoin()
configureAuth()
configureRouting()
configureSerialization()
configureMonitoring()
configureSession()
}
Prockfile
web: build/install/com.example.googleauth/bin/com.example.googleauth
worker: python scheduler.py
every thing is uptodate and i also add the Config Vars on heroku setting
i also tryed the embedded way and also the engin way same issue

Remote ip address is ::1 when localhost

I have an ASP.NET Core 6 project deployed as AWS Lambda NET6 runtime and before the upgrade from 3.1 to 6 the code below worked fine returning the remote IP address even when invoked locally.
IHttpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString()
Now when I run it locally it resolves to ::1 and I have read that this might be a problem due to localhost which is something I need to overcome since I rely upon the remote IP address.
From articles found in SO (This, This, and This) I have tried the below.
Adding the below middleware in Startup.cs
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
Also added an endpoint to check what is returned locally and the deployed AWS Lambda (works fine).
[HttpGet("ipaddress")]
public IActionResult GetRemoteIpAddress(CancellationToken cancellationToken)
{
return new JsonResult(new
{
requestContextConnection = Request.HttpContext.Connection.RemoteIpAddress.ToString(),
httpContextaccessorContextConnection = _accessor.HttpContext.Connection.RemoteIpAddress.ToString(),
getRequestIp = GetRequestIP()
});
}
Method GetRequestIP() retrieved from this answer. From the below endpoint I get the below results.
Localhost:
{
"requestContextConnection": "::1",
"httpContextaccessorContextConnection": "::1",
"getRequestIp": "::1"
}
AWS Lambda deployed:
{
"requestContextConnection": "SOME.IP.207",
"httpContextaccessorContextConnection": "SOME.IP.207",
"getRequestIp": "SOME.IP.207"
}
How can I fix the localhost issue that is not supported in Kestrel; (from my understanding); I use SDK 6.0.201.

What is the purpose of IWebHostBuilder.PreferHostingUrls

I know what the documentation says, but I do not know where the IServer gets introduced or how it is configured.
My specific case is that I am calling IHostBuilder.ConfigureWebHost (not ConfigureWebHostDefaults), which as best I can determine does not automatically include Kestrel. I am using HttpSys via a UseHttpSys instead of using Kestrel.
I ran into an issue when I ran two local development websites at the same time. Even though the lauchSettings file had different ports for each, they both did register port 5000. Of course the 2nd site received an error indicating that 5000 was already in use. After much poking around, I found documentation indicating that port 5000 was the default for everything not just Kestrel. (I really believed that prior to 5.0, only Kestrel defaulted to 5000.) I proved the defaults by explicitly setting a URL in my code and it was honored and 5000 was not accessed. I then removed the code and set "urls": "http://localhost:6000" in the appSettings file and it to was honored. At this point I tried both true and false as the parameter to PreferHostingUrls and they both worked with the url configured in the appSettings file and both failed without an explicit url in either the appSettings or code.
So part of the question becomes what is IServer and how is it introduced and configured.
Both the HostBuilder and IWebHostBuilder containing the UseUrls method, it is semicolon-delimited list of IP addresses or host addresses with ports and protocols that the server should listen on for requests. By using this method, we could set the URL that the server should listen on for requests,
Besides, when we configure the Asp.net core application to use Server (such as Http.sys or Kestrel), in the server options, we could also set the URL that the server should listen on for requests, such as using the HttpSysOptions.UrlPrefixes Property or the KestrelServerOptions.Listen() method.
Then, using the PreferHostingUrls property, we could indicate whether the host should listen on the URLs configured on the IWebHostBuilder or those configured on the IServer.
Sample code as below:
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hostsettings.json", optional: true)
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:5000")
.UseConfiguration(config)
.UseHttpSys(serveroptions =>
{
serveroptions.Authentication.Schemes = Microsoft.AspNetCore.Server.HttpSys.AuthenticationSchemes.None;
serveroptions.Authentication.AllowAnonymous = true;
serveroptions.MaxConnections = 100;
serveroptions.MaxRequestBodySize = 30000000;
serveroptions.UrlPrefixes.Add("http://localhost:5001");
})
//.ConfigureKestrel(serverOptions =>
//{
// serverOptions.Limits.MaxConcurrentConnections = 100;
// serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
// serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
// serverOptions.Limits.MinRequestBodyDataRate =
// new MinDataRate(bytesPerSecond: 100,
// gracePeriod: TimeSpan.FromSeconds(10));
// serverOptions.Limits.MinResponseDataRate =
// new MinDataRate(bytesPerSecond: 100,
// gracePeriod: TimeSpan.FromSeconds(10));
// serverOptions.Listen(IPAddress.Loopback, 5001);
// serverOptions.Limits.KeepAliveTimeout =
// TimeSpan.FromMinutes(2);
// serverOptions.Limits.RequestHeadersTimeout =
// TimeSpan.FromMinutes(1);
//})
.PreferHostingUrls(false)
.Configure(app =>
{
app.Run(context =>
context.Response.WriteAsync("Hello, World!"));
});
}
If the PreferHostingUrls is false, it listening the 5001 port:
If the PreferHostingUrls is true, it will listen the 5000 port:
Reference:
How to use HTTP.sys
ASP.NET Core Web Host: Host configuration values

Swashbuckle using port 80 for https when run behind reverse proxy

I have a .net core api documented with swagger/swashbuckle.
When running the swagger ui on localhost on url https://localhost:44390/ the "Try it out" works fine.
We have the same solution in an App service in Azure with an Azure Front Door acting as reverse proxy. Front Door only accepts https traffic and only forwards https traffic. Front door domain is widget.example.com and App service is widget-test-app.azurewebsites.net. When running the swagger ui in Azure using the url https://widget.example.com/api/index.html there are two differences compared to running in localhost:
The swagger ui is showing a Servers -heading and a dropdown
The swagger ui is showing the server url as https://widget.example.com:80
I added an endpoint in the api with the following code
return $"Host {HttpContext.Request.Host.Host} Port {HttpContext.Request.Host.Port} Https {HttpContext.Request.IsHttps}";
When requesting https://widget.example.com/api/v1/test/url it returns
Host widget-test-app.azurewebsites.net Port Https True
This is completely ok since Front door is changing the host header. Port is empty, though.
Summary: Swagger ui is showing the correct domain in the Servers -dropdown but the port number is wrong. How can I get it to either omit the port number if it's 80 or 443, or add it correctly?
Update: The problem is in the swagger.json file which behind the reverse proxy includes a servers element
"servers": [{
"url": "https://widget.example.com:80"
}]
Startup.ConfigureServices
services.AddApiVersioning(options => {
options.Conventions.Add(new VersionByNamespaceConvention());
});
services.AddVersionedApiExplorer(o => {
o.GroupNameFormat = "'v'VVV";
o.SubstituteApiVersionInUrl = true;
});
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo {
Title = "Widget backend v1", Version = "v1"
});
c.SwaggerDoc("v2", new OpenApiInfo {
Title = "Widget backend v2", Version = "v2"
});
c.EnableAnnotations();
c.AddEnumsWithValuesFixFilters();
var xmlFile = $ "{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
Startup.Configure
app.UseSwagger(options => {
options.RouteTemplate = "/api/swagger/{documentname}/swagger.json";
});
app.UseSwaggerUI(options => {
foreach(var description in provider.ApiVersionDescriptions) {
options.SwaggerEndpoint($ "/api/swagger/{description.GroupName}/swagger.json", "widget backend " + description.GroupName);
}
options.RoutePrefix = "api";
});
To fix this I cleared the Servers -list. Here is my code:
app.UseSwagger(options =>
{
options.RouteTemplate = "/api/swagger/{documentname}/swagger.json";
options.PreSerializeFilters.Add((swagger, httpReq) =>
{
//Clear servers -element in swagger.json because it got the wrong port when hosted behind reverse proxy
swagger.Servers.Clear();
});
});
The solution (ok, a - mine - solution :)) is to configure forward headers in Startup.
services.Configure<ForwardHeadersOptions>(options =>
{
options.ForwardHeaders = ForwardHeaders.All; // For, Proto and Host
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
Doing this, any URL generation in the app (behind reverse proxy) should respect the port-forwarding value. According to documentation known networks should be specified (taken from docs):
Only allow trusted proxies and networks to forward headers. Otherwise, IP spoofing attacks are possible.
See ASP.NET documentation for more details.

Ktor Netty Server sending an empty response

I'm using ktor 0.9.5. I'm trying a simple example. But when a try to connect to the server i get ERR_EMPTY_RESPONSE. This is my code.
fun main(args: Array<String>) {
embeddedServer(Netty, port = 8080, host = "localhost") {
install(DefaultHeaders)
install(CallLogging)
routing {
get(path = "/") {
call.respondText("Hello World!!")
}
}
}.start()
}
Doing some research I found that changing the project to Maven fix the problem, but because of rules of my organization I can't do it. Any other solution... Thanks before hand.
I have added a println("sometext") before call.respondText("Hello World!!") and it's never executed.
With ERR_EMPTY_RESPONSE error, I guess you are requesting the server from a Google Chrome browser. Right ?
Are you trying to connect to the server from another computer? If so it won't work because you have set the server to only respond for requests coming from localhost.
embeddedServer(Netty, port = 8080, host = "localhost")
Even if you add a println() it won't execute.
Try to remove host = "localhost" from embeddedServer() parameters an re-test.