X-Git-Url: http://nitlanguage.org diff --git a/lib/nitcorn/http_response.nit b/lib/nitcorn/http_response.nit index 523c051..97276ca 100644 --- a/lib/nitcorn/http_response.nit +++ b/lib/nitcorn/http_response.nit @@ -19,8 +19,12 @@ # Provides the `HttpResponse` class and `http_status_codes` module http_response +import serialization +private import template + # A response to send over HTTP class HttpResponse + serialize # HTTP protocol version var http_version = "HTTP/1.0" is writable @@ -35,32 +39,70 @@ class HttpResponse var header = new HashMap[String, String] # Body of this response - var body = "" is writable + var body: Writable = "" is writable + + # Files appended after `body` + var files = new Array[String] # Finalize this response before sending it over HTTP fun finalize do # Set the content length if not already set if not header.keys.has("Content-Length") then - header["Content-Length"] = body.bytelen.to_s + # Size of the body + var len + var body = self.body + if body isa Text then + len = body.byte_length + else if body isa Bytes then + len = body.length + else + # We need the length, but there is no length in a writable. + # So just render it as a bytes then measure :/ + body = body.write_to_bytes + len = body.length + # Keep the body as bytes since we have it + self.body = body + end + + # Size of included files + for path in files do + # TODO handle these error cases elsewhere, an error here will result in an invalid response + if not path.file_exists then + print_error "File does not exists at '{path}'" + continue + end + + var stat = path.file_stat + if stat == null then + print_error "Failed to stat file at '{path}'" + continue + end + + len += stat.size + end + + # Set header + header["Content-Length"] = len.to_s end # Set server ID - if not header.keys.has("Server") then header["Server"] = "unitcorn" + if not header.keys.has("Server") then header["Server"] = "nitcorn" end # Get this reponse as a string according to HTTP protocol - redef fun to_s + fun render: Writable do finalize - var buf = new FlatBuffer - buf.append("{http_version} {status_code} {status_message or else ""}\r\n") + var buf = new Template + buf.add("{http_version} {status_code} {status_message or else ""}\r\n") for key, value in header do - buf.append("{key}: {value}\r\n") + buf.add("{key}: {value}\r\n") end - buf.append("\r\n{body}") - return buf.to_s + buf.add("\r\n") + buf.add body + return buf end end @@ -73,7 +115,8 @@ class HttpStatusCodes # All know code and their message var codes = new HashMap[Int, String] - protected init do insert_status_codes + # Init the status `codes` list. + protected init is old_style_init do insert_status_codes # Get the message associated to the status `code`, return `null` in unknown fun [](code: Int): nullable String