parsav  Diff

Differences From Artifact [af3d41e739]:

To Artifact [8605ea50bd]:


   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)