1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 var EventEmitter = require('events');
17 var util = require('util');
18 var HTTPParser = process.binding(process.binding.httpparser).HTTPParser;
19 var IncomingMessage = require('http_incoming').IncomingMessage;
20 var OutgoingMessage = require('http_outgoing').OutgoingMessage;
21 var Buffer = require('buffer');
25 var createHTTPParser = function() {
26 // REQUEST is the default type.
27 // For RESPONSE, use HTTPParser.reinitialize(HTTPParser.RESPONSE)
28 var parser = new HTTPParser(HTTPParser.REQUEST);
29 // cb during http parsing from C side(http_parser)
30 parser.OnHeaders = parserOnHeaders;
31 parser.OnHeadersComplete = parserOnHeadersComplete;
32 parser.OnBody = parserOnBody;
33 parser.OnMessageComplete = parserOnMessageComplete;
37 exports.createHTTPParser = createHTTPParser;
40 // This is called when parsing of incoming http msg done
41 function parserOnMessageComplete() {
44 var stream = parser.incoming;
47 stream.complete = true;
48 // no more data from incoming, stream will emit 'end' event
52 stream.socket.resume();
56 // This is called when header part in http msg is parsed.
57 function parserOnHeadersComplete(info) {
60 var headers = info.headers;
69 headers = parser._headers;
70 // FIXME: This should be impl. with Array
75 parser.incoming = new IncomingMessage(parser.socket);
76 parser.incoming.url = url;
78 // add header fields of headers to incoming.headers
79 parser.incoming.addHeaders(headers);
81 if (util.isNumber(info.method)) {
83 parser.incoming.method = HTTPParser.methods[info.method];
86 parser.incoming.statusCode = info.status;
87 parser.incoming.statusMessage = info.status_msg;
90 // For client side, if response to 'HEAD' request, we will skip parsing body
91 var skipBody = parser.onIncoming(parser.incoming, info.shouldkeepalive);
97 // parserOnBody is called when HTTPParser parses http msg(incoming) and
98 // get body part(buf from start at length of len)
99 function parserOnBody(buf, start, len) {
102 var stream = parser.incoming;
108 // Push body part into incoming stream, which will emit 'data' event
109 var body = buf.slice(start, start+len);
114 function AddHeader(dest, src) {
119 for (var i=0;i<src.length;i++) {
120 dest[dest.length+i] = src[i];
122 dest.length = dest.length + src.length;
126 // This is called when http header is fragmented and
127 // HTTPParser sends it to JS in separate pieces.
128 function parserOnHeaders(headers, url) {
129 // FIXME: This should be impl. with Array.concat
130 AddHeader(this._headers, headers);