mountebank
mountebank copied to clipboard
Add support for binary HTTP request bodies
Relates to #78
Expected behavior
An HTTP request with a binary body is sent through a mountebank proxy (such as a multipart/form-data request to upload an image). The request is proxied and somehow saved to a stub if predicated on its body.
Actual behavior
The binary request body is mangled with unicode replacement characters, and the request fails.
In addition to fixing the proxying behavior, I'd like to introduce a new body:base64
predicate type to match base64-encoded binary request bodies. If that sounds good I'll submit a PR soon.
Err, with further thinking body:base64
doesn't really make sense - a new comparison operator like base64Equals
would make more sense.
For starters, this diff seems to fix the mangling:
index 872ef420..04c85da1 100644
--- a/src/models/http/httpProxy.js
+++ b/src/models/http/httpProxy.js
@@ -79,12 +79,12 @@ function create (logger) {
if (originalRequest.body &&
!headersHelper.hasHeader('Transfer-Encoding', originalRequest.headers) &&
!headersHelper.hasHeader('Content-Length', originalRequest.headers)) {
- options.headers['Content-Length'] = Buffer.byteLength(originalRequest.body);
+ options.headers['Content-Length'] = Buffer.byteLength(originalRequest.body, 'binary');
}
const proxiedRequest = protocol.request(options);
if (originalRequest.body) {
- proxiedRequest.write(originalRequest.body);
+ proxiedRequest.write(originalRequest.body, 'binary');
}
return proxiedRequest;
}
diff --git a/src/models/http/httpRequest.js b/src/models/http/httpRequest.js
index 65dd80c3..8a0084f8 100644
--- a/src/models/http/httpRequest.js
+++ b/src/models/http/httpRequest.js
@@ -54,7 +54,7 @@ function createFrom (request) {
const Q = require('q'),
deferred = Q.defer();
request.body = '';
- request.setEncoding('utf8');
+ request.setEncoding('binary');
request.on('data', chunk => { request.body += chunk; });
request.on('end', () => { deferred.resolve(transform(request)); });
return deferred.promise;
Thinking further, comparing multipart/form-data requests is probably going to be more complicated than comparing base64-encoded bodies as the boundary is subject to change between requests. I'll try an injection-based approach once #416 lands.
edit: I may not actually need to predicate against the multipart/form-data request body at all, but I believe I do need the above diff for my use case. Will keep updating here.
Resolved via #418
Reopening as previous fix broke cirillic character predicate matching.