source: trip-planner-front/node_modules/http-deceiver/lib/deceiver.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 6.6 KB
Line 
1var assert = require('assert');
2var util = require('util');
3
4var Buffer = require('buffer').Buffer;
5
6// Node.js version
7var mode = /^v0\.8\./.test(process.version) ? 'rusty' :
8 /^v0\.(9|10)\./.test(process.version) ? 'old' :
9 /^v0\.12\./.test(process.version) ? 'normal' :
10 'modern';
11
12var HTTPParser;
13
14var methods;
15var reverseMethods;
16
17var kOnHeaders;
18var kOnHeadersComplete;
19var kOnMessageComplete;
20var kOnBody;
21if (mode === 'normal' || mode === 'modern') {
22 HTTPParser = process.binding('http_parser').HTTPParser;
23 methods = HTTPParser.methods;
24
25 // v6
26 if (!methods)
27 methods = process.binding('http_parser').methods;
28
29 reverseMethods = {};
30
31 methods.forEach(function(method, index) {
32 reverseMethods[method] = index;
33 });
34
35 kOnHeaders = HTTPParser.kOnHeaders | 0;
36 kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
37 kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
38 kOnBody = HTTPParser.kOnBody | 0;
39} else {
40 kOnHeaders = 'onHeaders';
41 kOnHeadersComplete = 'onHeadersComplete';
42 kOnMessageComplete = 'onMessageComplete';
43 kOnBody = 'onBody';
44}
45
46function Deceiver(socket, options) {
47 this.socket = socket;
48 this.options = options || {};
49 this.isClient = this.options.isClient;
50}
51module.exports = Deceiver;
52
53Deceiver.create = function create(stream, options) {
54 return new Deceiver(stream, options);
55};
56
57Deceiver.prototype._toHeaderList = function _toHeaderList(object) {
58 var out = [];
59 var keys = Object.keys(object);
60
61 for (var i = 0; i < keys.length; i++)
62 out.push(keys[i], object[keys[i]]);
63
64 return out;
65};
66
67Deceiver.prototype._isUpgrade = function _isUpgrade(request) {
68 return request.method === 'CONNECT' ||
69 request.headers.upgrade ||
70 request.headers.connection &&
71 /(^|\W)upgrade(\W|$)/i.test(request.headers.connection);
72};
73
74// TODO(indutny): support CONNECT
75if (mode === 'modern') {
76 /*
77 function parserOnHeadersComplete(versionMajor, versionMinor, headers, method,
78 url, statusCode, statusMessage, upgrade,
79 shouldKeepAlive) {
80 */
81 Deceiver.prototype.emitRequest = function emitRequest(request) {
82 var parser = this.socket.parser;
83 assert(parser, 'No parser present');
84
85 parser.execute = null;
86
87 var self = this;
88 var method = reverseMethods[request.method];
89 parser.execute = function execute() {
90 self._skipExecute(this);
91 this[kOnHeadersComplete](1,
92 1,
93 self._toHeaderList(request.headers),
94 method,
95 request.path,
96 0,
97 '',
98 self._isUpgrade(request),
99 true);
100 return 0;
101 };
102
103 this._emitEmpty();
104 };
105
106 Deceiver.prototype.emitResponse = function emitResponse(response) {
107 var parser = this.socket.parser;
108 assert(parser, 'No parser present');
109
110 parser.execute = null;
111
112 var self = this;
113 parser.execute = function execute() {
114 self._skipExecute(this);
115 this[kOnHeadersComplete](1,
116 1,
117 self._toHeaderList(response.headers),
118 response.path,
119 response.code,
120 response.status,
121 response.reason || '',
122 self._isUpgrade(response),
123 true);
124 return 0;
125 };
126
127 this._emitEmpty();
128 };
129} else {
130 /*
131 `function parserOnHeadersComplete(info) {`
132
133 info = { .versionMajor, .versionMinor, .url, .headers, .method,
134 .statusCode, .statusMessage, .upgrade, .shouldKeepAlive }
135 */
136 Deceiver.prototype.emitRequest = function emitRequest(request) {
137 var parser = this.socket.parser;
138 assert(parser, 'No parser present');
139
140 var method = request.method;
141 if (reverseMethods)
142 method = reverseMethods[method];
143
144 var info = {
145 versionMajor: 1,
146 versionMinor: 1,
147 url: request.path,
148 headers: this._toHeaderList(request.headers),
149 method: method,
150 statusCode: 0,
151 statusMessage: '',
152 upgrade: this._isUpgrade(request),
153 shouldKeepAlive: true
154 };
155
156 var self = this;
157 parser.execute = function execute() {
158 self._skipExecute(this);
159 this[kOnHeadersComplete](info);
160 return 0;
161 };
162
163 this._emitEmpty();
164 };
165
166 Deceiver.prototype.emitResponse = function emitResponse(response) {
167 var parser = this.socket.parser;
168 assert(parser, 'No parser present');
169
170 var info = {
171 versionMajor: 1,
172 versionMinor: 1,
173 url: response.path,
174 headers: this._toHeaderList(response.headers),
175 method: false,
176 statusCode: response.status,
177 statusMessage: response.reason || '',
178 upgrade: this._isUpgrade(response),
179 shouldKeepAlive: true
180 };
181
182 var self = this;
183 parser.execute = function execute() {
184 self._skipExecute(this);
185 this[kOnHeadersComplete](info);
186 return 0;
187 };
188
189 this._emitEmpty();
190 };
191}
192
193Deceiver.prototype._skipExecute = function _skipExecute(parser) {
194 var self = this;
195 var oldExecute = parser.constructor.prototype.execute;
196 var oldFinish = parser.constructor.prototype.finish;
197
198 parser.execute = null;
199 parser.finish = null;
200
201 parser.execute = function execute(buffer, start, len) {
202 // Parser reuse
203 if (this.socket !== self.socket) {
204 this.execute = oldExecute;
205 this.finish = oldFinish;
206 return this.execute(buffer, start, len);
207 }
208
209 if (start !== undefined)
210 buffer = buffer.slice(start, start + len);
211 self.emitBody(buffer);
212 return len;
213 };
214
215 parser.finish = function finish() {
216 // Parser reuse
217 if (this.socket !== self.socket) {
218 this.execute = oldExecute;
219 this.finish = oldFinish;
220 return this.finish();
221 }
222
223 this.execute = oldExecute;
224 this.finish = oldFinish;
225 self.emitMessageComplete();
226 };
227};
228
229Deceiver.prototype.emitBody = function emitBody(buffer) {
230 var parser = this.socket.parser;
231 assert(parser, 'No parser present');
232
233 parser[kOnBody](buffer, 0, buffer.length);
234};
235
236Deceiver.prototype._emitEmpty = function _emitEmpty() {
237 // Emit data to force out handling of UPGRADE
238 var empty = new Buffer(0);
239 if (this.socket.ondata)
240 this.socket.ondata(empty, 0, 0);
241 else
242 this.socket.emit('data', empty);
243};
244
245Deceiver.prototype.emitMessageComplete = function emitMessageComplete() {
246 var parser = this.socket.parser;
247 assert(parser, 'No parser present');
248
249 parser[kOnMessageComplete]();
250};
Note: See TracBrowser for help on using the repository browser.