9d9fb99891959c5d0ae50a0788d6b8980e5a90c3
[WebKit.git] / Websites / perf.webkit.org / tools / js / remote.js
1 'use strict';
2
3 let assert = require('assert');
4 let http = require('http');
5 let https = require('https');
6 let querystring = require('querystring');
7 let CommonRemoteAPI = require('../../public/shared/common-remote.js').CommonRemoteAPI;
8
9 class NodeRemoteAPI extends CommonRemoteAPI {
10     constructor(server)
11     {
12         super();
13         this._server = null;
14         this._cookies = new Map;
15         if (server)
16             this.configure(server);
17     }
18
19     url(path)
20     {
21         let scheme = this._server.scheme;
22         let port = this._server.port;
23         let portSuffix = this._server.port == this._server.defaultPort ? '' : `:${port}`;
24         if (path.charAt(0) != '/')
25             path = '/' + path;
26         return `${scheme}://${this._server.host}${portSuffix}${path}`;
27     }
28
29     configure(server)
30     {
31         assert(server.scheme === 'http' || server.scheme === 'https');
32         assert.equal(typeof(server.host), 'string', 'host should be a string');
33         assert(!server.port || typeof(server.port) == 'number', 'port should be a number');
34
35         let auth = null;
36         if (server.auth) {
37             assert.equal(typeof(server.auth), 'object', 'auth should be a dictionary with username and password as keys');
38             assert.equal(typeof(server.auth.username), 'string', 'auth should contain a string username');
39             assert.equal(typeof(server.auth.password), 'string', 'auth should contain a string password');
40             auth = {
41                 username: server.auth.username,
42                 password: server.auth.password,
43             };
44         }
45
46         const defaultPort = server.scheme == 'http' ? 80 : 443;
47         this._server = {
48             scheme: server.scheme,
49             host: server.host,
50             port: server.port || defaultPort,
51             defaultPort: defaultPort,
52             auth: auth,
53         };
54     }
55
56     clearCookies() { this._cookies = new Map; }
57
58     postFormUrlencodedData(path, data)
59     {
60         const contentType = 'application/x-www-form-urlencoded';
61         const payload = querystring.stringify(data);
62         return this.sendHttpRequest(path, 'POST', contentType, payload).then(function (result) {
63             return result.responseText;
64         });
65     }
66
67     sendHttpRequest(path, method, contentType, content, headers = {}, responseHandler = null)
68     {
69         let server = this._server;
70         return new Promise((resolve, reject) => {
71             let options = {
72                 hostname: server.host,
73                 port: server.port,
74                 auth: server.auth ? server.auth.username + ':' + server.auth.password : null,
75                 method: method,
76                 path: path,
77             };
78
79             let request = (server.scheme == 'http' ? http : https).request(options, (response) => {
80                 let responseText = '';
81                 if (responseHandler)
82                     responseHandler(response);
83                 else {
84                     response.setEncoding('utf8');
85                     response.on('data', (chunk) => { responseText += chunk; });
86                 }
87                 response.on('end', () => {
88                     if (response.statusCode < 200 || response.statusCode >= 300)
89                         return reject(response.statusCode);
90
91                     if ('set-cookie' in response.headers) {
92                         for (let cookie of response.headers['set-cookie']) {
93                             const nameValue = cookie.split('=');
94                             this._cookies.set(nameValue[0], nameValue[1]);
95                         }
96                     }
97                     resolve({statusCode: response.statusCode, responseText: responseText, headers: response.headers});
98                 });
99             });
100
101             request.on('error', reject);
102
103             if (contentType)
104                 request.setHeader('Content-Type', contentType);
105
106             if (this._cookies.size)
107                 request.setHeader('Cookie', Array.from(this._cookies.keys()).map((key) => `${key}=${this._cookies.get(key)}`).join('; '));
108
109             for (let headerName in headers)
110                 request.setHeader(headerName, headers[headerName]);
111
112             if (content instanceof Function)
113                 content(request);
114             else {
115                 if (content)
116                     request.write(content);
117                 request.end();
118             }
119         });
120     }
121
122     sendHttpRequestWithFormData(path, formData)
123     {
124         return this.sendHttpRequest(path, 'POST', `multipart/form-data; boundary=${formData.getBoundary()}`, (request) => {
125             formData.pipe(request);
126         });
127     }
128
129 };
130
131 if (typeof module != 'undefined')
132     module.exports.RemoteAPI = NodeRemoteAPI;