React-native: [IOS] "fetch + FormData" create the Content-Type with a boundary wrapped with delimiter "

Created on 14 May 2016  路  8Comments  路  Source: facebook/react-native

When I attempt to upload file using the _fetch_ + _FormData_, Android plays well and IOS always fails. After monitoring the http request, I found that IOS creates the http request as follows:

100144153633240385

the _boundary_ in the _content-type_ is wrapped with delimiter _"_
and this is the android's:

712435250518463508

This is probably cause by the code in _react-native/Libraries/Network/RCTNetworking.m_line 117

https://github.com/facebook/react-native/blob/5723915eaacfd3d8a8a7165c550f1fb9316c15ad/Libraries/Network/RCTNetworking.m

Another little problem is that ios does not add "content-length" for each part.

Locked

Most helpful comment

@unordered Thanks! I +1ed it before, just was wondering if we have some client side work around until react-native fix will land.
Currently I'm patching the header on the server side - something like that if anyone is interested
Using node + express

// HACK - react-native generates FormData with an invalid boundary that might contain '/'
// we need to wrap the boundary value with quotes to fix it
// TODO - remove this when react-native releases the fix
var re = /^multipart\/form-data.\s?boundary=['"]?(.*?)['"]?$/i;
app.use(function (req, res, next) {
    var contentType = req.headers['content-type'];
    var match = re.exec(contentType);
    if (match && match.length === 2) {
        req.headers['content-type'] = 'multipart/form-data; boundary="' + match[1] + '"';
    }
    next();
});

All 8 comments

Can you reproduce this problem on a small sample app with a rnplay.org link?

@lacker @XuChangZJU I happened to have the same issue. It happened only on some servers where 'ModSecurity' is enabled, and MULTIPART_BOUNDARY_QUOTED rule is added in same. What it saying is that we have to remove the "'" on sending boundary for example

boundary="some_value"

to

 boundary=some_value 

In Libraries/Network/RCTNetworking.mm there

 NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=\"%@\"", _boundary];

when i change to

 NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", _boundary];

then compiled then run and its working perfect,I have made pull request too
https://github.com/facebook/react-native/pull/10876

not work if boundary include slash

// koa request.js (line 548)
  is(types) {
    if (!types) return typeis(this.req);
    if (!Array.isArray(types)) types = [].slice.call(arguments);
    return typeis(this.req, types);
  }

// type-is index.js (line 237)
function normalizeType (value) {
  // parse the type
  var type = typer.parse(value)

  // remove the parameters
  type.parameters = undefined

  // reformat it
  return typer.format(type)
}

// media-typer
var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u0020-\u007e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g;

https://github.com/jshttp/media-typer/issues/5
The / is an illegal character for Content-Type, which is what this module parses. The boundary parameter value needs to be quoted if it contains a / character, for example:

multipart/form-data; boundary="b/QeEbFgqK9PCZo4T/eXv7f.T74SHd5MxCZ846AsTz-yNV0xrRR_Zks4fkNMCzJck9ZE8o"

may the quote is necessary

@unordered I'm having the same issue, any workaround for that until this is resolved?

@unordered Thanks! I +1ed it before, just was wondering if we have some client side work around until react-native fix will land.
Currently I'm patching the header on the server side - something like that if anyone is interested
Using node + express

// HACK - react-native generates FormData with an invalid boundary that might contain '/'
// we need to wrap the boundary value with quotes to fix it
// TODO - remove this when react-native releases the fix
var re = /^multipart\/form-data.\s?boundary=['"]?(.*?)['"]?$/i;
app.use(function (req, res, next) {
    var contentType = req.headers['content-type'];
    var match = re.exec(contentType);
    if (match && match.length === 2) {
        req.headers['content-type'] = 'multipart/form-data; boundary="' + match[1] + '"';
    }
    next();
});

This is also an issue for me. When will the official fix land? Anyone? Never mind, I see it made it into RN-0.41. Thanks!

This bug is still present in 0.41.2
EDIT: I forgot to recompile. Working great!!

For now @kfiroo 's fix works great though, thank you!

Was this page helpful?
0 / 5 - 0 ratings