Search code examples
swiftvaporserver-side-swift

Swift Vapor index.html is not recognised by server as default


Hi I am using vapor for server side with swift programming language. For file serving I correctly configured the middleware in xcode. But index.html in the folder is not recognisable by server itself. But calling specific file http://127.0.0.1:8080/index.html works fine.

If I call http://127.0.0.1:8080/ only then there is an error

"open(file:oFlag:mode:): No such file or directory (errno: 2)"

Code:

import Vapor

import FluentSQL
import FluentKit
import FluentMySQLDriver

// configures your application
public func configure(_ app: Application) throws {
     app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
    app.views.use(.plaintext)
    try routes(app)
}

In the routes(_ app: Application) I used to serve html file by below method but this is also not working and got same error.

app.get("folder") { req in
     
    req.view.render("index.html")
}

How can I serve html file programmatically also How can I make the server index.html recognisable when calling http://127.0.0.1:8080/.


Solution

  • The problem is that you are mixing up what is served using the file middleware and via a route. Your route http://127.0.01:8080/folder is looking for a file called index.html in Resources/Views - that's why you are getting the error at the moment. http://localhost:8080/index.html works because you have a file named index.html in Public.

    I suggest moving index.html into Resources/Views and controlling access via routes. Use Public for static content, JS, etc. not your actual webpages.

    I use the following method to define my routes. This can be in configure.swift, but for larger apps I tend to put it in a helper function, with the other registrations, in a separate file.

    try app.register(collection: InsecureController())
    

    The controller is defined as:

    struct InsecureController: RouteCollection {
        func boot(routes: RoutesBuilder) {
            routes.get("", use: index)
            routes.get("index.html", use: index)
        }
    
        func index(request: Request) async throws -> View {
            return try await request.view.render("index.html")
        }
    }
    

    This results in your app responding to both http://localhost:8080/ and http://localhost:8080/index.html.