@0xengine/xmlrpc 0.0.1-security → 1.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @0xengine/xmlrpc might be problematic. Click here for more details.

package/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: node_js
2
+ node_js:
3
+ - "0.10"
4
+ - "0.12"
5
+ - "4"
6
+ - "6"
package/HISTORY.md ADDED
@@ -0,0 +1,129 @@
1
+ ## 1.3.2 / 2016-06-16
2
+
3
+ * Drops support CI/Support for node v0.8
4
+ * Adds support for node v6.x
5
+ * Adds support for emojies
6
+ * Removes Makefile in favor of npm test
7
+ * Updates XMLBuilder to 8.2
8
+ * Updates Sax to 1.2
9
+
10
+ ## 1.3.1 / 2015-05-23
11
+
12
+ * Adds option to specify xml encoding.
13
+ * Updates XMLBuilder to 2.6.
14
+ * Adds support for Node v0.12.
15
+
16
+ ## 1.3.0 / 2015-01-09
17
+
18
+ * Reworked DateFormatter to improve ISO-8601 implementation.
19
+ * Updates XMLBuilder to 2.4.
20
+ * Updates sax to 0.6.
21
+ * Adds more detail to Client request errors to ease debugging.
22
+
23
+ ## 1.2.0 / 2014-01-12
24
+
25
+ * Adds (tested) support for Node v0.10 and v0.11.
26
+ * Drops support for Node v0.6.
27
+ * Adds a Custom Type serializer for non-standard XML-RPC types.
28
+
29
+ ## 1.1.1 / 2013-09-22
30
+
31
+ * Adds CDATA deserialization.
32
+ * Updates XMLBuilder to get rid of warnings at installation time.
33
+ * Cleans up unformatted code.
34
+ * Removes vestigial code from ancient v0.4 days.
35
+
36
+ ## 1.1.0 / 2012-11-13
37
+
38
+ * Supports optional listening handler in Server.
39
+ * Adds close function to server.
40
+ * Adds cookie support to client.
41
+ * Changes minimum Node engine to v0.6.
42
+
43
+ ## 1.0.2 / 2012-07-29
44
+
45
+ * Server responds with a 404 if it does not handle the method.
46
+ * Client returns an error if the server returns a 404.
47
+
48
+ ## 1.0.1 / 2012-04-29
49
+
50
+ * Fixes content-length header value when sending multi-byte characters.
51
+
52
+ ## 1.0.0 / 2012-03-28
53
+
54
+ * Replaces builder/parser logic with marshaller/unmarshaller.
55
+ * Uses XML-RPC's nil for JavaScript null values and vice versa.
56
+ * Client and parser are now re-entrant safe.
57
+ * Moves test strings to fixture files.
58
+ * Adds 30+ test cases.
59
+ * Special thanks to @agnat for his work on the (un)marshaller and tests.
60
+
61
+ ## 0.9.4 / 2012-03-03
62
+
63
+ * Handles chunked method calls.
64
+ * Supports ISO-8859-1 encodings.
65
+
66
+ ## 0.9.3 / 2012-01-21
67
+
68
+ * Values with no type now default to String as per XML-RPC spec.
69
+
70
+ ## 0.9.2 / 2011-12-10
71
+
72
+ * Replaces the XML parser with the Sax.js module.
73
+ * Uses Travic CI for Continuous Integration.
74
+ * Fixes accidental global variable.
75
+
76
+ ## 0.9.1 / 2011-11-29
77
+
78
+ * Returns an Error on invalid XML-RPC.
79
+ * Updates to latest version of xmlbuilder to fix install warning.
80
+
81
+ ## 0.9.0 / 2011-11-01
82
+
83
+ * Supports the Base64 datatype.
84
+ * Supports the i8 datatype, treating it as a float.
85
+ * Fixes issue where not returning for faults containing no params.
86
+ * Standardizes how to handle empty params. Last failing test now passes.
87
+ * Enforces null value for error param in callbacks.
88
+ * Updates to latest version of xmlbuilder.
89
+
90
+ ## 0.8.1 / 2011-09-01
91
+
92
+ * Supports passing the URI as a string to client or server.
93
+ * Host is now an optional parameter for client or server.
94
+ * Fixes bug when performing a method call multiple times.
95
+ * Removes node_modules directory. Use `npm install .` if cloning.
96
+
97
+ ## 0.8.0 / 2011-08-14
98
+
99
+ * Supports HTTPS server and client.
100
+ * Improves Basic Auth support.
101
+ * Errors returned are now an instance of Error, not a String.
102
+ * Fixes bug with structs and whitespace.
103
+ * Fixes bug with empty arrays responses.
104
+
105
+ ## 0.7.1 / 2011-08-02
106
+
107
+ * Handles chunked method responses.
108
+ * Fixes parsing multi-line strings values in the String parameter.
109
+ * Allows for custom headers in the HTTP request.
110
+
111
+ ## 0.7.0 / 2011-07-12
112
+
113
+ * Renames Client.call() to Client.methodCall().
114
+ * Adds better support for sending and parsing empty String parameters.
115
+ * Client handles errors on http request. Includes handling of invalid URLs.
116
+ * Updates documentation.
117
+
118
+ ## 0.6.2 / 2011-06-15
119
+
120
+ * Fixes issue with parsing non-value whitespace in method calls.
121
+
122
+ ## 0.6.1 / 2011-06-03
123
+
124
+ * Supports CDATA when generating XML calls or responses.
125
+
126
+ ## 0.6.0 / 2011-05-18
127
+
128
+ * Initial release to NPM. Considered stable enough for public use.
129
+
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2011-2016 Brandon Ace Alexander
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
package/README.md CHANGED
@@ -1,5 +1,206 @@
1
- # Security holding package
1
+ ## The What
2
2
 
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
3
+ The xmlrpc module is a pure JavaScript XML-RPC server and client for node.js.
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=%400xengine%2Fxmlrpc for more information.
5
+ Pure JavaScript means that the [XML parsing](https://github.com/isaacs/sax-js)
6
+ and [XML building](https://github.com/robrighter/node-xml) use pure JavaScript
7
+ libraries, so no extra C dependencies or build requirements. The xmlrpc module
8
+ can be used as an XML-RPC server, receiving method calls and responding with
9
+ method responses, or as an XML-RPC client, making method calls and receiving
10
+ method responses, or as both.
11
+
12
+
13
+ ## The How
14
+
15
+ ### To Install
16
+
17
+ ```bash
18
+ npm install xmlrpc
19
+ ```
20
+
21
+ ### To Use
22
+
23
+ The file client_server.js in the example directory has a nicely commented
24
+ example of using xmlrpc as an XML-RPC server and client (they even talk to each
25
+ other!).
26
+
27
+ A brief example:
28
+
29
+ ```javascript
30
+ var xmlrpc = require('xmlrpc')
31
+
32
+ // Creates an XML-RPC server to listen to XML-RPC method calls
33
+ var server = xmlrpc.createServer({ host: 'localhost', port: 9090 })
34
+ // Handle methods not found
35
+ server.on('NotFound', function(method, params) {
36
+ console.log('Method ' + method + ' does not exist');
37
+ })
38
+ // Handle method calls by listening for events with the method call name
39
+ server.on('anAction', function (err, params, callback) {
40
+ console.log('Method call params for \'anAction\': ' + params)
41
+
42
+ // ...perform an action...
43
+
44
+ // Send a method response with a value
45
+ callback(null, 'aResult')
46
+ })
47
+ console.log('XML-RPC server listening on port 9091')
48
+
49
+ // Waits briefly to give the XML-RPC server time to start up and start
50
+ // listening
51
+ setTimeout(function () {
52
+ // Creates an XML-RPC client. Passes the host information on where to
53
+ // make the XML-RPC calls.
54
+ var client = xmlrpc.createClient({ host: 'localhost', port: 9090, path: '/'})
55
+
56
+ // Sends a method call to the XML-RPC server
57
+ client.methodCall('anAction', ['aParam'], function (error, value) {
58
+ // Results of the method response
59
+ console.log('Method response for \'anAction\': ' + value)
60
+ })
61
+
62
+ }, 1000)
63
+ ```
64
+
65
+ Output from the example:
66
+
67
+ ```
68
+ XML-RPC server listening on port 9090
69
+ Method call params for 'anAction': aParam
70
+ Method response for 'anAction': aResult
71
+ ```
72
+
73
+ ### Date/Time Formatting
74
+
75
+ XML-RPC dates are formatted according to ISO 8601. There are a number of
76
+ formatting options within the boundaries of the standard. The decoder detects
77
+ those formats and parses them automatically, but for encoding dates to ISO
78
+ 8601 some options can be specified to match your specific implementation.
79
+
80
+
81
+ The formatting options can be set through
82
+ ```xmlrpc.dateFormatter.setOpts(options);```, where the ```options```
83
+ parameter is an object, with the following (optional) boolean members:
84
+
85
+ * ```colons``` - enables/disables formatting the time portion with a colon as
86
+ separator (default: ```true```)
87
+ * ```hyphens``` - enables/disables formatting the date portion with a hyphen
88
+ as separator (default: ```false```)
89
+ * ```local``` - encode as local time instead of UTC (```true``` = local,
90
+ ```false``` = utc, default: ```true```)
91
+ * ```ms``` - enables/disables output of milliseconds (default: ```false```)
92
+ * ```offset``` - enables/disables output of UTC offset in case of local time
93
+ (default: ```false```)
94
+
95
+
96
+ Default format: 20140101T11:20:00
97
+
98
+
99
+ UTC Example:
100
+ ```javascript
101
+ xmlrpc.dateFormatter.setOpts({
102
+ colons: true
103
+ , hyphens: true
104
+ , local: false
105
+ , ms: true
106
+ }) // encoding output: '2014-01-01T16:20:00.000Z'
107
+ ```
108
+
109
+ Local date + offset example:
110
+ ```javascript
111
+ xmlrpc.dateFormatter.setOpts({
112
+ colons: true
113
+ , hyphens: true
114
+ , local: true
115
+ , ms: false
116
+ , offset: true
117
+ }) // encoding output: '2014-01-01T11:20:00-05:00'
118
+ ```
119
+
120
+ ### Cookies support
121
+
122
+ It is possible to turn on cookies support for XML-RPC client by special options
123
+ flag. If turned on then all the cookies received from server will be bounced
124
+ back with subsequent calls to the server. You also may manipulate cookies
125
+ manually by the setCookie/getCookie call.
126
+
127
+ ```javascript
128
+ var client = xmlrpc.createClient({
129
+ host: 'localhost',
130
+ port: 9090,
131
+ cookies: true
132
+ });
133
+
134
+ client.setCookie('login', 'bilbo');
135
+
136
+ //This call will send provided cookie to the server
137
+ client.methodCall('someAction', [], function(error, value) {
138
+ //Here we may get cookie received from server if we know its name
139
+ console.log(client.getCookie('session'));
140
+ });
141
+
142
+ ```
143
+
144
+ ### Custom Types
145
+ If you need to parse to a specific format or need to handle custom data types
146
+ that are not supported by default, it is possible to extend the serializer
147
+ with a user-defined type for your specific needs.
148
+
149
+ A custom type can be defined as follows:
150
+ ```javascript
151
+ var xmlrpc = require('xmlrpc');
152
+ var util = require('util');
153
+
154
+ // create your custom class
155
+ var YourType = function (raw) {
156
+ xmlrpc.CustomType.call(this, raw);
157
+ };
158
+
159
+ // inherit everything
160
+ util.inherits(YourType, xmlrpc.CustomType);
161
+
162
+ // set a custom tagName (defaults to 'customType')
163
+ YourType.prototype.tagName = 'yourType';
164
+
165
+ // optionally, override the serializer
166
+ YourType.prototype.serialize = function (xml) {
167
+ var value = somefunction(this.raw);
168
+ return xml.ele(this.tagName).txt(value);
169
+ }
170
+ ```
171
+
172
+ and then make your method calls, wrapping your variables inside your new type
173
+ definition:
174
+
175
+ ```javascript
176
+ var client = xmlrpc.createClient('YOUR_ENDPOINT');
177
+ client.methodCall('YOUR_METHOD', [new YourType(yourVariable)], yourCallback);
178
+ ```
179
+
180
+ ### To Debug (client-side)
181
+
182
+ Error callbacks on the client are enriched with request and response
183
+ information and the returned body as long as a http connection was made,
184
+ to aide with request debugging. Example:
185
+
186
+ ```javascript
187
+ var client = xmlrpc.createClient({ host: 'example.com', port: 80 });
188
+ client.methodCall('FAULTY_METHOD', [], function (error, value) {
189
+ if (error) {
190
+ console.log('error:', error);
191
+ console.log('req headers:', error.req && error.req._header);
192
+ console.log('res code:', error.res && error.res.statusCode);
193
+ console.log('res body:', error.body);
194
+ } else {
195
+ console.log('value:', value);
196
+ }
197
+ });
198
+
199
+ // error: [Error: Unknown XML-RPC tag 'TITLE']
200
+ // req headers: POST / HTTP/1.1
201
+ // User-Agent: NodeJS XML-RPC Client
202
+ // ...
203
+ // res code: 200
204
+ // res body: <!doctype html>
205
+ // ...
206
+ ```
package/lib/client.js ADDED
@@ -0,0 +1,177 @@
1
+ var http = require('http')
2
+ , https = require('https')
3
+ , url = require('url')
4
+ , Serializer = require('./serializer')
5
+ , Deserializer = require('./deserializer')
6
+ , Cookies = require('./cookies')
7
+
8
+ /**
9
+ * Creates a Client object for making XML-RPC method calls.
10
+ *
11
+ * @constructor
12
+ * @param {Object|String} options - Server options to make the HTTP request to.
13
+ * Either a URI string
14
+ * (e.g. 'http://localhost:9090') or an object
15
+ * with fields:
16
+ * - {String} host - (optional)
17
+ * - {Number} port
18
+ * - {String} url - (optional) - may be used instead of host/port pair
19
+ * - {Boolean} cookies - (optional) - if true then cookies returned by server will be stored and sent back on the next calls.
20
+ * Also it will be possible to access/manipulate cookies via #setCookie/#getCookie methods
21
+ * @param {Boolean} isSecure - True if using https for making calls,
22
+ * otherwise false.
23
+ * @return {Client}
24
+ */
25
+ function Client(options, isSecure) {
26
+
27
+ // Invokes with new if called without
28
+ if (false === (this instanceof Client)) {
29
+ return new Client(options, isSecure)
30
+ }
31
+
32
+ // If a string URI is passed in, converts to URI fields
33
+ if (typeof options === 'string') {
34
+ options = url.parse(options)
35
+ options.host = options.hostname
36
+ options.path = options.pathname
37
+ }
38
+
39
+ if (typeof options.url !== 'undefined') {
40
+ var parsedUrl = url.parse(options.url);
41
+ options.host = parsedUrl.hostname;
42
+ options.path = parsedUrl.pathname;
43
+ options.port = parsedUrl.port;
44
+ }
45
+
46
+ // Set the HTTP request headers
47
+ var headers = {
48
+ 'User-Agent' : 'NodeJS XML-RPC Client'
49
+ , 'Content-Type' : 'text/xml'
50
+ , 'Accept' : 'text/xml'
51
+ , 'Accept-Charset' : 'UTF8'
52
+ , 'Connection' : 'Keep-Alive'
53
+ }
54
+ options.headers = options.headers || {}
55
+
56
+ if (options.headers.Authorization == null &&
57
+ options.basic_auth != null &&
58
+ options.basic_auth.user != null &&
59
+ options.basic_auth.pass != null)
60
+ {
61
+ var auth = options.basic_auth.user + ':' + options.basic_auth.pass
62
+ options.headers['Authorization'] = 'Basic ' + new Buffer(auth).toString('base64')
63
+ }
64
+
65
+ for (var attribute in headers) {
66
+ if (options.headers[attribute] === undefined) {
67
+ options.headers[attribute] = headers[attribute]
68
+ }
69
+ }
70
+
71
+ options.method = 'POST'
72
+ this.options = options
73
+
74
+ this.isSecure = isSecure
75
+ this.headersProcessors = {
76
+ processors: [],
77
+ composeRequest: function(headers) {
78
+ this.processors.forEach(function(p) {p.composeRequest(headers);})
79
+ },
80
+ parseResponse: function(headers) {
81
+ this.processors.forEach(function(p) {p.parseResponse(headers);})
82
+ }
83
+ };
84
+ if (options.cookies) {
85
+ this.cookies = new Cookies();
86
+ this.headersProcessors.processors.unshift(this.cookies);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Makes an XML-RPC call to the server specified by the constructor's options.
92
+ *
93
+ * @param {String} method - The method name.
94
+ * @param {Array} params - Params to send in the call.
95
+ * @param {Function} callback - function(error, value) { ... }
96
+ * - {Object|null} error - Any errors when making the call, otherwise null.
97
+ * - {mixed} value - The value returned in the method response.
98
+ */
99
+ Client.prototype.methodCall = function methodCall(method, params, callback) {
100
+ var options = this.options
101
+ var xml = Serializer.serializeMethodCall(method, params, options.encoding)
102
+ var transport = this.isSecure ? https : http
103
+
104
+ options.headers['Content-Length'] = Buffer.byteLength(xml, 'utf8')
105
+ this.headersProcessors.composeRequest(options.headers)
106
+ var request = transport.request(options, function(response) {
107
+
108
+ var body = []
109
+ response.on('data', function (chunk) { body.push(chunk) })
110
+
111
+ function __enrichError (err) {
112
+ Object.defineProperty(err, 'req', { value: request })
113
+ Object.defineProperty(err, 'res', { value: response })
114
+ Object.defineProperty(err, 'body', { value: body.join('') })
115
+ return err
116
+ }
117
+
118
+ if (response.statusCode == 404) {
119
+ callback(__enrichError(new Error('Not Found')))
120
+ }
121
+ else {
122
+ this.headersProcessors.parseResponse(response.headers)
123
+
124
+ var deserializer = new Deserializer(options.responseEncoding)
125
+
126
+ deserializer.deserializeMethodResponse(response, function(err, result) {
127
+ if (err) {
128
+ err = __enrichError(err)
129
+ }
130
+ callback(err, result)
131
+ })
132
+ }
133
+ }.bind(this))
134
+
135
+ request.on('error', callback)
136
+ request.write(xml, 'utf8')
137
+ request.end()
138
+ }
139
+
140
+ /**
141
+ * Gets the cookie value by its name. The latest value received from servr with 'Set-Cookie' header is returned
142
+ * Note that method throws an error if cookies were not turned on during client creation (see comments for constructor)
143
+ *
144
+ * @param {String} name name of the cookie to be obtained or changed
145
+ * @return {*} cookie's value
146
+ */
147
+ Client.prototype.getCookie = function getCookie(name) {
148
+ if (!this.cookies) {
149
+ throw 'Cookies support is not turned on for this client instance';
150
+ }
151
+ return this.cookies.get(name);
152
+ }
153
+
154
+ /**
155
+ * Sets the cookie value by its name. The cookie will be sent to the server during the next xml-rpc call.
156
+ * The method returns client itself, so it is possible to chain calls like the following:
157
+ *
158
+ * <code>
159
+ * client.cookie('login', 'alex').cookie('password', '123');
160
+ * </code>
161
+ *
162
+ * Note that method throws an error if cookies were not turned on during client creation (see comments for constructor)
163
+ *
164
+ * @param {String} name name of the cookie to be changed
165
+ * @param {String} value value to be set.
166
+ * @return {*} client object itself
167
+ */
168
+ Client.prototype.setCookie = function setCookie(name, value) {
169
+ if (!this.cookies) {
170
+ throw 'Cookies support is not turned on for this client instance';
171
+ }
172
+ this.cookies.set(name, value);
173
+ return this;
174
+ }
175
+
176
+ module.exports = Client
177
+
package/lib/cookies.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Creates object for cookies manipulation on client side.
3
+ * Allows to parse server's response in order to get cookies and compose http request to transfer cookies to the server
4
+ * @constructor
5
+ */
6
+ function Cookies() {
7
+ this.cookies = {}
8
+ }
9
+
10
+ Cookies.prototype = {
11
+ /**
12
+ * Obtains value of the cookie with specified name.
13
+ * This call checks expiration dates and does not return expired cookies.
14
+ * @param {String} name cookie name
15
+ * @return {String} cookie value or null
16
+ */
17
+ get: function(name) {
18
+ var cookie = this.cookies[name]
19
+ if (cookie && this.checkNotExpired(name)) {
20
+ return this.cookies[name].value
21
+ }
22
+ return null
23
+ },
24
+
25
+ /**
26
+ * Sets cookie's value and optional options
27
+ * @param {String} name cookie's name
28
+ * @param {String} value value
29
+ * @param {Object} options with the following fields:
30
+ * - {Boolean} secure - is cookie secure or not (does not mean anything for now)
31
+ * - {Date} expires - cookie's expiration date. If specified then cookie will disappear after that date
32
+ */
33
+ set: function(name, value, options) {
34
+ var cookie = typeof options == 'object'
35
+ ? {value: value, expires: options.expires, secure: options.secure || false, new: options.new || false}
36
+ : {value: value}
37
+ if (this.checkNotExpired(name, cookie)) {
38
+ this.cookies[name] = cookie
39
+ }
40
+ },
41
+
42
+ // For testing purposes
43
+ getExpirationDate: function(name) {
44
+ return this.cookies[name] ? this.cookies[name].expires : null
45
+ },
46
+
47
+ // Internal function
48
+ checkNotExpired: function(name, cookie) {
49
+ if (typeof cookie === 'undefined') {
50
+ cookie = this.cookies[name]
51
+ }
52
+ var now = new Date()
53
+ if (cookie && cookie.expires && now > cookie.expires) {
54
+ delete this.cookies[name]
55
+ return false
56
+ }
57
+ return true
58
+ },
59
+
60
+
61
+ /**
62
+ * Parses headers from server's response for 'set-cookie' header and store cookie's values.
63
+ * Also parses expiration date
64
+ * @param headers
65
+ */
66
+ parseResponse: function(headers) {
67
+ var cookies = headers['set-cookie']
68
+ if (cookies) {
69
+ cookies.forEach(function(c) {
70
+ var cookiesParams = c.split(';')
71
+ var cookiePair = cookiesParams.shift().split('=')
72
+ var options = {}
73
+ cookiesParams.forEach(function(param) {
74
+ param = param.trim()
75
+ if (param.toLowerCase().indexOf('expires') == 0) {
76
+ var date = param.split('=')[1].trim()
77
+ options.expires = new Date(date)
78
+ }
79
+ })
80
+ this.set(cookiePair[0].trim(), cookiePair[1].trim(), options)
81
+ }.bind(this))
82
+ }
83
+ },
84
+
85
+ /**
86
+ * Adds cookies to the provided headers as array. Does nothing if there are no cookies stored.
87
+ * This call checks expiration dates and does not add expired cookies.
88
+ * @param headers
89
+ */
90
+ composeRequest: function(headers) {
91
+ if (Object.keys(this.cookies).length == 0) {
92
+ return
93
+ }
94
+ headers['Cookie'] = this.toString()
95
+ },
96
+
97
+
98
+ /**
99
+ *
100
+ * @return {String} cookies as 'name=value' pairs joined by semicolon
101
+ */
102
+ toString: function() {
103
+ return Object.keys(this.cookies)
104
+ .filter(this.checkNotExpired.bind(this))
105
+ .map(function(name) {
106
+ return name + '=' + this.cookies[name].value
107
+ }.bind(this)).join(';')
108
+ }
109
+ }
110
+
111
+ module.exports = Cookies
@@ -0,0 +1,10 @@
1
+ var CustomType = module.exports = function(raw) {
2
+ this.raw = raw
3
+ }
4
+
5
+ CustomType.prototype.serialize = function(xml) {
6
+ return xml.ele(this.tagName).txt(this.raw)
7
+ }
8
+
9
+ CustomType.prototype.tagName = 'customType'
10
+