(dirPath: string, port: number, loopback?: string, sslOptions?: object)
| 83 | } |
| 84 | |
| 85 | constructor(dirPath: string, port: number, loopback?: string, sslOptions?: object) { |
| 86 | if (sslOptions) |
| 87 | this._server = createHttpsServer(sslOptions, this._onRequest.bind(this)); |
| 88 | else |
| 89 | this._server = createHttpServer(this._onRequest.bind(this)); |
| 90 | this._server.on('connection', socket => this._onSocket(socket)); |
| 91 | this._wsServer = new WebSocketServer({ noServer: true }); |
| 92 | this._server.on('upgrade', async (request, socket, head) => { |
| 93 | const doUpgrade = () => { |
| 94 | this._wsServer.handleUpgrade(request, socket, head, ws => { |
| 95 | // Next emit is only for our internal 'connection' listeners. |
| 96 | this._wsServer.emit('connection', ws, request); |
| 97 | }); |
| 98 | }; |
| 99 | if (this._upgradeCallback) { |
| 100 | this._upgradeCallback({ doUpgrade, socket }); |
| 101 | return; |
| 102 | } |
| 103 | const pathname = new URL(request.url, 'http://localhost').pathname; |
| 104 | if (pathname === '/ws-401') { |
| 105 | socket.write('HTTP/1.1 401 Unauthorized\r\n\r\nUnauthorized body'); |
| 106 | socket.destroy(); |
| 107 | return; |
| 108 | } |
| 109 | if (pathname === '/ws-slow') |
| 110 | await new Promise(f => setTimeout(f, 2000)); |
| 111 | if (!['/ws', '/ws-slow'].includes(pathname)) { |
| 112 | socket.write('HTTP/1.1 400 Bad Request\r\n\r\n'); |
| 113 | socket.destroy(); |
| 114 | return; |
| 115 | } |
| 116 | doUpgrade(); |
| 117 | }); |
| 118 | this._server.listen(port); |
| 119 | this._dirPath = dirPath; |
| 120 | this.debugServer = require('debug')('pw:testserver'); |
| 121 | |
| 122 | this._startTime = new Date(); |
| 123 | this._cachedPathPrefix = null; |
| 124 | |
| 125 | const cross_origin = loopback || '127.0.0.1'; |
| 126 | const same_origin = loopback || 'localhost'; |
| 127 | const protocol = sslOptions ? 'https' : 'http'; |
| 128 | this.PORT = port; |
| 129 | this.PREFIX = `${protocol}://${same_origin}:${port}`; |
| 130 | this.CROSS_PROCESS_PREFIX = `${protocol}://${cross_origin}:${port}`; |
| 131 | this.EMPTY_PAGE = `${protocol}://${same_origin}:${port}/empty.html`; |
| 132 | this.HOST = new URL(this.EMPTY_PAGE).host; |
| 133 | this.HOSTNAME = new URL(this.EMPTY_PAGE).hostname; |
| 134 | this.HELLO_WORLD = `${this.PREFIX}/hello-world`; |
| 135 | } |
| 136 | |
| 137 | async waitUntilReady() { |
| 138 | await new Promise(x => this._server.once('listening', x)); |
nothing calls this directly
no test coverage detected