Search code examples
javascripthttpheaderxmlhttprequest

RegExp to validate an HTTP header value


I'm sending a custom header to my back-end:

var oXhr = new XMLHttpRequest;
oXhr.setRequestHeader("X-File-Name", fileName);

But if fileName contains accents for example, I get:

SyntaxError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': 'é - December 3rd, 2015.pdf' is not a valid HTTP header field value.

I have a hard time understanding the doc...

edit:

I realized that even though it does look like an accent, it's something different. It is the character: ́

It behaves strangely (ascii code 769), it confuses my browser console and even phpStorm. It comes on top of the very next character, no matter what, even when pasted (try it). The problem is that the content of this header value is a file name chosen by user from a file picker, and this file name contains this character. What would be the best approach to filter this kind of incident?


Solution

  • Only US-ASCII should be used as is specified in RFC7230 - 3.2.4. Field Parsing :

    Historically, HTTP has allowed field content with text in the ISO-8859-1 charset [ISO-8859-1], supporting other charsets only through use of [RFC2047] encoding. In practice, most HTTP header field values use only a subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD limit their field values to US-ASCII octets. A recipient SHOULD treat other octets in field content (obs-text) as opaque data.

    If you try some unsupported character

    oXhr.setRequestHeader("X-File-Name", "Φ");
    

    then you get

    Uncaught DOMException: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': 
    'Φ' is not a valid HTTP header field value.
    

    The key is where the spec says

    ... supporting other charsets only through use of [RFC2047] encoding.

    so you need to encode the value 'Φ' like this

    oXhr.setRequestHeader("X-File-Name", "=?UTF-8?Q?=CE=A6?=");
    

    In your case, you need to encode the filename before sending it, using strutil or some other library.

    Or just remove any non printable US-ASCII char from the filename

    filename.replace(/[^\x20-\x7E]+/g, '')