Mercurial Hosting > luan
annotate src/luan/modules/http/Http.luan @ 1743:792268dce5ec
http push security
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 09 Nov 2022 18:33:09 -0700 |
parents | 9713f7fd50b3 |
children |
rev | line source |
---|---|
1353
8d95711f6615
replace java() with require "java"
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
1 require "java" |
693
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
2 local Luan = require "luan:Luan.luan" |
508 | 3 local error = Luan.error |
572
f1601a4ce1aa
fix stack when calling meta-methods
Franklin Schmidt <fschmidt@gmail.com>
parents:
568
diff
changeset
|
4 local ipairs = Luan.ipairs or error() |
f1601a4ce1aa
fix stack when calling meta-methods
Franklin Schmidt <fschmidt@gmail.com>
parents:
568
diff
changeset
|
5 local pairs = Luan.pairs or error() |
1152
21d157b153fe
change http parameters interface
Franklin Schmidt <fschmidt@gmail.com>
parents:
1150
diff
changeset
|
6 local type = Luan.type or error() |
1578 | 7 local set_metatable = Luan.set_metatable or error() |
8 local get_local_cloned = Luan.get_local_cloned or error() | |
9 local set_local_cloned = Luan.set_local_cloned or error() | |
10 local get_local_only = Luan.get_local_only or error() | |
11 local set_local_only = Luan.set_local_only or error() | |
12 local raw_set = Luan.raw_set or error() | |
693
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
13 local Io = require "luan:Io.luan" |
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
14 local Html = require "luan:Html.luan" |
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
15 local Table = require "luan:Table.luan" |
580 | 16 local clear = Table.clear or error() |
1261
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
17 local java_to_table_deep = Table.java_to_table_deep or error() |
1607 | 18 local case_insensitive = Table.case_insensitive or error() |
693
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
19 local Package = require "luan:Package.luan" |
ca169567ce07
module URIs must now include ".luan"
Franklin Schmidt <fschmidt@gmail.com>
parents:
629
diff
changeset
|
20 local String = require "luan:String.luan" |
1166
7ef40e1923b7
add back Thread.global
Franklin Schmidt <fschmidt@gmail.com>
parents:
1165
diff
changeset
|
21 local lower = String.lower or error() |
1263
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
22 local trim = String.trim or error() |
1743 | 23 local regex = String.regex or error() |
1546
2b4471d310b3
better time zone handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1438
diff
changeset
|
24 local Time = require "luan:Time.luan" |
2b4471d310b3
better time zone handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1438
diff
changeset
|
25 local time_format = Time.format or error() |
1280 | 26 local Boot = require "luan:Boot.luan" |
1259
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
27 local LuanJava = require "java:luan.Luan" |
1402
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1383
diff
changeset
|
28 local Request = require "java:goodjava.webserver.Request" |
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1383
diff
changeset
|
29 local Response = require "java:goodjava.webserver.Response" |
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1383
diff
changeset
|
30 local ResponseOutputStream = require "java:goodjava.webserver.ResponseOutputStream" |
27efb1fcbcb5
move luan.lib to goodjava
Franklin Schmidt <fschmidt@gmail.com>
parents:
1383
diff
changeset
|
31 local Status = require "java:goodjava.webserver.Status" |
1738 | 32 local ServerSentEvents = require "java:goodjava.webserver.ServerSentEvents" |
1160 | 33 local OutputStreamWriter = require "java:java.io.OutputStreamWriter" |
1163 | 34 local HashMap = require "java:java.util.HashMap" |
1263
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
35 local Logging = require "luan:logging/Logging.luan" |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
36 local logger = Logging.logger "Http" |
320
fed1893821bf
remove global namespace
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
300
diff
changeset
|
37 |
1152
21d157b153fe
change http parameters interface
Franklin Schmidt <fschmidt@gmail.com>
parents:
1150
diff
changeset
|
38 |
1088
bae2d0c2576c
change module naming convention
Franklin Schmidt <fschmidt@gmail.com>
parents:
1082
diff
changeset
|
39 local Http = {} |
1578 | 40 local mt = {} |
41 function mt.__index(tbl,key) | |
1618
a37ffe2d1b14
fix not_found_handler
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
42 if key=="error_priority" or key=="not_found_handler" then |
1578 | 43 return get_local_cloned(tbl,key) |
44 elseif key=="request" or key=="response" then | |
45 return get_local_only(tbl,key) | |
46 else | |
47 return nil | |
48 end | |
49 end | |
50 function mt.__new_index(tbl,key,value) | |
1618
a37ffe2d1b14
fix not_found_handler
Franklin Schmidt <fschmidt@gmail.com>
parents:
1607
diff
changeset
|
51 if key=="error_priority" or key=="not_found_handler" then |
1578 | 52 set_local_cloned(tbl,key,value) |
53 elseif key=="request" or key=="response" then | |
54 set_local_only(tbl,key,value) | |
55 else | |
56 raw_set(tbl,key,value) | |
57 end | |
58 end | |
59 set_metatable(Http,mt) | |
320
fed1893821bf
remove global namespace
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
300
diff
changeset
|
60 |
1261
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
61 local old_java_to_table_shallow = Table.java_to_table_shallow or error() |
1259
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
62 |
1261
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
63 local function java_to_table_shallow(obj) |
1259
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
64 if type(obj)=="java" and obj.instanceof(Request.MultipartFile) then |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
65 return { |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
66 filename = obj.filename |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
67 content_type = obj.contentType |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
68 content = obj.content |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
69 } |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
70 end |
1261
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
71 return old_java_to_table_shallow(obj) |
1259
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
72 end |
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
73 |
1160 | 74 function Http.new_request(java) |
75 local this = {} | |
76 Http.request = this | |
77 if java == nil then | |
78 this.method = "GET" | |
1237 | 79 this.scheme = "http" |
1607 | 80 this.headers = case_insensitive{} |
1160 | 81 this.parameters = {} |
82 this.cookies = {} | |
83 else | |
84 this.java = java | |
1179
f9136432847e
add request.raw_head
Franklin Schmidt <fschmidt@gmail.com>
parents:
1171
diff
changeset
|
85 this.raw_head = java.rawHead or error() |
1437 | 86 this.body = java.body |
1160 | 87 this.method = java.method or error() |
88 this.raw_path = java.rawPath or error() | |
1371
4c5548a61d4f
add Request.originalPath
Franklin Schmidt <fschmidt@gmail.com>
parents:
1353
diff
changeset
|
89 this.original_path = java.originalPath or error() |
1160 | 90 this.path = java.path or error() |
91 this.protocol = java.protocol or error() | |
1237 | 92 this.scheme = java.scheme or error() |
1607 | 93 this.headers = case_insensitive(java_to_table_deep(java.headers)) |
1261
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
94 this.parameters = java_to_table_deep(java.parameters,java_to_table_shallow) |
198d6af7330a
rename Luan.to_table to Table.java_to_table_shallow and Luan.to_luan to Table.java_to_table_deep
Franklin Schmidt <fschmidt@gmail.com>
parents:
1260
diff
changeset
|
95 this.cookies = java_to_table_deep(java.cookies) |
1160 | 96 end |
497
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
97 |
499 | 98 function this.url() |
1607 | 99 return this.scheme.."://"..this.headers["Host"]..this.raw_path |
497
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
100 end |
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
101 |
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
102 return this |
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
103 end |
55f9f74f1e55
Http.request is now pure luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
495
diff
changeset
|
104 |
503 | 105 local STATUS = { |
1109 | 106 OK = 200 |
107 MOVED_PERMANENTLY = 301 | |
1160 | 108 FOUND = 302 |
1383
a3d0d1c2ce89
add NotFound to luanhost
Franklin Schmidt <fschmidt@gmail.com>
parents:
1371
diff
changeset
|
109 NOT_FOUND = 404 |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
110 -- add more as needed |
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
111 } |
1088
bae2d0c2576c
change module naming convention
Franklin Schmidt <fschmidt@gmail.com>
parents:
1082
diff
changeset
|
112 Http.STATUS = STATUS |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
113 |
1163 | 114 function Http.new_response() |
1160 | 115 local this = {} |
116 Http.response = this | |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
117 |
1163 | 118 function this.reset() |
119 this.java = Response.new() | |
1607 | 120 this.headers = case_insensitive{} |
1163 | 121 this.status = STATUS.OK |
122 this.writer = nil | |
123 end | |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
124 |
1163 | 125 this.reset() |
1153
1f4da56abd4f
change http cookies interface
Franklin Schmidt <fschmidt@gmail.com>
parents:
1152
diff
changeset
|
126 |
1160 | 127 function this.send_redirect(location) |
128 this.status = STATUS.FOUND | |
1607 | 129 this.headers["Location"] = location |
1160 | 130 end |
131 | |
1161 | 132 function this.send_error(status,msg) |
1163 | 133 this.reset() |
1161 | 134 this.status = status |
135 if msg ~= nil then | |
1607 | 136 this.headers["Content-Type"] = "text/plain; charset=utf-8" |
1161 | 137 local writer = this.text_writer() |
138 writer.write(msg) | |
139 end | |
140 end | |
141 | |
1160 | 142 function this.set_cookie(name,value,attributes) |
1163 | 143 attributes = attributes or {} |
1213 | 144 attributes["Path"] = attributes["Path"] or "/" |
1163 | 145 local attrMap = HashMap.new() |
146 for attr_name, attr_value in pairs(attributes) do | |
1164 | 147 type(attr_name)=="string" or "cookie attribute name must be string" |
148 type(attr_value)=="string" or "cookie attribute value must be string" | |
1163 | 149 attrMap.put(attr_name,attr_value) |
150 end | |
151 this.java.setCookie(name,value,attrMap) | |
1160 | 152 end |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
153 |
1160 | 154 function this.set_persistent_cookie(name,value,attributes) |
155 attributes = attributes or {} | |
156 attributes["Max-Age"] = "10000000" | |
157 this.set_cookie(name,value,attributes) | |
158 end | |
159 | |
160 function this.remove_cookie(name,attributes) | |
161 attributes = attributes or {} | |
162 attributes["Max-Age"] = "0" | |
163 this.set_cookie(name,"delete",attributes) | |
164 end | |
568
aa17ad66a370
fix http response headers
Franklin Schmidt <fschmidt@gmail.com>
parents:
509
diff
changeset
|
165 |
1160 | 166 function this.text_writer() |
1559 | 167 this.writer and error "writer already set" |
1160 | 168 this.writer = ResponseOutputStream.new(this.java) |
169 this.writer = OutputStreamWriter.new(this.writer) | |
1280 | 170 return Boot.text_writer(this.writer) |
1160 | 171 end |
500
ab9c2afefb47
add response.binary_writer
Franklin Schmidt <fschmidt@gmail.com>
parents:
499
diff
changeset
|
172 |
1160 | 173 function this.binary_writer() |
1559 | 174 this.writer and error "writer already set" |
1160 | 175 this.writer = ResponseOutputStream.new(this.java) |
1280 | 176 return Boot.binary_writer(this.writer) |
1160 | 177 end |
580 | 178 |
498
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
179 return this |
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
180 end |
ee55be414a34
Http.response is now mostly luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
497
diff
changeset
|
181 |
1163 | 182 function Http.finish() -- called only from java |
183 local response = Http.response or error() | |
184 local java = response.java or error() | |
185 java.status = Status.getStatus(response.status) | |
186 for name, value in pairs(response.headers) do | |
1164 | 187 type(name)=="string" or "header name must be string" |
1259
e8020216dee7
add Luan.to_luan and fix multipart/form-data
Franklin Schmidt <fschmidt@gmail.com>
parents:
1257
diff
changeset
|
188 value = LuanJava.toJava(value) |
1163 | 189 java.headers.put(name,value) |
190 end | |
191 response.writer and response.writer.close() | |
192 return java | |
193 end | |
194 | |
1438 | 195 function Http.error_priority(e) |
1263
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
196 return "error" |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
197 end |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
198 |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
199 function Http.handle_error(java_request,e) |
1438 | 200 Http.new_request(java_request) |
201 local call = Http.error_priority(e) | |
1263
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
202 local err = e.get_stack_trace_string() |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
203 logger[call](err.."\n"..trim(java_request.rawHead).."\n") |
1648 | 204 local msg = "Internal Server Error\n\n"..err |
1263
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
205 return Response.errorResponse( Status.INTERNAL_SERVER_ERROR, msg ) |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
206 end |
382c444a6c77
add Http.eval_in_root and Http.handle_error
Franklin Schmidt <fschmidt@gmail.com>
parents:
1261
diff
changeset
|
207 |
1315 | 208 Http.domain = nil -- set in domain specific cases |
1743 | 209 local domain_regex = nil |
210 function Http.set_domain(domain) | |
211 Http.domain = domain or error() | |
212 domain_regex = regex( [[^https?://]]..domain..[[(/|:)]] ) | |
213 end | |
1315 | 214 |
1414 | 215 Http.is_serving = false |
216 | |
1546
2b4471d310b3
better time zone handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1438
diff
changeset
|
217 function Http.format_date(date) |
1607 | 218 return time_format(date,"EEE, dd MMM yyyy HH:mm:ss z","GMT") |
1546
2b4471d310b3
better time zone handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1438
diff
changeset
|
219 end |
2b4471d310b3
better time zone handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
1438
diff
changeset
|
220 |
1743 | 221 local sse_push = ServerSentEvents.writeMessage |
222 function Http.push( url, message ) | |
223 domain_regex==nil or domain_regex.matches(url) or error "can't push to another domain" | |
224 sse_push(url,message) | |
225 end | |
1738 | 226 |
1088
bae2d0c2576c
change module naming convention
Franklin Schmidt <fschmidt@gmail.com>
parents:
1082
diff
changeset
|
227 return Http |