I have a static web page stored in the Public folder of my Vapor server. It has an index.html file. However when I navigate to root (http://localhost:8080) it displays Not found.
What I need to do make root point to index.html?
On Vapor 3, adding a home route worked for me. Specifically, I added the route in routes.swift like this:
router.get { req -> Future<View> in
let dir = DirectoryConfig.detect()
let path = dir.workDir + "/Public/index.html"
return try req.view().render(path)
}
For Vapor 4 ...
Inside routes.swift:
app.get { req -> EventLoopFuture<View> in
return req.view.render(app.directory.publicDirectory + "index.html")
}
This assumes you have a "Public" folder in your project directory root with an index.html file inside.
Also, in configure.swift:
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
Build project, run server, and point a browser to localhost:8080, you don't even have to specify localhost:8080/index.html, it just goes.
You could create a middleware to handle this.
import Vapor
final class IndexPageMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
// check if path is /
guard request.url.path == "/" else {
// otherwise pass to next responder
return next.respond(to: request)
}
// respond with index
let indexPath = request.application.directory.publicDirectory + "/index.html"
let response = request.fileio.streamFile(at: indexPath)
return request.eventLoop.makeSucceededFuture(response)
}
}
then in configure.swift add the following
app.middleware.use(IndexPageMiddleware())
Related
I haaave been trying to set up a cloudflare worker to redirecet an URL to another (SOURCE.ie/... -> DESTINATION.com/...).
The destination URL is set up within cloudflare the source-URL however is purchased via Onlydomains.
I have been using the code given in the documentation:
const base = "https://DESTINATION.com"
const statusCode = 301
async function handleRequest(request) {
const url = new URL(request.url)
const { pathname, search } = url
const destinationURL = base + pathname + search
return Response.redirect(destinationURL, statusCode)
}
addEventListener("fetch", async event => {
event.respondWith(handleRequest(event.request))
})
What I think have to do now is to aadd a route but is does not want to do that:
Although I added the nameservers to the Onlydomains URL.
Am I missing something? I just want a simple redirect that replaces SOURCE with DESTINATION :|
I have a Vapor app that needs to do most things authenticated via HTTPS, but also needs to receive unauthenticated PUT requests via HTTP.
Can I conditionalize my route definitions based on the server's host name or authentication type? How can I capture that information from the server?
If you start up the different instances of vapor using the command line argument --hostname, you can put this code in your configure.swift and then include different routes as needed per host. You will then get 404s if invalid routes are attempted on the wrong hosts.
if let index = env.arguments.index(of: "--hostname")
{
if env.arguments.count > index
{
let hostname = env.arguments[index+1]
if hostname == "hostA"
{
// load routes
}
else
{
// load other routes
}
}
}
An alternative is to use custom Middleware. Something like this enables the hostname being called in the request to be inspected and prohibited routes can be re-directed:
struct HostSpecificMiddleware:Middleware
{
func respond( to request: Request, chainingTo next: Responder ) throws -> Future<Response>
{
let host = request.http.headers.filter{ (arg) in let (name, _) = arg; return name == "Host" }[0]
if host.1 == "hostA:8080"
{
if request.http.url.path == "routeA"
{
throw Abort.redirect(to:"routeNotAllowed")
}
}
return try next.respond(to: request)
}
}
You can then configure the middleware into routes in configure.swift using:
let soMW = HostSpecificMiddleware()
let users = router.grouped(uriUsers).grouped(soMW)
The second approach gives you much more flexibility.
I've been messing around with Spring Boot and was pointed at Swagger as a way of documenting my Rest Api.
I managed to get it working except I can't figure out how to customise the index.html file. Whenever I go to http://localhost:8080/index.html it loads the default pet store search bar one and not the one I customised.
I've gone through a tonne of pages online and tried a hundred things but nothing has worked.
Any help would be greatly appreciated.
In my swagger index.html code I have something that looks like this:
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
var pathArray = location.href.split( '/' );
var protocol = pathArray[0];
var host = pathArray[2];
var base = protocol + '//' + host;
if (url && url.length > 1) {
url = url[1];
} else {
url = base + "/api-docs";
}
window.swaggerUi = new SwaggerUi({
url: url,
...
This loads the base, my json code for my swagger api is at /api-docs as you might understand.
It was simple to build my first servlet with spray-io.
But the recources referenced in the header are never found.
< head>
...
< script src="javascript/jquery/jquery-1.9.1.js"/>
...
< / head>
In which directory does one have to put those recsources, or how can spray be directed to look up there?
Simple question, but I could not figure out.
Many thankx
Girgl
With Spray routing, I use these directives -
pathPrefix("css") { get { getFromResourceDirectory("css") } } ~
pathPrefix("js") { get { getFromResourceDirectory("js") } } ~
"css" and "js" have to be in src/main/resources directory
If you are using spray routing, then it should be easy, just provide a route for your static resources. For example you can do the following:
Let's say that your static resources are in /css, /js and /img folders:
def staticPrefixes = List("css", "js", "img") map { pathPrefix(_) } reduce { _ | _ }
with pathPrefix you are making each path a prefix of an unmatched path. Then you need a directive to extract path to static file from the request, for example you can do it like this:
def stripLeadingSlash(path: String) = if (path startsWith "/") path.tail else path
val staticPath =
staticPrefixes &
cache(routeCache()) &
extract(ctx ⇒ stripLeadingSlash(ctx.request.uri.path.toString))
then construct your route which would manage your resources:
val staticRoutes =
get {
staticPath { path ⇒
getFromResource(path.toString)
}
}
I use this method the get the urls of ressources contain on web page
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception
{
final String url = request.getURL();
return super.handleResourceRequest(request);
}
But, I made request.getURL(); it returns relative url and not the absolute url.
How can I change it to get the absolute URL?
When I run your code, it does return me absolute URLs, even when my web page contained relative links. That said, it wouldn't surprise me if sometimes, it doesn't. I haven't fully tested this code, but I would think you could try something like this.
Basically, you check to see if the URL is absolute, and if not, you assemble an absolute URL by using the parent BrowserField document URL:
ProtocolController controller = new ProtocolController(_browserField) {
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception {
String absoluteUrl = null;
URI uri = URI.create(request.getURL());
if (uri.isAbsolute()) {
absoluteUrl = request.getURL();
} else {
String docUrl = _browserField.getDocumentUrl();
String url = request.getURL();
if (url.startsWith("/")) {
// the URL is relative to the server root
URI docUri = URI.create(docUrl);
absoluteUrl = docUri.getScheme() + "://" + docUri.getHost() + url;
} else {
// the URL is relative to the document URL
absoluteUrl = docUrl + url;
}
}
System.out.println(" requesting: " + absoluteUrl);
return super.handleResourceRequest(request);
}
}
Again, for me, I was getting absolute URLs, so I couldn't easily test the code in the branch where the URL is relative. So, it's possible that I'm dropping a "/" somewhere, or not handling file:/// URLs properly.
But, this is a starting point, to workaround your problem.