Node.js-无法将xml文件附加到soap请求

时间:2019-09-30 10:48:07

标签: javascript node.js xml soap mime

在这种结构中,我需要发出带有xml附件的肥皂请求:

原始格式的HTTP请求:

POST url1 HTTP/1.1
Content-Encoding: gzip
Accept-Encoding: gzip,deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="----=_Part_3_19706996.1467294979823"
SOAPAction: "url2/submitDATTRA"
MIME-Version: 1.0
Transfer-Encoding: chunked
Host: host
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)


------=_Part_3_19706996.1467294979823
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart@soapui.org>

<soapenv:Envelope xmlns:abc="url2" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-44C3662D584567FE6A14672949268541">
                <wsse:Username>your.customer1234#1234567890</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXXXXX</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">+WifMh5kFw/1fHgMahFu7A==</wsse:Nonce>
                <wsu:Created>2016-06-30T13:55:26.852Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <abc:submitDATTRA>
            <inDATTRA>
            <abc:dateiname>testfile_001.xml</abc:dateiname>
            </inDATTRA>
            <!--Optional:-->
            <kundenreferenz>ClientRef_001</kundenreferenz>
            <datei><inc:Include href="cid:139580394822" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></datei>
        </abc:submitDATINS>
    </soapenv:Body>
</soapenv:Envelope>
------=_Part_3_19706996.1467294979823
Content-Type: application/octet-binary; name=testfile_001.xml
Content-Transfer-Encoding: binary
Content-ID: <139580394822>
Content-Disposition: attachment; name="testfile_001.xml"; filename="testfile_001.xml"

... Inhalt der XML-Datei ...
------=_Part_3_19706996.1467294979823—

到目前为止,我在这里创建了xml文件:

 var xml = builder.buildObject({...});

...然后我这样写并保存它:

  var path = './public/files/'
  //var filename = uuid.v4() + '.xml';
  var filename = 'testfile_001' + '.xml';

  fs.writeFile(path+filename, xml, function(err) {
    if(err) {
      console.log(err);
      return;
     }
     console.log("File created!");
     console.log(filename);
  });

为制造肥皂,我这样做:

  var soapUsername = 'abc';
  var soapUserID = 'def';
  var soapPassword = 'xyz';

  const getWSSE = ({ username, password, nonce, created }) => {

    const Created = new Date().toISOString();
    const rawNonce = nonce || Created + '-' + Math.random().toString();
    const NonceB64 = Buffer.from(rawNonce).toString('base64');

    let passwordSha1 = crypto.createHash('sha1').update(password).digest('hex');

    let textBuff = Buffer.concat([
      Buffer.from(NonceB64, 'utf8'),
      Buffer.from(Created, 'utf8'),
      Buffer.from(passwordSha1, 'hex'),
    ]);

    let pwHash = crypto.createHash('sha1').update(textBuff).digest('binary');

    const PasswordDigest = Buffer.from(pwHash, 'binary').toString('base64');

    passwordSha1 = null;
    textBuff = null;
    pwHash = null;

    return {
      Username: username,
      Password: PasswordDigest,
      RawNonce: rawNonce,
      NonceB64: NonceB64,
      CreatedAt: Created
    };
  };

  var token = getWSSE({ username: soapUsername, password: soapPassword });
  console.log(token)

  var soapXML = {
    'soapenv:Envelope': {
      '$': {
        'xmlns:abc': 'url',
        'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/'
      },
      'soapenv:Header': {
        'wsse:Security': {
          '$': {
            'soapenv:mustUnderstand': '1',
            'xmlns:wsse': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd',
            'xmlns:wsu': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
          },
          'wsse:UsernameToken': {
            '$': {
              'wsu:Id': 'UsernameToken-'+token.NonceB64
            },
            'wsse:Username': soapUsername+'#'+soapUserID,
            'wsse:Password': {
              '$': {
                'Type': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'
              },
              '_': soapPassword
            },
            'wsse:Nonce': {
              '$': {
                'EncodingType': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary'
              },
              '_': token.NonceB64
            },
            'wsu:Created': token.CreatedAt
          }
        }
      },
      'soapenv:Body': {
        'abc:submitDATTRA': {
          'inDATTRA': {
            'abc:dateiname': filename
          }/*,
          'kundenreferenz': 'ClientRef_001',
          'datei': '<inc:Include href="cid:139580394822" xmlns:inc="http://www.w3.org/2004/08/xop/include"/>'*/
        }
      }
    }
  };

  var builder2 = new xml2js.Builder({ });
  var xmlMulti = builder2.buildObject(soapXML);

我尝试像这样附加文件:

  const url = 'url2?wsdl'

  var multipartArr = [];

  // Add soap request
  multipartArr.push({
      body: xmlMulti
  });

  var boundary = "xxxxxxxxxx";

  const directoryPath = modulePath.join(__dirname, '../public/files');
  fs.readdir(directoryPath, function (err, files) {
      if (err) {
          return console.log('Unable to scan directory: ' + err);
      }
      files.forEach(function (file) {
          multipartArr.push({
              'Content-Id': '<' + file + '>',
              'Content-Type': 'application/octet-stream name=testfile_001.xml',
              'Content-Transfer-Encoding': 'binary',
              'Content-Disposition': 'attachment; name="testfile_001.xml"; filename="testfile_001.xml"',
              //body: fs.createReadStream(file.path)
              body: fs.createReadStream(''+directoryPath+'/'+file+'')
          });
      });
  });

  const opts = {
    url: url,
    method: 'POST',
    headers: {
      'Content-Encoding': 'gzip',
      'Accept-Encoding': 'gzip,deflate',
      'Content-Type': 'multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="--'+boundary+'"',
      //'Content-Type': 'type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml";',
      'SOAPAction': 'url2',
      'MIME-Version': 1.0,
      'Transfer-Encoding': 'chunked',
      'Host': 'host',
      'Connection': 'Keep-Alive',
      'User-Agent': 'Apache-HttpClient/4.1.1 (java 1.5)',

     },
    multipart: multipartArr
  }

...并通过这样的请求http发送:

  const body = request.post(opts, (err, response) => {
    if(err) {
      console.log(err);
      return;
     }
    console.log(response.body)
  })

  //res.header('Content-Type','text/xml').send(body)
  res.send('Done')  

但是我总是收到一个错误:console.log(response.body)

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Error: Invalid MIME package: no end boundary</faultstring></soap:Fault></soap:Body></soap:Envelope>

如何为我的案例正确附加一个xml文件?

0 个答案:

没有答案