Mercurial > prosody-modules
comparison mod_http_upload/mod_http_upload.lua @ 3378:aefd64629e29
mod_http_upload: Relocate function definition to avoid traceback
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 18 Nov 2018 12:16:47 +0000 |
| parents | 683365d370d8 |
| children | f1c1f6bc4892 |
comparison
equal
deleted
inserted
replaced
| 3377:683365d370d8 | 3378:aefd64629e29 |
|---|---|
| 228 -- module:measure was added in 0.10 | 228 -- module:measure was added in 0.10 |
| 229 measure_upload = module:measure("upload", "sizes"); | 229 measure_upload = module:measure("upload", "sizes"); |
| 230 end | 230 end |
| 231 | 231 |
| 232 -- http service | 232 -- http service |
| 233 local function upload_data(event, path) | |
| 234 set_cross_domain_headers(event.response); | |
| 235 | |
| 236 local uploader = pending_slots[path]; | |
| 237 if not uploader then | |
| 238 module:log("warn", "Attempt to upload to unknown slot %q", path); | |
| 239 return; -- 404 | |
| 240 end | |
| 241 local random_dir, filename = path:match("^([^/]+)/([^/]+)$"); | |
| 242 if not random_dir then | |
| 243 module:log("warn", "Invalid file path %q", path); | |
| 244 return 400; | |
| 245 end | |
| 246 if #event.request.body > file_size_limit then | |
| 247 module:log("warn", "Uploaded file too large %d bytes", #event.request.body); | |
| 248 return 400; | |
| 249 end | |
| 250 pending_slots[path] = nil; | |
| 251 local full_filename = join_path(storage_path, random_dir, filename); | |
| 252 if lfs.attributes(full_filename) then | |
| 253 module:log("warn", "File %s exists already, not replacing it", full_filename); | |
| 254 return 409; | |
| 255 end | |
| 256 local fh, ferr = io.open(full_filename, "w"); | |
| 257 if not fh then | |
| 258 module:log("error", "Could not open file %s for upload: %s", full_filename, ferr); | |
| 259 return 500; | |
| 260 end | |
| 261 local ok, err = fh:write(event.request.body); | |
| 262 if not ok then | |
| 263 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); | |
| 264 os.remove(full_filename); | |
| 265 return 500; | |
| 266 end | |
| 267 ok, err = fh:close(); | |
| 268 if not ok then | |
| 269 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); | |
| 270 os.remove(full_filename); | |
| 271 return 500; | |
| 272 end | |
| 273 measure_upload(#event.request.body); | |
| 274 module:log("info", "File uploaded by %s to slot %s", uploader, random_dir); | |
| 275 return 201; | |
| 276 end | |
| 277 | |
| 278 -- FIXME Duplicated from net.http.server | |
| 279 | |
| 280 local codes = require "net.http.codes"; | |
| 281 local headerfix = setmetatable({}, { | |
| 282 __index = function(t, k) | |
| 283 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": "; | |
| 284 t[k] = v; | |
| 285 return v; | |
| 286 end | |
| 287 }); | |
| 288 | |
| 289 local function set_cross_domain_headers(response) | 233 local function set_cross_domain_headers(response) |
| 290 local headers = response.headers; | 234 local headers = response.headers; |
| 291 headers.access_control_allow_methods = "GET, PUT, POST, OPTIONS"; | 235 headers.access_control_allow_methods = "GET, PUT, POST, OPTIONS"; |
| 292 headers.access_control_allow_headers = "Content-Type"; | 236 headers.access_control_allow_headers = "Content-Type"; |
| 293 headers.access_control_max_age = "7200"; | 237 headers.access_control_max_age = "7200"; |
| 294 headers.access_control_allow_origin = response.request.headers.origin or "*"; | 238 headers.access_control_allow_origin = response.request.headers.origin or "*"; |
| 295 return response; | 239 return response; |
| 296 end | 240 end |
| 241 | |
| 242 local function upload_data(event, path) | |
| 243 set_cross_domain_headers(event.response); | |
| 244 | |
| 245 local uploader = pending_slots[path]; | |
| 246 if not uploader then | |
| 247 module:log("warn", "Attempt to upload to unknown slot %q", path); | |
| 248 return; -- 404 | |
| 249 end | |
| 250 local random_dir, filename = path:match("^([^/]+)/([^/]+)$"); | |
| 251 if not random_dir then | |
| 252 module:log("warn", "Invalid file path %q", path); | |
| 253 return 400; | |
| 254 end | |
| 255 if #event.request.body > file_size_limit then | |
| 256 module:log("warn", "Uploaded file too large %d bytes", #event.request.body); | |
| 257 return 400; | |
| 258 end | |
| 259 pending_slots[path] = nil; | |
| 260 local full_filename = join_path(storage_path, random_dir, filename); | |
| 261 if lfs.attributes(full_filename) then | |
| 262 module:log("warn", "File %s exists already, not replacing it", full_filename); | |
| 263 return 409; | |
| 264 end | |
| 265 local fh, ferr = io.open(full_filename, "w"); | |
| 266 if not fh then | |
| 267 module:log("error", "Could not open file %s for upload: %s", full_filename, ferr); | |
| 268 return 500; | |
| 269 end | |
| 270 local ok, err = fh:write(event.request.body); | |
| 271 if not ok then | |
| 272 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); | |
| 273 os.remove(full_filename); | |
| 274 return 500; | |
| 275 end | |
| 276 ok, err = fh:close(); | |
| 277 if not ok then | |
| 278 module:log("error", "Could not write to file %s for upload: %s", full_filename, err); | |
| 279 os.remove(full_filename); | |
| 280 return 500; | |
| 281 end | |
| 282 measure_upload(#event.request.body); | |
| 283 module:log("info", "File uploaded by %s to slot %s", uploader, random_dir); | |
| 284 return 201; | |
| 285 end | |
| 286 | |
| 287 -- FIXME Duplicated from net.http.server | |
| 288 | |
| 289 local codes = require "net.http.codes"; | |
| 290 local headerfix = setmetatable({}, { | |
| 291 __index = function(t, k) | |
| 292 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": "; | |
| 293 t[k] = v; | |
| 294 return v; | |
| 295 end | |
| 296 }); | |
| 297 | 297 |
| 298 local function send_response_sans_body(response, body) | 298 local function send_response_sans_body(response, body) |
| 299 if response.finished then return; end | 299 if response.finished then return; end |
| 300 response.finished = true; | 300 response.finished = true; |
| 301 response.conn._http_open_response = nil; | 301 response.conn._http_open_response = nil; |
