@@ -7,52 +7,60 @@ import Foundation
7
7
import GCDWebServers
8
8
9
9
protocol WKEngineWebServerProtocol {
10
- var server : GCDWebServer { get }
10
+ var isRunning : Bool { get }
11
+
11
12
@discardableResult
12
13
func start( ) throws -> Bool
14
+ func stop( )
13
15
16
+ func addTestHandler( )
14
17
func baseReaderModeURL( ) -> String
15
18
}
16
19
17
20
class WKEngineWebServer : WKEngineWebServerProtocol {
18
- private var logger : Logger
19
-
20
21
static let shared : WKEngineWebServerProtocol = WKEngineWebServer ( )
21
22
22
- let server = GCDWebServer ( )
23
-
24
- var base : String {
23
+ private let logger : Logger
24
+ private let server = GCDWebServer ( )
25
+ private var base : String {
25
26
return " http://localhost: \( server. port) "
26
27
}
27
28
28
29
/// The private credentials for accessing resources on this Web server.
29
- let credentials : URLCredential
30
+ private let credentials : URLCredential
30
31
31
32
/// A random, transient token used for authenticating requests.
32
33
/// Other apps are able to make requests to our local Web server,
33
34
/// so this prevents them from accessing any resources.
34
35
private let sessionToken = UUID ( ) . uuidString
35
36
37
+ var isRunning : Bool {
38
+ server. isRunning
39
+ }
40
+
36
41
init ( logger: Logger = DefaultLogger . shared) {
37
42
credentials = URLCredential ( user: sessionToken, password: " " , persistence: . forSession)
38
43
self . logger = logger
39
44
}
40
45
41
46
@discardableResult
42
47
func start( ) throws -> Bool {
43
- // TODO: FXIOS-7894 #17639 Move dependencies for WebServer
44
- // if !server.isRunning {
45
- // try server.start(options: [
46
- // GCDWebServerOption_Port: WKEngineInfo.webserverPort,
47
- // GCDWebServerOption_BindToLocalhost: true,
48
- // GCDWebServerOption_AutomaticallySuspendInBackground: false, // done by the app in AppDelegate
49
- // GCDWebServerOption_AuthenticationMethod: GCDWebServerAuthenticationMethod_Basic,
50
- // GCDWebServerOption_AuthenticationAccounts: [sessionToken: ""]
51
- // ])
52
- // }
48
+ if !server. isRunning {
49
+ try server. start ( options: [
50
+ GCDWebServerOption_Port: WKEngineInfo . webserverPort,
51
+ GCDWebServerOption_BindToLocalhost: true ,
52
+ GCDWebServerOption_AutomaticallySuspendInBackground: false , // done by the app in AppDelegate
53
+ GCDWebServerOption_AuthenticationMethod: GCDWebServerAuthenticationMethod_Basic,
54
+ GCDWebServerOption_AuthenticationAccounts: [ sessionToken: " " ]
55
+ ] )
56
+ }
53
57
return server. isRunning
54
58
}
55
59
60
+ func stop( ) {
61
+ server. stop ( )
62
+ }
63
+
56
64
/// Convenience method to register a dynamic handler. Will be mounted at $base/$module/$resource
57
65
func registerHandlerForMethod(
58
66
_ method: String ,
@@ -62,10 +70,9 @@ class WKEngineWebServer: WKEngineWebServerProtocol {
62
70
) {
63
71
// Prevent serving content if the requested host isn't a safelisted local host.
64
72
let wrappedHandler = { ( request: GCDWebServerRequest ? ) -> GCDWebServerResponse ? in
65
- // TODO: FXIOS-7894 #17639 Move dependencies for WebServer
66
- // guard let request = request,
67
- // InternalURL.isValid(url: request.url)
68
- // else { return GCDWebServerResponse(statusCode: 403) }
73
+ guard let request = request,
74
+ WKInternalURL . isValid ( url: request. url)
75
+ else { return GCDWebServerResponse ( statusCode: 403 ) }
69
76
70
77
return handler ( request)
71
78
}
@@ -108,6 +115,56 @@ class WKEngineWebServer: WKEngineWebServerProtocol {
108
115
return URLForResource ( " page " , module: " reader-mode " )
109
116
}
110
117
118
+ func addTestHandler( ) {
119
+ // Add tracking protection check page
120
+ server. addHandler ( forMethod: " GET " ,
121
+ path: " /test-fixture/find-in-page-test.html " ,
122
+ request: GCDWebServerRequest . self) { ( _: GCDWebServerRequest ? ) in
123
+ let node = """
124
+ <span> And the beast shall come forth surrounded by a roiling cloud of vengeance. \
125
+ The house of the unbelievers shall be razed and they shall be scorched to the earth. \
126
+ Their tags shall blink until the end of days. from The Book of Mozilla, 12:10 And the \
127
+ beast shall be made legion. Its numbers shall be increased a thousand thousand fold. The \
128
+ din of a million keyboards like unto a great storm shall cover the earth, and the followers \
129
+ of Mammon shall tremble. from The Book of Mozilla, 3:31 (Red Letter Edition) </span>
130
+ """
131
+
132
+ let repeatCount = 1000
133
+ let textNodes = [ String] ( repeating: node, count: repeatCount) . reduce ( " " , + )
134
+ return GCDWebServerDataResponse ( html: " <html><body> \( textNodes) </body></html> " )
135
+ }
136
+
137
+ let htmlFixtures = [ " test-indexeddb-private " ,
138
+ " test-window-opener " ,
139
+ " test-password " ,
140
+ " test-password-submit " ,
141
+ " test-password-2 " ,
142
+ " test-password-submit-2 " ,
143
+ " empty-login-form " ,
144
+ " empty-login-form-submit " ,
145
+ " test-example " ,
146
+ " test-example-link " ,
147
+ " test-mozilla-book " ,
148
+ " test-mozilla-org " ,
149
+ " test-popup-blocker " ,
150
+ " test-user-agent " ]
151
+ htmlFixtures. forEach {
152
+ addHTMLFixture ( name: $0, server: server)
153
+ }
154
+ }
155
+
156
+ // Make sure to add files to '/test-fixtures' directory in the source tree
157
+ private func addHTMLFixture( name: String , server: GCDWebServer ) {
158
+ if let filePath = Bundle . main. path ( forResource: " test-fixtures/ \( name) " , ofType: " html " ) {
159
+ let fileHtml = try ? String ( contentsOfFile: filePath, encoding: . utf8)
160
+ server. addHandler ( forMethod: " GET " ,
161
+ path: " /test-fixture/ \( name) .html " ,
162
+ request: GCDWebServerRequest . self) { ( request: GCDWebServerRequest ? ) in
163
+ return GCDWebServerDataResponse ( html: fileHtml!)
164
+ }
165
+ }
166
+ }
167
+
111
168
/// Return a full url, as a string, for a resource in a module.
112
169
/// No check is done to find out if the resource actually exist.
113
170
private func URLForResource( _ resource: String , module: String ) -> String {
0 commit comments