Initial commit
[yaffs-website] / node_modules / websocket-driver / lib / websocket / http_parser.js
1 'use strict';
2
3 var NodeHTTPParser = process.binding('http_parser').HTTPParser,
4     version        = NodeHTTPParser.RESPONSE ? 6 : 4;
5
6 var HttpParser = function(type) {
7   if (type === 'request')
8     this._parser = new NodeHTTPParser(NodeHTTPParser.REQUEST || 'request');
9   else
10     this._parser = new NodeHTTPParser(NodeHTTPParser.RESPONSE || 'response');
11
12   this._type     = type;
13   this._complete = false;
14   this.headers   = {};
15
16   var current = null,
17       self    = this;
18
19   this._parser.onHeaderField = function(b, start, length) {
20     current = b.toString('utf8', start, start + length).toLowerCase();
21   };
22
23   this._parser.onHeaderValue = function(b, start, length) {
24     var value = b.toString('utf8', start, start + length);
25
26     if (self.headers.hasOwnProperty(current))
27       self.headers[current] += ', ' + value;
28     else
29       self.headers[current] = value;
30   };
31
32   this._parser.onHeadersComplete = this._parser[NodeHTTPParser.kOnHeadersComplete] =
33   function(majorVersion, minorVersion, headers, method, pathname, statusCode) {
34     var info = arguments[0];
35
36     if (typeof info === 'object') {
37       method     = info.method;
38       pathname   = info.url;
39       statusCode = info.statusCode;
40       headers    = info.headers;
41     }
42
43     self.method     = (typeof method === 'number') ? HttpParser.METHODS[method] : method;
44     self.statusCode = statusCode;
45     self.url        = pathname;
46
47     if (!headers) return;
48
49     for (var i = 0, n = headers.length, key, value; i < n; i += 2) {
50       key   = headers[i].toLowerCase();
51       value = headers[i+1];
52       if (self.headers.hasOwnProperty(key))
53         self.headers[key] += ', ' + value;
54       else
55         self.headers[key] = value;
56     }
57
58     self._complete = true;
59   };
60 };
61
62 HttpParser.METHODS = {
63   0:  'DELETE',
64   1:  'GET',
65   2:  'HEAD',
66   3:  'POST',
67   4:  'PUT',
68   5:  'CONNECT',
69   6:  'OPTIONS',
70   7:  'TRACE',
71   8:  'COPY',
72   9:  'LOCK',
73   10: 'MKCOL',
74   11: 'MOVE',
75   12: 'PROPFIND',
76   13: 'PROPPATCH',
77   14: 'SEARCH',
78   15: 'UNLOCK',
79   16: 'REPORT',
80   17: 'MKACTIVITY',
81   18: 'CHECKOUT',
82   19: 'MERGE',
83   24: 'PATCH'
84 };
85
86 HttpParser.prototype.isComplete = function() {
87   return this._complete;
88 };
89
90 HttpParser.prototype.parse = function(chunk) {
91   var offset   = (version < 6) ? 1 : 0,
92       consumed = this._parser.execute(chunk, 0, chunk.length) + offset;
93
94   if (this._complete)
95     this.body = (consumed < chunk.length)
96               ? chunk.slice(consumed)
97               : new Buffer(0);
98 };
99
100 module.exports = HttpParser;