lvsti / CEF.swift

Swift bindings for the Chromium Embedded Framework
BSD 3-Clause "New" or "Revised" License
94 stars 29 forks source link

Try to load local file with Request Interception #55

Closed ebaujard closed 3 years ago

ebaujard commented 3 years ago

Hi, I try to load a local html file with Request Interception but the browser remains desperately empty.

I have created a CEFRequestHandler :

class TestRequestHandler: CEFRequestHandler {
    func onGetResourceRequestHandler(browser: CEFBrowser, frame: CEFFrame, request: CEFRequest, isNavigation: Bool, isDownload: Bool, initiator: String, disableDefault: inout Bool) -> CEFResourceRequestHandler? {
        disableDefault = true
        return TestResourceRequestHandler()
    }
}

a CEFResourceRequestHandler :

class TestResourceRequestHandler: CEFResourceRequestHandler {
    func cookieAccessFilter(browser: CEFBrowser?, frame: CEFFrame?, request: CEFRequest) -> CEFCookieAccessFilter? {
        return nil
    }

    func resourceHandler(browser: CEFBrowser?, frame: CEFFrame?, request: CEFRequest) -> CEFResourceHandler? {
        return TestResourceHandler()
    }

    func onResourceLoadComplete(browser: CEFBrowser?, frame: CEFFrame?, request: CEFRequest, response: CEFResponse, status: CEFURLRequestStatus, contentLength: Int64) {
        print("Load Complete")
    }
}

and a CEFResourceHandler :

class TestResourceHandler: CEFResourceHandler {
    var fileData:Data?
    var bytesDone:Int = 0

    func onOpenResponseStream(request: CEFRequest, callback: CEFCallback) -> CEFOnOpenResponseStreamAction {
        let fileManager = FileManager.default
        var filePath = Bundle.main.resourcePath!
        let url = request.url!.absoluteString
        let index = url.index(url.startIndex, offsetBy: "http://localhost".characters.count)

        filePath += url.substring(from:index)
        if fileManager.fileExists(atPath: filePath) {
            // Open the file
            let file = FileHandle(forReadingAtPath: filePath)
            fileData = file?.readDataToEndOfFile()
            // Close the file
            file?.closeFile()
        } else {
            print("File not found : " + filePath)
        }
        return .handle
    }

    func onGetResponseHeaders(response: CEFResponse) -> CEFOnGetResponseHeadersAction {
        if fileData != nil{
            response.status = 200;
            response.statusText = "OK";
            return .continueWithResponseLength(UInt64(fileData!.count))
        }
        return .abort
    }

    func onReadResponseData(buffer: UnsafeMutableRawPointer, bufferLength: Int, callback: CEFResourceReadCallback) -> CEFOnReadResponseDataAction {
        let nsData = fileData! as NSData
        let chunkSize = min(fileData!.count - bytesDone, bufferLength)
        if (chunkSize <= 0){
            return .complete
        }
        buffer.copyMemory(from: nsData.bytes.advanced(by: bytesDone), byteCount: chunkSize)
        bytesDone += chunkSize
        return .read(chunkSize)
    }

}

The onResourceLoadComplete is called but nothing is displayed.

I probably forgot something but what ? Do you have a sample code with request interception ?

Thank you in advance

ebaujard commented 3 years ago

It was the absence of the mimetype that was the cause of the problem.