-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StaticFileHandler weird behaviour on old browsers #33
Comments
Ensure you are passing https://github.com/PerfectlySoft/PerfectTemplate/blob/master/Sources/PerfectTemplate/main.swift#L41 |
I also encounter this kind of errors:
Also, some of my JS files are sometimes incorrectly decoded. I wonder if this can be related to the cache because it eventually works after I refresh the page multiple times without changing anything in my code. |
Update: I dug a little bit deeper using Wireshark and discovered an interesting phenomenon. I think Perfect might be mixing responses and requests. Indeed, I realised that I sometimes get a JS file as response to a PNG request... any idea why? Again, it all works fine if I load my resources from an Apache server, which makes be think that the problem indeed comes from Perfect and not the client. Thanks! |
Do you have content compression enabled? If so, remove that filter and see if it has an effect. I'm just trying to eliminate certain causes at this point. If you can, paste in your code for launching the server, just so I can see if there's anything unusual there. |
I tried both, with and without compression. It has no effect. Sure thing, here is the code: let server = HTTPServer()
let sessionDriver = SessionMemoryDriver()
let routes = [
Route(method: .get, uri: "/**", handler: try! HTTPHandler.staticFiles(data: [
"documentRoot": "./webroot",
"allowResponseFilters": true
])),
Route(method: .get, uri: "/", handler:homeController.indexAction),
// more non-static files routes...
]
server.setRequestFilters([sessionDriver.requestFilter])
server.setResponseFilters([sessionDriver.responseFilter, (Finalizer(), .high)])
/*
With compression:
server.setResponseFilters([sessionDriver.responseFilter, (Finalizer(), .high), (try PerfectHTTPServer.HTTPFilter.contentCompression(data: [:]), HTTPFilterPriority.high)])
*/
server.serverPort = 8181
server.addRoutes(routes)
server.serverName = "localhost"
try! server.start() Here is my response filter ( class Finalizer: HTTPResponseFilter {
public func filterHeaders(response: HTTPResponse, callback: (HTTPResponseFilterResult) -> ()) {
if 400...500 ~= response.status.code {
let pageContent = "An error occured"
response.setBody(string: pageContent)
response.setHeader(.contentLength, value: String(pageContent.count))
callback(.done)
}
else {
callback(.continue)
}
}
public func filterBody(response: HTTPResponse, callback: (HTTPResponseFilterResult) -> ()) {
callback(.continue)
}
} I hope this helps! |
I'm at a bit of a loss here. I don't know of anything that would cause what you are experiencing and was unable to reproduce the issue with your code. I banged away on an iOS 9.3.5 iPad and never saw any anomalies with the requests/responses. Can you check the package versions you are working with? Should be HTTPServer@3.0.23, HTTP@3.3.0, PerfectSession@3.1.5. |
Thank you for your reply! I am indeed using HTTPServer@3.0.23 and PerfectSession@3.1.5. However HTTPServer@3.0.23 is targeting HTTP@3.0.12, hence this is the version I am using instead of 3.3.0. I managed to design a minimal server needed to reproduce the bug. Here is my // swift-tools-version:4.2
import PackageDescription
let package = Package(
name: "RunnifySwift",
dependencies: [
.package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", from: "3.0.23"),
.package(url: "https://github.com/PerfectlySoft/Perfect-Mustache.git", from: "3.0.2")
],
targets: [
.target(
name: "RunnifySwift",
dependencies: ["PerfectHTTPServer", "PerfectMustache"]),
.testTarget(
name: "RunnifySwiftTests",
dependencies: ["RunnifySwift"]),
]
) My server contains 2 Swift files: import PerfectHTTP
import PerfectHTTPServer
import PerfectMustache
import Foundation
let server = HTTPServer()
let WEBROOT = "[path-to-webroot]"
func handlePage(_ controller: @escaping (HTTPRequest) throws -> (String, [String: Any])) -> (HTTPRequest, HTTPResponse) -> Void {
return { req, res in
do {
let (view, data) = try controller(req)
mustacheRequest(request: req, response: res, handler: PageHandler(values: data, sessionData: [:]), templatePath: WEBROOT + view)
}
catch(let error) {
res.setBody(string: error.localizedDescription)
res.completed(status: .internalServerError)
}
}
}
func indexAction(request: HTTPRequest) throws -> (String, [String: Any]) {
return ("pages/Index/index.html.mustache", ["listRaces": []])
}
let routes = Routes([
Route(method: .get, uri: "/**", handler: try! HTTPHandler.staticFiles(data: [
"documentRoot": WEBROOT,
"allowResponseFilters": true
])),
Route(method: .get, uri: "/", handler: handlePage(indexAction))
])
server.serverPort = 80
server.addRoutes(routes)
server.serverName = "localhost"
try! server.start() And import Foundation
import PerfectMustache
import PerfectHTTP
struct PageHandler: MustachePageHandler {
let values: MustacheEvaluationContext.MapType
let sessionData: [String: Any]
func extendValuesForResponse(context contxt: MustacheWebEvaluationContext, collector: MustacheEvaluationOutputCollector) {
contxt.extendValues(with: values)
contxt.extendValues(with: sessionData)
do{ try contxt.requestCompleted(withCollector: collector) }
catch {
let response = contxt.webResponse
response.status = .internalServerError
response.setBody(string: "\(error)")
response.completed()
}
}
} You can find the content of my webroot here (I removed everything that is not necessary). I am running the server on an Early-2015 MacBook Pro (macOS Mojave 10.14.6) and the bug occurs when I try to access the root of the website from Safari, Firefox and Google Chrome running on both an iPad 2 and iPad 3 running iOS 9.5.3 (latest available version for both models). Note that the bug does not occur every time. Best way to trigger it is to empty the cache and reload the page. If it does not occur, it is sometimes necessary to repeat the operation 3-4 times. I hope it helps! 😄 |
That was very helpful, thank you. I am able to reproduce the problem and will report back when I get to the bottom of what's happening. |
So… still not sure exactly what's happening, but I have been able to eliminate several possibilities. It's not mustache; I removed that and just serve the static index page and the problem is still there. It's nothing internal to Perfect mixing up the requests/responses. I added some debugging there and the proper files are being read and returned with the proper mime type and content-length. The strangest bit though is that if I comment out <script src="/vendors/fontawesome/js/all.js"></script> it all loads fine. I switched it to use all.min.js and it still hangs. |
Hello,
I am developing a web platform that I need to work with iPads running iOS9.
I tried accessing it with Safari, Firefox and Chrome but it seems to me that
StaticFileHandler
does not work properly. Indeed, some of my JS and CSS files and my images are not always loaded. I inspected the requests sent by the browser and it seems that some of them randomly never complete, then the browser waits indefinitely for the response.I did not have any problems with newer versions of iOS. I also tried to load the resources from an Apache server and it works fine.
Do you have any idea why this happens?
Thanks!
The text was updated successfully, but these errors were encountered: