Question

I'm playing with the idea of retrofitting spray-can with the simplistic node.js/http API.

Node allows to send a fixed length response (i.e. not chunked) in separate TCP packets. In the example below, the message is sent in eight packets. The first contains the HTTP head and the first chunk of 'x's, and the following packets contain 1024 'x's each (verified with Wireshark on OS X).

Is it possible to achieve the same with spray-can/http?

var http = require('http'),
    server = http.createServer(function (request, response) {
        var count = 8, size = 1024;

        response.writeHead(200, 'honky-dory', {
            'Content-Type': 'text/plain', 
            'Content-Length': count * size
        });

        (function send () {
            setTimeout(function () {
                response.write(Array(size + 1).join('x'));
                count -= 1;
                if(count > 0) send();
                else response.end();
            }, 10);
        }());
    });

server.listen(8080);

From what I saw so far, HttpResponse is rather 'atomic'.

UPDATE:

Based on the answers of jrudolph and Yuli Matsai, I came up with a listener which does more or less the same as the above node server. Actually it does a little more, as it doesn't allow flooding the network, because of the acknowledgements involved.

class Listener extends Actor {
  def receive = {
    case Connected (_, _) => sender ! Register (self)

    case _: HttpRequest =>
      val hs = HttpHeaders.`Content-Length` (8192) :: Nil
      sender ! ChunkedResponseStart (HttpResponse (headers = hs)).withAck (8)

    case 0 =>
      sender ! ChunkedMessageEnd

    case remaining: Int =>
      sender ! MessageChunk (body = "x" * 1024).withAck (remaining - 1)
  }
}

In order to be allowed to explicitly supply a Content-Length, the following entry must be enabled in application.conf:

spray.can.server {
    chunkless-streaming = "on"
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top