hubotとnode-xmlrpcを使って、
IRC上からconfluenceにページを作成するものを作ってたのだが、
どうも特定のページを元にページを作成しようとするとエラーがでて失敗してしまう。
調べてみると、どうも生成しようとするページ内にCDATAが含まれていると失敗するっぽい。
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
| xmlrpc = require 'xmlrpc'
async = require 'async'
clientOption =
host: "host"
path: "/confluence/rpc/xmlrpc"
port: 443
space = '~userspace'
userName = 'username'
password = 'password'
client = xmlrpc.createSecureClient clientOption
title = "てすと"
content = '<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[<html>hogehoge</html>]]></ac:plain-text-body></ac:macro>'
async.waterfall [
(callback) ->
client.methodCall "confluence2.login", [userName, password], callback
(token, callback) ->
page =
space: space
parentId: '0'
title: title
content: content
client.methodCall "confluence2.storePage", [token, page], callback
], (err, page) ->
console.log page
|
こんな感じのコードを書いて実行すると、Invalid CDATA text
というエラーが出てページが作成できない。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| $ coffee confluence.coffee
/Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:150
throw new Error("Invalid CDATA text: " + value);
^
Error: Invalid CDATA text: <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[<html>hogehoge</html>]]></ac:plain-text-body></ac:macro>
at XMLFragment.cdata (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:150:15)
at XMLFragment.d (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:355:19)
at appendString (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:172:23)
at serializeValue (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:92:11)
at /Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:25:5
at Array.forEach (native)
at Object.exports.serializeMethodCall (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:24:10)
at Client.methodCall (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/client.js:100:30)
at /Users/saiten/local/tmp/confl/test/confluence.coffee:28:5, <js>:38:21
at fn (/Users/saiten/local/tmp/confl/node_modules/async/lib/async.js:579:34)
at Object._onImmediate (/Users/saiten/local/tmp/confl/node_modules/async/lib/async.js:495:34)
at processImmediate [as _immediateCallback] (timers.js:330:15)
|
どうもCDATAが含まれる文字列なのにCDATAで囲もうとして失敗してるようだったので、
node-xmlrpcのserializer.jsの以下の部分を直したらうまく行った。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| @@ -163,14 +163,10 @@ function appendBoolean(value, xml) {
xml.ele('boolean').txt(value ? 1 : 0)
}
-var illegalChars = /^(?![^<&]*]]>[^<&]*)[^<&]*$/
function appendString(value, xml) {
if (value.length === 0) {
xml.ele('string')
}
- else if (!illegalChars.test(value)) {
- xml.ele('string').d(value)
- }
else {
xml.ele('string').txt(value)
}
|
動くけどこの修正で良いのか微妙なところ。