1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2013 Frederic Sevillano
4 # Copyright 2013 Jean-Philippe Caissy <jpcaissy@piji.ca>
5 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 # Provides the `HttpResponse` class and `http_status_codes`
24 # A response to send over HTTP
28 # HTTP protocol version
29 var http_version
= "HTTP/1.0" is writable
31 # Status code of this response (200, 404, etc.)
32 var status_code
: Int is writable
34 # Return the message associated to `status_code`
35 fun status_message
: nullable String do return http_status_codes
[status_code
]
37 # Headers of this response as a `Map`
38 var header
= new HashMap[String, String]
40 # Body of this response
41 var body
= "" is writable
43 # Files appended after `body`
44 var files
= new Array[String]
46 # Finalize this response before sending it over HTTP
49 # Set the content length if not already set
50 if not header
.keys
.has
("Content-Length") then
52 var len
= body
.byte_length
54 # Size of included files
56 # TODO handle these error cases elsewhere, an error here will result in an invalid response
57 if not path
.file_exists
then
58 print_error
"File does not exists at '{path}'"
62 var stat
= path
.file_stat
64 print_error
"Failed to stat file at '{path}'"
72 header
["Content-Length"] = len
.to_s
76 if not header
.keys
.has
("Server") then header
["Server"] = "nitcorn"
79 # Get this reponse as a string according to HTTP protocol
84 var buf
= new FlatBuffer
85 buf
.append
("{http_version} {status_code} {status_message or else ""}\r\n")
86 for key
, value
in header
do
87 buf
.append
("{key}: {value}\r\n")
89 buf
.append
("\r\n{body}")
94 # Helper class to associate HTTP status code to their message
96 # You probably want the default instance available as the top-level method
97 # `http_status_codes`.
100 # All know code and their message
101 var codes
= new HashMap[Int, String]
103 # Init the status `codes` list.
104 protected init is old_style_init
do insert_status_codes
106 # Get the message associated to the status `code`, return `null` in unknown
107 fun [](code
: Int): nullable String
109 if codes
.keys
.has
(code
) then
114 private fun insert_status_codes
116 codes
[100] = "Continue"
117 codes
[101] = "Switching Protocols"
119 codes
[201] = "Created"
120 codes
[202] = "Accepted"
121 codes
[203] = "Non-Authoritative Information"
122 codes
[204] = "No Content"
123 codes
[205] = "Reset Content"
124 codes
[206] = "Partial Content"
125 codes
[300] = "Multiple Choices"
126 codes
[301] = "Moved Permanently"
128 codes
[303] = "See Other"
129 codes
[304] = "Not Modified"
130 codes
[305] = "Use Proxy"
131 codes
[307] = "Temporary Redirect"
132 codes
[400] = "Bad Request"
133 codes
[401] = "Unauthorized"
134 codes
[402] = "Payment Requred"
135 codes
[403] = "Forbidden"
136 codes
[404] = "Not Found"
137 codes
[405] = "Method Not Allowed"
138 codes
[406] = "Not Acceptable"
139 codes
[407] = "Proxy Authentication Required"
140 codes
[408] = "Request Timeout"
141 codes
[409] = "Conflict"
143 codes
[411] = "Length Required"
144 codes
[412] = "Precondition Failed"
145 codes
[413] = "Request Entity Too Large"
146 codes
[414] = "Request-URI Too Long"
147 codes
[415] = "Unsupported Media Type"
148 codes
[416] = "Requested Range Not Satisfiable"
149 codes
[417] = "Expectation Failed"
150 codes
[500] = "Internal Server Error"
151 codes
[501] = "Not Implemented"
152 codes
[502] = "Bad Gateway"
153 codes
[503] = "Service Unavailable"
154 codes
[504] = "Gateway Timeout"
155 codes
[505] = "HTTP Version Not Supported"
159 # Get the default instance of `HttpStatusCodes`
160 fun http_status_codes
: HttpStatusCodes do return once
new HttpStatusCodes