Differences From
Artifact [af3d41e739]:
404 404 end
405 405
406 406 terra http.media_manager(co: &lib.srv.convo, path: hpath, meth: method.t)
407 407 if meth == method.post then
408 408 goto badop
409 409 end
410 410
411 - if path.ct == 1 or (path.ct >= 3 and path(1):cmp(lib.str.lit'a')) then
412 - if meth == method.post then goto badop end
413 - lib.render.media_gallery(co,path,co.who.id,nil)
414 - elseif path.ct == 2 then
415 - if path(1):cmp(lib.str.lit'upload') and co.who.rights.powers.artifact() then
416 - if meth == method.get then
417 - var view = data.view.media_upload {
418 - folders = ''
419 - }
420 - var pg = view:tostr() defer pg:free()
421 - co:stdpage([lib.srv.convo.page] {
422 - title = lib.str.plit'media :: upload';
423 - class = lib.str.plit'media upload';
424 - cache = false; body = pg;
425 - })
426 - elseif meth == method.post_file then
427 - var desc = pstring.null()
428 - var folder = pstring.null()
429 - var mime = pstring.null()
430 - var name = pstring.null()
431 - var body = binblob.null()
432 - for i=0, co.uploads.sz do var up = co.uploads.storage.ptr + i
433 - if up.body.ct > 0 then
434 - if up.field:cmp(lib.str.plit'desc') then
435 - desc = up.body
436 - elseif up.field:cmp(lib.str.plit'folder') then
437 - folder = up.body
438 - elseif up.field:cmp(lib.str.plit'file') then
439 - mime = up.ctype
440 - body = binblob {ptr = [&uint8](up.body.ptr), ct = up.body.ct}
441 - name = up.filename
442 - end
411 + if path.ct == 2 and path(1):cmp(lib.str.lit'upload') and co.who.rights.powers.artifact() then
412 + if meth == method.get then
413 + var view = data.view.media_upload {
414 + folders = ''
415 + }
416 + var pg = view:tostr() defer pg:free()
417 + co:stdpage([lib.srv.convo.page] {
418 + title = lib.str.plit'media :: upload';
419 + class = lib.str.plit'media upload';
420 + cache = false; body = pg;
421 + })
422 + elseif meth == method.post_file then
423 + var desc = pstring.null()
424 + var folder = pstring.null()
425 + var mime = pstring.null()
426 + var name = pstring.null()
427 + var body = binblob.null()
428 + for i=0, co.uploads.sz do var up = co.uploads.storage.ptr + i
429 + if up.body.ct > 0 then
430 + if up.field:cmp(lib.str.plit'desc') then
431 + desc = up.body
432 + elseif up.field:cmp(lib.str.plit'folder') then
433 + folder = up.body
434 + elseif up.field:cmp(lib.str.plit'file') then
435 + mime = up.ctype
436 + body = binblob {ptr = [&uint8](up.body.ptr), ct = up.body.ct}
437 + name = up.filename
443 438 end
444 439 end
445 - if not body then goto badop end
446 - if body.ct > co.srv.cfg.maxupsz then
447 - co:complain(403, 'file too long', "the file you have attempted to upload exceeds the maximum length permitted by this server's upload policy. if it is an image or video, try compressing it at a lower quality setting or resolution")
448 - return
449 - end
450 - var id = co.srv:artifact_instantiate(body,mime)
451 - if id == 0 then
452 - co:complain(500,'upload failed','artifact rejected. either the server is running out of space or this file is banned from the server')
453 - return
454 - end
455 - co.srv:artifact_expropriate(co.who.id,id,desc,folder)
440 + end
441 + if not body then goto badop end
442 + if body.ct > co.srv.cfg.maxupsz then
443 + co:complain(403, 'file too long', "the file you have attempted to upload exceeds the maximum length permitted by this server's upload policy. if it is an image or video, try compressing it at a lower quality setting or resolution")
444 + return
445 + end
446 + var id = co.srv:artifact_instantiate(body,mime)
447 + if id == 0 then
448 + co:complain(500,'upload failed','artifact rejected. either the server is running out of space or this file is banned from the server')
449 + return
450 + end
451 + co.srv:artifact_expropriate(co.who.id,id,desc,folder)
452 +
453 + var idbuf: int8[lib.math.shorthand.maxlen]
454 + var idlen = lib.math.shorthand.gen(id,&idbuf[0])
456 455
457 - var idbuf: int8[lib.math.shorthand.maxlen]
458 - var idlen = lib.math.shorthand.gen(id,&idbuf[0])
459 -
460 - var url = lib.str.acc{}:compose('/media/a/',pstring{&idbuf[0],idlen}):finalize()
461 - co:reroute(url.ptr)
462 - url:free()
463 - else goto badop end
464 - end
465 - else goto e404 end
456 + var url = lib.str.acc{}:compose('/media/a/',pstring{&idbuf[0],idlen}):finalize()
457 + co:reroute(url.ptr)
458 + url:free()
459 + else goto badop end
460 + else
461 + if meth == method.post then goto badop end
462 + lib.render.media_gallery(co,path,co.who.id,nil)
463 + end
466 464 do return end
467 465
468 466 ::badop:: do co:complain(405, 'invalid operation', 'the operation you have attempted on this post is not meaningful') return end
469 467 ::e404:: do co:complain(404, 'artifact not found', 'no such artifact has been uploaded by this user') return end
470 468 end
471 469
472 470 do local branches = quote end
................................................................................
505 503 end
506 504
507 505
508 506 terra http.local_avatar(co: &lib.srv.convo, handle: lib.mem.ptr(int8))
509 507 -- TODO retrieve user avatars
510 508 co:reroute('/s/default-avatar.webp')
511 509 end
510 +
511 +terra http.file_serve_raw(co: &lib.srv.convo, id: lib.mem.ptr(int8))
512 + var id, idok = lib.math.shorthand.parse(id.ptr, id.ct)
513 + if not idok then goto e404 end
514 + var data, mime = co.srv:artifact_load(id)
515 + if not data then goto e404 end
516 + do defer data:free() defer mime:free()
517 + lib.net.mg_printf(co.con, 'HTTP/1.1 200 OK\r\nContent-Type: %.*s\r\nContent-Length: %llu\r\n\r\n', mime.ct, mime.ptr, data.ct + 2)
518 + lib.net.mg_send(co.con, data.ptr, data.ct)
519 + lib.net.mg_send(co.con, '\r\n', 2)
520 + return end
521 +
522 + ::e404:: do co:complain(404, 'artifact not found', 'no such artifact has been uploaded to this instance') return end
523 +end
512 524
513 525 -- entry points
514 526 terra r.dispatch_http(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
515 527 lib.dbg('handling URI of form ', {uri.ptr,uri.ct})
516 528 co.navbar = lib.render.nav(co)
517 529 -- some routes are non-hierarchical, and can be resolved with a simple strcmp
518 530 -- we run through those first before giving up and parsing the URI
................................................................................
526 538 elseif uri.ptr[1] == @'@' then
527 539 http.actor_profile_xid(co, uri, meth)
528 540 elseif uri.ptr[1] == @'s' and uri.ptr[2] == @'/' and uri.ct > 3 then
529 541 if not meth_get(meth) then goto wrongmeth end
530 542 if not http.static_content(co, uri.ptr + 3, uri.ct - 3) then goto notfound end
531 543 elseif lib.str.ncmp('/avi/', uri.ptr, 5) == 0 then
532 544 http.local_avatar(co, [lib.mem.ptr(int8)] {ptr = uri.ptr + 5, ct = uri.ct - 5})
545 + elseif lib.str.ncmp('/file/', uri.ptr, 6) == 0 then
546 + http.file_serve_raw(co, [lib.mem.ptr(int8)] {ptr = uri.ptr + 6, ct = uri.ct - 6})
533 547 elseif uri:cmp(lib.str.plit '/notices') then
534 548 if co.aid == 0 then co:reroute('/login') return end
535 549 http.user_notices(co,meth)
536 550 elseif uri:cmp(lib.str.plit '/compose') then
537 551 if co.aid == 0 then co:reroute('/login') return end
538 552 http.post_compose(co,meth)
539 553 elseif uri:cmp(lib.str.plit '/login') then
................................................................................
551 565 if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
552 566 http.actor_profile_uid(co, path, meth)
553 567 elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
554 568 http.tweet_page(co, path, meth)
555 569 elseif path(0):cmp(lib.str.lit('tl')) then
556 570 http.timeline(co, path)
557 571 elseif path(0):cmp(lib.str.lit('media')) then
572 + if co.aid == 0 then goto unauth end
558 573 http.media_manager(co, path, meth)
559 574 elseif path(0):cmp(lib.str.lit('doc')) then
560 575 if not meth_get(meth) then goto wrongmeth end
561 576 http.documentation(co, path)
562 577 elseif path(0):cmp(lib.str.lit('conf')) then
563 578 if co.aid == 0 then goto unauth end
564 579 http.configure(co,path,meth)