Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reading an attachment from soap rsponse #35

Open
chrisgh1 opened this issue Jun 5, 2017 · 6 comments
Open

reading an attachment from soap rsponse #35

chrisgh1 opened this issue Jun 5, 2017 · 6 comments

Comments

@chrisgh1
Copy link
Contributor

chrisgh1 commented Jun 5, 2017

I'm having some trouble reading an attachment from the soap response using.
var file = ws.getAttachment(ctx, "response", "//*[local-name(.)='File1']"); //fs.writeFileSync("result.pdf", file);

after much hacking around I was able to get the file from the soap response by adding
fs.writeFileSync("result.pdf", parts[1].data);

to mtom.js after this block of code
` //use slice() since in http multipart response the first chars are #13#10 which the parser does not expect
var parts = reader.parse_multipart(ctx.response.slice(2), boundary)

if (parts.length==0) {
console.log("warning: no mime parts in response")
callback(ctx)
return
}`

two things that I'm not sure of are:

  1. in ws.getAttachment(ctx, "response", "//[local-name(.)='File1']"); what this is doing //[local-name(.)='File1'].
  2. what this block of code in mtom.js is trying to do
    for (var i in parts) { var p = parts[i] , id = utils.extractContentId(p.headers["content-id"] ) , xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*" , elem = select(doc, xpath)[0] console.log(elem); if (!elem) continue elem.removeChild(elem.firstChild) utils.setElementValue(doc, elem, p.data.toString("base64")) }

fyi the console.log(elem) is returning undefined for each part[0] and part[1] when I run it.

the error I'm getting when I try to run is:
c:\node\test\node_modules\ws.js\lib\ws.js:69
return new Buffer(elem.firstChild.data, "base64")
^

TypeError: Cannot read property 'firstChild' of undefined
at Object.getAttachment (c:\node\test\node_modules\ws.js\lib\ws.js:69:25)

@chrisgh1
Copy link
Contributor Author

chrisgh1 commented Jun 5, 2017

ok a little more information. so in ws.js in function getAttachment() I console logged the var prop.

function getAttachment(ctx, property, xpath) { var prop = eval("ctx." + property); console.log(prop); var doc = new Dom().parseFromString(prop) , elem = select(doc, xpath)[0] return new Buffer(elem.firstChild.data, "base64") }

I'm getting xml from the soap:Envelope. I would thing this is supposed to be the data of the attachment or what was found in parts[1] above.

@chrisgh1
Copy link
Contributor Author

chrisgh1 commented Jun 5, 2017

Ok it seems like elem is not being set to anything from select(doc, xpath)[0] in this code in mtom.js
`var parts = reader.parse_multipart(ctx.response.slice(2), boundary)

if (parts.length==0) {
console.log("warning: no mime parts in response")
callback(ctx)
return
}

var doc = new Dom().parseFromString(parts[0].data.toString())

for (var i in parts) {
var p = parts[i]
, id = utils.extractContentId(p.headers["content-id"] )
, xpath = "//[@href='cid:" + encodeURIComponent(id) + "']//parent::"
, elem = select(doc, xpath)[0]
if (!elem) continue
elem.removeChild(elem.firstChild)
utils.setElementValue(doc, elem, p.data.toString("base64"))
}`

@chrisgh1
Copy link
Contributor Author

So I added this block of code
if(parts.length > 1){ ctx.file = parts[1].data; }

after

` for (var i in parts) {
var p = parts[i]
, id = utils.extractContentId(p.headers["content-id"] )
, xpath = "//[@href='cid:" + encodeURIComponent(id) + "']//parent::"
, elem = select(doc, xpath)[0]

if (!elem) continue
elem.removeChild(elem.firstChild)
utils.setElementValue(doc, elem, p.data.toString("base64"))

}`

in mtom.js

This seems to work for a single file. I would really like to get the getAttachment working but I don't really understand the third argument in the function. in the example it's set to "//*[local-name(.)='File1']"

@chrisgh1
Copy link
Contributor Author

chrisgh1 commented Oct 24, 2018

Ok so I think I've got this figured out. My clue was in the following issue
#11 look at yaronn comment on Mar 26, 2015

I had to also use the work around
encodeURIComponent = function(s) {return s}

Then I was able to use the following
ws.getAttachment(ctx, "response", "//*[local-name(.)='content']")

which the local-name(.)='content' part was because my soap response from the server was like:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:getContentResponse xmlns:ns2="http://url-redacted.com/"> <return> <content_data> <content> <xop:Include href="cid:[email protected]" xmlns:xop="http://www.w3.org/2004/08/xop/include"/> </content> </content_data> </return> </ns2:getContentResponse> </soap:Body> </soap:Envelope>

@jbaris
Copy link

jbaris commented May 12, 2020

@chrisgh1 same problem here. When the document name is an url, then the encodeURIComponent breaks the xpath find.
As you said, to make it run, you need to modify mtom.js by replacing:

xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*"

with:

xpath = "//*[@href='cid:" + id + "']//parent::*"

Should we create a PR with this? I mean, do anybody have the same issue?

@chrisgh1
Copy link
Contributor Author

@jbaris I'm not really fluent in xpath so I wasn't sure if this was an appropriate fix. However now that you have been able to verify that it's working for more than just me maybe it's time for a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants