-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxconnect-odata-proxy.js
145 lines (112 loc) · 3.92 KB
/
xconnect-odata-proxy.js
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
var xConnectHost = 'xp0.xconnect';
var proxyHost = 'localhost';
var proxyPort = '5060';
var keyFile = 'C:\\Program Files\\OpenSSL\\bin\\xconnect.key';
var clientCertFile = 'C:\\Program Files\\OpenSSL\\bin\\xconnectcert.pem';
var siteCertFile = 'C:\\Program Files\\OpenSSL\\bin\\bundle\\xp0CertSiteCopy.pem';
var xConnectUrl = 'https://' + xConnectHost;
var proxyUrl = 'http://' + proxyHost + ':' + proxyPort;
var http = require('http'),
connect = require('connect'),
httpProxy = require('http-proxy');
var replaceStream = require('string-replace-stream');
var app = connect();
var fs = require('fs');
var proxy = httpProxy.createProxyServer({});
app.use(function (req, res) {
proxy.on('proxyRes', function (proxyRes, request, response) {
if (proxyRes.headers) {
var _end = response.end,
chunks,
_writeHead = response.writeHead;
response.writeHead = function () {
if (proxyRes.headers && proxyRes.headers['content-length'] && proxyRes.headers['content-type'] != 'application/xml') {
response.setHeader(
'content-length',
// Amend content length with URL changes
parseInt(proxyRes.headers['content-length'], 10) + calculateResponseLength()
);
}
response.removeHeader('connection');
_writeHead.apply(this, arguments);
};
response.write = function (data) {
if (chunks) {
chunks += data;
} else {
chunks = data;
}
};
response.end = function () {
if (chunks && chunks.toString) {
var replacedText = modifyJson(chunks.toString());
_end.apply(response, [replacedText]);
} else {
_end.apply(response, arguments);
}
};
}
});
function calculateResponseLength() {
// xConnect URL is bigger so return diff plus 1 for slash on the end
if (xConnectUrl.length > proxyUrl.length) {
return (xConnectUrl.length - proxyUrl.length) +1;
} // proxyUrlURL is bigger so return diff plus 1 for slash on the end
else if(proxyUrl.length > xConnectUrl.length)
{
return (proxyUrl.length - xConnectUrl.length) +1;
}
//just return slash on the end
return 1;
}
function modifyJson(str) {
if (str.indexOf(xConnectUrl) > -1) {
//make Power BI use the correct URL
str = str.replace(xConnectUrl, proxyUrl);
// fix for metadata '/'
str = str.replace('$metadata', '$metadata/');
}
return str;
}
proxy.web(req, res, options, function (err) {
var mystring = require('util').inspect(err);
console.log(mystring);
if (!res.headersSent) {
res.statusCode = 502;
res.end('bad gateway');
}
});
});
function getCABundle(Bundle) {
var ca = [];
chain = fs.readFileSync(Bundle, 'utf8');
chain = chain.split("\n");
cert = [];
for (line in chain) {
if (line.length > 0) {
cert.push(chain[line]);
if (chain[line].match(/-END CERTIFICATE-/)) {
ca.push(cert.join("\n"));
cert = [];
}
}
}
return ca;
}
var proxyServer = http.createServer(app)
{
var options = {
target: {
host: xConnectHost,
port: 443,
protocol: 'https:',
key: fs.readFileSync(keyFile, 'utf8'),
cert: fs.readFileSync(clientCertFile, 'utf8'),
requestCert: true,
ca: getCABundle(siteCertFile)
},
changeOrigin: true
};
};
console.log("listening on port " + proxyPort)
proxyServer.listen(proxyPort);