Performing soap mtom requests


We’re trying to create soap requests with attachments (mtom).

So far we’ve used fileBody(using ssp templates and placeholders for the xml-stuff), creating multipart boundaries etc manually.

Now, in our case the attachment is binary - this is giving us some problems due to non printable characters in pdf etc

What would be the best approach to solve this issue? Create a cusom fileBodyMtom thing?

Btw, we’re using gatling 1.5



I think we need a better multipart support.
Let me think about it.

Implemented in master:

You’ll be able to grab a SNAPSHOT on Cloudbees in ~30 minutes:
Note that this won’t be backported as this part of the code is quite different, sorry.



Man, you’re fast. Thanks for your great effort.

I’ve looked at your commit, andt seems the API lacks a feature that I would need in order to perform for instance SOAP MTOM requests

If you look at the example below (generated using apache cxf), you will notice that I need to be able to set several specific “http” headers per part. I can’t see how that can be achieved using the API you implemented.
In addition, I need to be able to set a relatively complex content-type header (it’s a mulitpart related header ++) for the entire request, but I guess that should be ok?

POST /somewhere
Other irrelevant headers…

Content-Type: multipart/related; type=“application/xop+xml”; boundary=“uuid:BOUNDARY”; start=“”; start-info=“text/xml”

Content-Type: application/xop+xml; charset=UTF-8; type=“text/xml”;
Content-Transfer-Encoding: binary
Content-ID: <>

<soapenv:Envelope xmlns:soapenv=“”>
<ns2:createDoc xmlns:ns2=“” >

<xop:Include xmlns:xop=“""/>

Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <>


Actually, Content-Type is the mimeType parameter, Content-Transfer-Encoding is automatically set when you send a File or a Byte array. The only thing that’s missing is this Content-ID custom header. AHC doesn’t currently support setting other headers.

Could you give it a try as is?
If we really need those custom headers, I’ll have to hack AHC…

I’m pretty sure we’ll need the Content-ID header - I’ll give it a shot anyways. I’ll keep you posted.

Kinda lame httpclient doesn’t support it. Seems like custom headers only can be applied to form-data mulitpart requests. I see no reason why.

I'm pretty sure we'll need the Content-ID header - I'll give it a shot
anyways. I'll keep you posted.

I'm quite pessimistic too...

Kinda lame httpclient doesn't support it. Seems like custom headers only
can be applied to form-data mulitpart requests. I see no reason why.

Well, that's probably because you're the first one to ask for it :wink:

Ok. Just testet without the Content-ID header.

Cxf crashes: java.lang.IllegalStateException: No attachment for id found in []

It makes sense, since cxf otherwise won’t know which part to reference.

Also, the spec also has a nice example:


How easy is it to get patches into ahc?

What do you mean? How easy is it to develop Content-ID header support, or how easy is it to get a pull request accepted and a new release to be done?
The former: simply adding Content-ID support is pretty straight forward, adding support for every kind of header is probably a bit more work. The main problem is compatibility.
The latter: I’m an AHC committer, and Jean-François Arcand is a very nice guy and can do a release anytime.

I probably won’t have time to develop Content-ID before this week-end, probably beginning of next week. If you can help with a PR, that would be much appreciated. If you do so, beware of doing it against the 1.7.X branch, not master.

ok. If you’re already an ahc committer it’s probibly way better that you implement this. I’ve hardly looked at the source of ahc since version 4.


You’re confusing apache httpclient and async http client. We use the latter.
Being a committer doesn’t make me an expert, just someone willing to lend a hand. :wink:

Issue opened:

I see, I see. Anyways, I looked at Apache Http Mime, and there is no support for adding custom headers (like Content-ID) there either. That might be an issue if you use apache as the backend for asynch client.

AHC only supports Apache HttpClient v3 (pretty ugly story), which will be dropped in the next major release, and will never support v4.

Default Provider is Netty.

I was able to quickly implement this:

Could you give it a try, please?

Hi there,

I’m currently converting our project to 2.0 in order to test your fix, however, since I’m a total scala newbie, I’m struggeling with converting our custom functions.

We used to do stuff like this in 1.5

val injectSamlAssertion = (session: Session) => {
val userid: String = session.getTypedAttribute(“userid”)
session.setAttributes(Map(“userid” → userid, “saml” → saml.generateSingedAssertionForUser(userid)))


  • session(“foo”) returns an Any that can be casted with .asInstanceOf[String] into a String, but will crash if “foo” attribute is missing or if it’s not a String

  • session.getString will return an Option[String], meaning that it will not crash is “foo” is missing, but will if it’s not a String

  • session.getVString will never crash but you have to use it properly
    Your code is not very safe, but it will compile once to remove .success: there’s an implicit that does it for you, but you lack the import to do it explicitly.

The proper way is:

val injectSamlAssertion = (session: Session) => { =>
session.setAll(Map(“userid” → userid, “saml” → saml.generateSingedAssertionForUser(userid))))

Hi there,

I tried your code. It gives med the following error when I do exec(injectSamlAssertion):

scala: overloaded method value exec with alternatives:
(scenario: io.gatling.core.structure.ScenarioBuilder)io.gatling.core.structure.ScenarioBuilder
(chains: Iterable[io.gatling.core.structure.ChainBuilder])io.gatling.core.structure.ScenarioBuilder
(chains: Iterator[io.gatling.core.structure.ChainBuilder])io.gatling.core.structure.ScenarioBuilder
(chains: io.gatling.core.structure.ChainBuilder*)io.gatling.core.structure.ScenarioBuilder
(actionBuilder: io.gatling.core.action.builder.ActionBuilder)io.gatling.core.structure.ScenarioBuilder
(sessionFunction: io.gatling.core.session.Session => io.gatling.core.validation.Validation[io.gatling.core.session.Session])io.gatling.core.structure.ScenarioBuilder
cannot be applied to (io.gatling.core.Predef.Session => Option[io.gatling.core.session.Session])

Just to clarify - what I’m trying to do is to exec() a function that will add a new attribute to the session (based on the userid session attribute) while keeping the existing ones.(similar to what is done here:

Could you send me your whole code so I can fix it at once, so we can avoid all the roundtrips?