16

I'm writing a web application API, where when someone accesses a URL, it returns text data. I set the content-type to "text/plain", but when I access it with Chrome, it downloads a file that contains the information, instead of displaying it. When I access it with IE, it shows properly, and when I access with Firefox, it says that it's attempting to access an application/octet-stream, and asking me if I want to download the file.

I recorded what was being returned by the web server using TinyHTTPProxy, and it's as follows:

[2012-03-11 16:51:45.345] INFO     {TinyHTTPProxy Thread-4} HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: close
Date: Mon, 05 Mar 2012 09:49:54 GMT
Server: localhost


[2012-03-11 16:51:45.345] INFO     {TinyHTTPProxy Thread-4} 10b
P,FIO,7,31.5900,0.,,0,100,0,0,30.7600,31.9600,100,1000,,,0.,16:03:14t,,0,31.5900    ,1.2,,,15,n,,,,,03/09/2012,,31.2200,,,,-0.37,-0.37,0.274456994,,,,,0,,2846732.85    ,14,4,,3989502,BSE-CSE-NYSE-PSE-NMS,,,,,0,,,0,1155872,N,,26,26,26,16:03:14,5-7-10-11-12-13-18-25-26-28-80,0

If I change the content-type to "application-json", then it displays on all browsers. Also, if I change the content-type to "text/html", it also works, even though I'm not returning an HTML file.

Is there an explanation why text/plain is behaving this way? I checked to make sure that all of the data being returned back is actually ASCII, and since I'm setting the content-type to be text/plain, I'm confused why it's being interpreted as application/octet-stream.

steve8918
  • 1,820
  • 6
  • 27
  • 38

2 Answers2

13

It sounds like you may be running into Chrome Issue 106150. Chrome apparently (sometimes) decides to use "sniffing" logic when the content-type is text/plain.

Possible workarounds:

  • Send the X-Content-Type-Options: nosniff header.
  • If the text is Unicode, include a BOM. This will tell the sniffing logic that it really is text.
  • Remove "binary looking" bytes from the file. From the bug report "Any value between 0x00 and 0x1f looks binary except for ESC, CR, NP, NL, HT".
  • It sounds like using an extension that's obviously supposed to be text/plain (like .txt) might disable the sniffing.
randers
  • 5,031
  • 5
  • 37
  • 64
Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • Interesting, thanks for the info, I didn't realize that the browsers would sniff the data to try to do something more intelligent. – steve8918 Mar 12 '12 at 03:21
  • Thanks for this. I was pulling my hair out trying to figure out why Chrome was insisting on downloading a UTF-8 text/plain file, and it turns out there were two instances of 0x02 in it. – dgw Jan 21 '15 at 00:52
  • Chrome will sniff only the first x bytes (possibly 1KB) for binary looking bytes, which can cause this to be unpredictable - sometimes I had binary looking bytes in the first 1KB and sometimes I didn't while doing some investigative print_r calls. See @trinth's answer for the current day solution. – thomasrutter May 01 '17 at 04:10
9

Laurence's explanation is correct. Only IE and Chrome is performing mime sniffing at the time of this post. You can now just set the HTTP header X-Content-Type-Options: nosniff and it will do the trick!

trinth
  • 5,919
  • 9
  • 40
  • 45