Setting content-type header with restify results in application/octet-stream

I'm trying out restify, and though I'm more comfortable with Express, so far it's pretty awesome. I'm trying to set the content type header in the response like so:

server.get('/xml', function(req, res) {
    res.setHeader('content-type', 'application/xml');
    // res.header('content-type', 'application/xml'); // tried this too
    // res.contentType = "application/xml"; // tried this too
    res.send("<root><test>stuff</test></root>");
});

But the response I get back is instead application/octet-stream.

I also tried res.contentType('application/xml') but that actually threw an error ("Object HTTP/1.1 200 OK\ has no method 'contentType'").

What is the correct way to set the content type header to xml on the response?

Update:

When I do console.log(res.contentType); it actually outputs application/xml. Why is it not in the response headers?

Curl snippet:

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /xml?params=1,2,3 HTTP/1.1
> User-Agent: curl/7.39.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/octet-stream
< Content-Length: 8995
< Date: Mon, 23 Feb 2015 20:20:14 GMT
< Connection: keep-alive
< 
<body goes here>

Turns out the reason this was failing is because I was not sending the response using Restify's response handler; it was defaulting to the native Node.js handler.

Where I was doing this:

res.send(js2xmlparser("search", obj));

I should have been doing this:

res.end(js2xmlparser("search", o));
//  ^ end, not send!

Request API, Setting content-type header with restify results in application/octet-stream - node. js. If no formatter matching the content-type can be found, restify will by default override the response’s content-type to 'application/octet-stream' and then error if no formatter is found for that content-type. This default behavior can be changed by passing strictFormatters: false (default is false) when creating the restify server instance.

When I do console.log(res.contentType); it actually outputs application/xml. Why is it not in the response headers?

All you've done there is set a property on the res object. And because this is JavaScript, that works fine and you can read the property value back, but that's not the correct API for either node core or restify, so it is ignored by everything other than your code.

Your res.header("Content-Type", "application/xml"); looks correct to me based on the restify docs you linked to. Therefore my hunch is your tooling may be misleading you. Are you sure you are seeing the raw values in the response (many developer tools will unhelpfully "prettify" or otherwise lie to you) and you are hitting the route you really think you are? Output of curl -v or httpie --headers would be helpful.

Restify Error handler and Content-Type: (text or html) broken · Issue , setHeader('Content-Type', 'text/html'); Chrome will show it as a bad response of 0 the result in a quote (") string (the default of the json content type). This would resolve the application/octet-stream issue you are seeing:. In this case, since your response has not specified a content-type (using res.header('content-type')) restify tries to find the content-type most suitable, in order of what the browser has asked for. In this case, the first match is xml.

It is possible to return application/xml by adding a formatter to the server instance at server creation:

var server  = restify.createServer( {
   formatters: {
       'application/xml' : function( req, res, body, cb ) {
           if (body instanceof Error)
              return body.stack;

           if (Buffer.isBuffer(body))
              return cb(null, body.toString('base64'));

           return cb(null, body);
       }
  } 
});

Then at some part of the code:

res.setHeader('content-type', 'application/xml');
res.send('<xml>xyz</xml>');

Please, take a look at: http://restify.com/#content-negotiation

Missing 'content-type' header for errors generated by Restify · Issue , https://github.com/restify/node-restify/blob/5.x/lib/server.js#L215 to use, in which case it should be falling back on application/octet-stream as the default. The browser will get a content-type header of application/xml. Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type. I'm trying to set Accept header to application/octet

You can send the XML response using sendRaw instead of send. The sendRaw method doesn't use any formatter at all (you should preformat your response if you need it). See an example below:

server.get('/xml', function(req, res, next) {
  res.setHeader('content-type', 'application/xml');
  res.sendRaw('<xml>xyz</xml>');
  next();
});

API Guide, restify is a node.js module built specifically to enable you to build correct REST name, String, By default, this will be set in the Server response header, default is restify fact that restify ships with application/json , text/plain and application/ octet-stream formatters. Of course, you can always explicitly set the content- type: If you include these messages in subsequent actions without casting, requests go out with the Content-Type header set to text/plain. For example, when you're working with a flat file, you might get an HTTP request with the Content-Type header set to text/plain content type: Date,Name,Address Oct-1,Frank,123 Ave

MIME types (IANA media types), A media type (also known as a Multipurpose Internet Mail Extensions or MIME Generic binary data (or binary data whose true type is unknown) is application/ octet-stream . They treat it as if the Content-Disposition header was set to and using any of those may result in scripts that do not load or run. You can set the acceptable (or server.acceptParser) param to tell restify to 415 all clients expecting a response type different than ones you may reply with. You can enforce the request to be a specific type by using req.is , for example to catch up all json requests you may want to use req.is('application/json') or req.is('json') .

qhttp: Documentation, QHttp auto-detects the request body and encodes it accordingly: strings as-is as text/plain , Buffers as-is as application/octet-stream , all else encoded with JSON. stringify as emulateRestifyClient(client) : decorate client with some restify jsonClient The call always sets Content-Type to match the body (unless already set),  restify will infer a formatter based on the content-type header you've set, falling back on application/octet-stream if no match is found. Since your server can presumably serve multiple types of payloads (html/json/whatever) you need to be explicit about it.

Package, The type option is used to determine what media type the middleware will parse. a mime type (like application/octet-stream ), or a mime type with a wildcard (like This error will occur when the request had a Content-Encoding header that restify-batch-endpoint · @buggyorg/library-mongo · react-controller-example  name String the name of the header; value String default value if header isn’t found on the req; Returns String trailer value. is. Check if the incoming request contains the Content-Type header field, and if it contains the given mime type. Parameters. type String a content-type header value; Examples

Comments
  • Can you post a snippet of curl or httpie command line testing this? You should confirm you are really hitting the server side code you think you are hitting.
  • @PeterLyons added. Moreover, in response to your answer, there are several instances around the web where all three of those options are used to set the headers o_O all three have the same outcome as well, setting the headers to application/octet-stream.
  • Thanks. Only thing I can think of is try using the correct case for "Content-Type". Otherwise this small example should be fine, or there's something else in your setup (like forgot to restart the server so you are running an old version of the code or something) tripping you up.
  • @PeterLyons yeah, tried uppercase too, and I know the server is running the correct copy of code because I added in the console log.
  • Do u have any explanation, why this happens like this?
  • Nope - I presume it was just an oversight (or intentionally designed).
  • I have the same issue, but ending doesn't fix for me, any other suggestion?