File: DefaultRequestHandler.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (50 lines) | stat: -rw-r--r-- 2,073 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
 This source file is part of the Swift.org open source project

 Copyright (c) 2021 Apple Inc. and the Swift project authors
 Licensed under Apache License v2.0 with Runtime Library Exception

 See https://swift.org/LICENSE.txt for license information
 See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if canImport(NIOHTTP1)
import Foundation
import NIO
import NIOHTTP1

/// A request handler that serves the default app page to clients.
///
/// The handler returns the contents of `index.html` in the root folder,
/// regardless of the requested URL. This behavior is suitable for
/// serving single-page web apps that display dynamic
/// content, depending on the requested URL path or query parameters.
struct DefaultRequestHandler: RequestHandlerFactory {
    
    /// The root of the documentation to serve.
    let rootURL: URL
    
    func create<ChannelHandler: ChannelInboundHandler>(channelHandler: ChannelHandler) -> RequestHandler
        where ChannelHandler.OutboundOut == HTTPServerResponsePart {
        
        return { context, head in
            let response = try Data(contentsOf: self.rootURL.appendingPathComponent("index.html"))
            
            var content = context.channel.allocator.buffer(capacity: response.count)
            content.writeBytes(response)
            
            var headers = HTTPHeaders()
            headers.add(name: "Content-Length", value: "\(response.count)")
            headers.add(name: "Content-Type", value: "text/html")
            
            // No caching of live preview
            headers.add(name: "Cache-Control", value: "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
            headers.add(name: "Pragma", value: "no-cache")

            let responseHead = HTTPResponseHead(matchingRequestHead: head, status: .ok, headers: headers)
            context.write(channelHandler.wrapOutboundOut(.head(responseHead)), promise: nil)
            context.write(channelHandler.wrapOutboundOut(.body(.byteBuffer(content))), promise: nil)
        }
    }
}
#endif