0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-10 22:18:54 +02:00

ircd:Ⓜ️:media: Start a weak central interface; move core utils into namespace.

This commit is contained in:
Jason Volk 2019-08-21 23:57:07 -07:00
parent 3a36d847eb
commit 065c0bd426
9 changed files with 422 additions and 326 deletions

View file

@ -79,6 +79,7 @@ namespace ircd::m
#include "sync.h"
#include "fetch.h"
#include "breadcrumb_rooms.h"
#include "media.h"
struct ircd::m::init
{

73
include/ircd/m/media.h Normal file
View file

@ -0,0 +1,73 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_M_MEDIA_H
namespace ircd::m::media
{
struct mxc;
}
namespace ircd::m::media::file
{
using closure = std::function<void (const const_buffer &)>;
room::id room_id(room::id::buf &out, const mxc &);
room::id::buf room_id(const mxc &);
size_t read(const room &, const closure &);
size_t write(const room &, const user::id &, const const_buffer &content, const string_view &content_type);
room::id::buf
download(const mxc &,
const m::user::id &,
const net::hostport & = {});
std::pair<http::response::head, unique_buffer<mutable_buffer>>
download(const mutable_buffer &head_buf,
const mxc &mxc,
net::hostport remote = {},
server::request::opts *const opts = nullptr);
m::room
download(const mxc &mxc,
const m::user::id &user_id,
const net::hostport &remote,
const m::room::id &room_id);
};
namespace ircd::m::media::block
{
using closure = std::function<void (const const_buffer &)>;
const_buffer get(const mutable_buffer &out, const string_view &hash);
void set(const string_view &hash, const const_buffer &block);
string_view set(const mutable_buffer &hashbuf, const const_buffer &block);
m::event::id::buf set(const room &, const user::id &, const const_buffer &block);
}
struct ircd::m::media::mxc
{
string_view server;
string_view mediaid;
public:
string_view path(const mutable_buffer &out) const;
string_view uri(const mutable_buffer &out) const;
// construct from server and file; note that if mediaid is empty then
// server is fed to the uri constructor.
mxc(const string_view &server, const string_view &mediaid);
// construct from "server/file" or "mxc://server/file"
mxc(const string_view &uri);
};

View file

@ -13367,24 +13367,12 @@ console_cmd__file__room(opt &out, const string_view &line)
param[1]
};
if(empty(file))
const m::media::mxc mxc
{
const auto s(split(server, '/'));
server = s.first;
file = s.second;
}
using prototype = m::room::id (m::room::id::buf &,
const string_view &server,
const string_view &file);
static mods::import<prototype> file_room_id
{
"media_media", "file_room_id"
server, file
};
m::room::id::buf buf;
out << file_room_id(buf, server, file) << std::endl;
out << m::media::file::room_id(mxc) << std::endl;
return true;
}
@ -13416,19 +13404,14 @@ console_cmd__file__download(opt &out, const string_view &line)
param.at("[remote]", server)
};
using prototype = m::room::id::buf (const string_view &server,
const string_view &file,
const m::user::id &,
const net::hostport &remote);
static mods::import<prototype> download
const m::media::mxc mxc
{
"media_media", "download"
server, file
};
const m::room::id::buf room_id
const auto room_id
{
download(server, file, m::me.user_id, remote)
m::media::file::download(mxc, m::me.user_id, remote)
};
out << room_id << std::endl;

View file

@ -10,6 +10,8 @@
#include "media.h"
using namespace ircd;
resource
download_resource
{
@ -73,7 +75,7 @@ get__download(client &client,
const m::room::id::buf room_id
{
download(server, file, user_id)
m::media::file::download({server, file}, user_id)
};
return get__download_local(client, request, server, file, room_id);
@ -133,7 +135,7 @@ get__download_local(client &client,
size_t sent{0}, read
{
read_each_block(room, [&client, &sent]
m::media::file::read(room, [&client, &sent]
(const string_view &block)
{
sent += write_all(*client.sock, block);
@ -142,7 +144,7 @@ get__download_local(client &client,
if(unlikely(read != file_size)) log::error
{
media_log, "File %s/%s [%s] size mismatch: expected %zu got %zu",
m::media::log, "File %s/%s [%s] size mismatch: expected %zu got %zu",
server,
file,
string_view{room.room_id},

View file

@ -10,14 +10,6 @@
#include "media.h"
ircd::mapi::header
IRCD_MODULE
{
"11.7 :Content respository",
ircd::m::media::init,
ircd::m::media::fini
};
struct ircd::m::media::magick
{
module modules
@ -26,72 +18,40 @@ struct ircd::m::media::magick
};
};
void
ircd::m::media::init()
ircd::mapi::header
IRCD_MODULE
{
static const std::string dbopts;
::media = std::make_shared<database>("media", dbopts, media_description);
::blocks = db::column{*::media, "blocks"};
"11.7 :Content respository",
ircd::m::media::init,
ircd::m::media::fini
};
// The conf setter callbacks must be manually executed after
// the database was just loaded to set the cache size.
conf::reset("ircd.media.blocks.cache.size");
conf::reset("ircd.media.blocks.cache_comp.size");
decltype(ircd::m::media::magick_support)
ircd::m::media::magick_support;
// conditions to load the magick.so module
const bool enable_magick
{
// used by the thumbnailer
thumbnail::enable
// support is available
&& mods::available("magick")
};
if(enable_magick)
magick_support.reset(new media::magick{});
else
log::warning
{
media_log, "GraphicsMagick support is disabled or unavailable."
};
}
void
ircd::m::media::fini()
{
magick_support.reset();
// The database close contains pthread_join()'s within RocksDB which
// deadlock under certain conditions when called during a dlclose()
// (i.e static destruction of this module). Therefor we must manually
// close the db here first.
::media = std::shared_ptr<database>{};
}
decltype(media_log)
media_log
decltype(ircd::m::media::log)
ircd::m::media::log
{
"m.media"
};
decltype(media_blocks_cache_enable)
media_blocks_cache_enable
decltype(ircd::m::media::blocks_cache_enable)
ircd::m::media::blocks_cache_enable
{
{ "name", "ircd.media.blocks.cache.enable" },
{ "default", true },
};
decltype(media_blocks_cache_comp_enable)
media_blocks_cache_comp_enable
decltype(ircd::m::media::blocks_cache_comp_enable)
ircd::m::media::blocks_cache_comp_enable
{
{ "name", "ircd.media.blocks.cache_comp.enable" },
{ "default", false },
};
// Blocks column
decltype(media_blocks_descriptor)
media_blocks_descriptor
decltype(ircd::m::media::blocks_descriptor)
ircd::m::media::blocks_descriptor
{
// name
"blocks",
@ -113,9 +73,9 @@ media_blocks_descriptor
{}, // prefix transform
false, // drop column
bool(media_blocks_cache_enable)? -1 : 0,
bool(blocks_cache_enable)? -1 : 0,
bool(media_blocks_cache_comp_enable)? -1 : 0,
bool(blocks_cache_comp_enable)? -1 : 0,
// bloom_bits
10,
@ -133,16 +93,16 @@ media_blocks_descriptor
""s // no compression
};
decltype(media_description)
media_description
decltype(ircd::m::media::description)
ircd::m::media::description
{
{ "default" }, // requirement of RocksDB
media_blocks_descriptor,
blocks_descriptor,
};
decltype(media_blocks_cache_size)
media_blocks_cache_size
decltype(ircd::m::media::blocks_cache_size)
ircd::m::media::blocks_cache_size
{
{
{ "name", "ircd.media.blocks.cache.size" },
@ -152,13 +112,13 @@ media_blocks_cache_size
if(!blocks)
return;
const size_t &value{media_blocks_cache_size};
const size_t &value{blocks_cache_size};
db::capacity(db::cache(blocks), value);
}
};
decltype(media_blocks_cache_comp_size)
media_blocks_cache_comp_size
decltype(ircd::m::media::blocks_cache_comp_size)
ircd::m::media::blocks_cache_comp_size
{
{
{ "name", "ircd.media.blocks.cache_comp.size" },
@ -168,54 +128,102 @@ media_blocks_cache_comp_size
if(!blocks)
return;
const size_t &value{media_blocks_cache_comp_size};
const size_t &value{blocks_cache_comp_size};
db::capacity(db::cache_compressed(blocks), value);
}
};
decltype(media)
media;
decltype(ircd::m::media::database)
ircd::m::media::database;
decltype(blocks)
blocks;
decltype(ircd::m::media::blocks)
ircd::m::media::blocks;
decltype(magick_support)
magick_support;
decltype(ircd::m::media::downloading)
ircd::m::media::downloading;
std::set<m::room::id>
downloading;
decltype(ircd::m::media::downloading_dock)
ircd::m::media::downloading_dock;
ctx::dock
downloading_dock;
//
// init
//
m::room::id::buf
download(const string_view &server,
const string_view &mediaid,
const m::user::id &user_id,
const net::hostport &remote)
void
ircd::m::media::init()
{
static const std::string dbopts;
database = std::make_shared<db::database>("media", dbopts, description);
blocks = db::column{*database, "blocks"};
// The conf setter callbacks must be manually executed after
// the database was just loaded to set the cache size.
conf::reset("ircd.media.blocks.cache.size");
conf::reset("ircd.media.blocks.cache_comp.size");
// conditions to load the magick.so module
const bool enable_magick
{
// used by the thumbnailer
thumbnail::enable
// support is available
&& mods::available("magick")
};
if(enable_magick)
magick_support.reset(new media::magick{});
else
log::warning
{
log, "GraphicsMagick support is disabled or unavailable."
};
}
void
ircd::m::media::fini()
{
magick_support.reset();
// The database close contains pthread_join()'s within RocksDB which
// deadlock under certain conditions when called during a dlclose()
// (i.e static destruction of this module). Therefor we must manually
// close the db here first.
database = std::shared_ptr<db::database>{};
}
//
// media::file
//
ircd::m::room::id::buf
IRCD_MODULE_EXPORT
ircd::m::media::file::download(const mxc &mxc,
const m::user::id &user_id,
const net::hostport &remote)
{
const m::room::id::buf room_id
{
file_room_id(server, mediaid)
file::room_id(mxc)
};
thread_local char rembuf[256];
if(remote && my_host(string(rembuf, remote)))
return room_id;
if(!remote && my_host(server))
if(!remote && my_host(mxc.server))
return room_id;
download(server, mediaid, user_id, remote, room_id);
download(mxc, user_id, remote, room_id);
return room_id;
}
m::room
download(const string_view &server,
const string_view &mediaid,
const m::user::id &user_id,
const net::hostport &remote,
const m::room::id &room_id)
ircd::m::room
IRCD_MODULE_EXPORT
ircd::m::media::file::download(const mxc &mxc,
const m::user::id &user_id,
const net::hostport &remote,
const m::room::id &room_id)
try
{
auto iit
@ -249,7 +257,7 @@ try
const auto pair
{
download(buf, server, mediaid, remote)
download(buf, mxc, remote)
};
const auto &head
@ -270,11 +278,11 @@ try
if(content_type != head.content_type) log::dwarning
{
media_log, "Server %s claims thumbnail %s is '%s' but we think it is '%s'",
log, "Server %s claims thumbnail %s is '%s' but we think it is '%s'",
string(remote),
mediaid,
mxc.mediaid,
head.content_type,
content_type
content_type,
};
m::vm::copts vmopts;
@ -292,7 +300,7 @@ try
const size_t written
{
write_file(room, user_id, content, content_type)
file::write(room, user_id, content, content_type)
};
return room;
@ -305,32 +313,36 @@ catch(const ircd::server::unavailable &e)
http::BAD_GATEWAY, "M_MEDIA_UNAVAILABLE",
"Server '%s' is not available for media for '%s/%s' :%s",
string(rembuf, remote),
server,
mediaid,
mxc.server,
mxc.mediaid,
e.what()
};
}
conf::item<seconds>
media_download_timeout
decltype(ircd::m::media::download_timeout)
ircd::m::media::download_timeout
{
{ "name", "ircd.media.download.timeout" },
{ "default", 15L },
};
std::pair<http::response::head, unique_buffer<mutable_buffer>>
download(const mutable_buffer &head_buf,
const string_view &server,
const string_view &mediaid,
net::hostport remote,
server::request::opts *const opts)
std::pair
<
ircd::http::response::head,
ircd::unique_buffer<ircd::mutable_buffer>
>
IRCD_MODULE_EXPORT
ircd::m::media::file::download(const mutable_buffer &head_buf,
const mxc &mxc,
net::hostport remote,
server::request::opts *const opts)
{
thread_local char rembuf[256];
assert(remote || !my_host(server));
assert(remote || !my_host(mxc.server));
assert(!remote || !my_host(string(rembuf, remote)));
if(!remote)
remote = server;
remote = mxc.server;
window_buffer wb{head_buf};
thread_local char uri[4_KiB];
@ -338,7 +350,9 @@ download(const mutable_buffer &head_buf,
{
wb, host(remote), "GET", fmt::sprintf
{
uri, "/_matrix/media/r0/download/%s/%s", server, mediaid
uri, "/_matrix/media/r0/download/%s/%s",
mxc.server,
mxc.mediaid,
}
};
@ -359,14 +373,14 @@ download(const mutable_buffer &head_buf,
remote, { out_head }, { in_head, {} }, opts
};
if(!remote_request.wait(seconds(media_download_timeout), std::nothrow))
if(!remote_request.wait(seconds(download_timeout), std::nothrow))
throw m::error
{
http::GATEWAY_TIMEOUT, "M_MEDIA_DOWNLOAD_TIMEOUT",
"Server '%s' did not respond with media for '%s/%s' in time",
string(rembuf, remote),
server,
mediaid
mxc.server,
mxc.mediaid
};
const auto &code
@ -387,10 +401,11 @@ download(const mutable_buffer &head_buf,
}
size_t
write_file(const m::room &room,
const m::user::id &user_id,
const const_buffer &content,
const string_view &content_type)
IRCD_MODULE_EXPORT
ircd::m::media::file::write(const m::room &room,
const m::user::id &user_id,
const const_buffer &content,
const string_view &content_type)
{
//TODO: TXN
send(room, user_id, "ircd.file.stat", "size", json::members
@ -417,7 +432,7 @@ write_file(const m::room &room,
data(content) + off, blksz
};
block_set(room, user_id, block);
block::set(room, user_id, block);
wrote += size(block);
off += blksz;
}
@ -428,19 +443,17 @@ write_file(const m::room &room,
}
size_t
read_each_block(const m::room &room,
const std::function<void (const const_buffer &)> &closure)
IRCD_MODULE_EXPORT
ircd::m::media::file::read(const m::room &room,
const closure &closure)
{
static const m::event::fetch::opts fopts
static const event::fetch::opts fopts
{
m::event::keys::include
{
"content", "type"
}
event::keys::include { "content", "type" }
};
size_t ret{0};
m::room::messages it
room::messages it
{
room, 1, &fopts
};
@ -469,7 +482,7 @@ read_each_block(const m::room &room,
const const_buffer &block
{
block_get(buf, hash)
block::get(buf, hash)
};
if(unlikely(size(block) != blksz)) throw error
@ -490,88 +503,28 @@ read_each_block(const m::room &room,
return ret;
}
const_buffer
block_get(const mutable_buffer &out,
const string_view &b58hash)
{
return read(blocks, b58hash, out);
}
//
// media::file
//
m::event::id::buf
block_set(const m::room &room,
const m::user::id &user_id,
const const_buffer &block)
{
static constexpr const auto bufsz
{
b58encode_size(sha256::digest_size)
};
char b58buf[bufsz];
const auto hash
{
block_set(mutable_buffer{b58buf}, block)
};
return send(room, user_id, "ircd.file.block", json::members
{
{ "size", long(size(block)) },
{ "hash", hash }
});
}
string_view
block_set(const mutable_buffer &b58buf,
const const_buffer &block)
{
const sha256::buf hash
{
sha256{block}
};
const string_view b58hash
{
b58encode(b58buf, hash)
};
block_set(b58hash, block);
return b58hash;
}
void
block_set(const string_view &b58hash,
const const_buffer &block)
{
write(blocks, b58hash, block);
}
m::room::id::buf
file_room_id(const string_view &server,
const string_view &file)
ircd::m::room::id::buf
IRCD_MODULE_EXPORT
ircd::m::media::file::room_id(const mxc &mxc)
{
m::room::id::buf ret;
file_room_id(ret, server, file);
room_id(ret, mxc);
return ret;
}
m::room::id
file_room_id(m::room::id::buf &out,
const string_view &server,
const string_view &file)
ircd::m::room::id
IRCD_MODULE_EXPORT
ircd::m::media::file::room_id(room::id::buf &out,
const mxc &mxc)
{
if(empty(server) || empty(file))
throw m::BAD_REQUEST
{
"Invalid MXC: empty server or file parameters..."
};
thread_local char buf[512];
const string_view path
const auto path
{
fmt::sprintf
{
buf, "%s/%s", server, file
}
mxc.path(buf)
};
const sha256::buf hash
@ -586,3 +539,141 @@ file_room_id(m::room::id::buf &out,
return out;
}
//
// media::block
//
ircd::m::event::id::buf
IRCD_MODULE_EXPORT
ircd::m::media::block::set(const m::room &room,
const m::user::id &user_id,
const const_buffer &block)
{
static constexpr const auto bufsz
{
b58encode_size(sha256::digest_size)
};
char b58buf[bufsz];
const auto hash
{
set(mutable_buffer{b58buf}, block)
};
return send(room, user_id, "ircd.file.block", json::members
{
{ "size", long(size(block)) },
{ "hash", hash }
});
}
ircd::string_view
IRCD_MODULE_EXPORT
ircd::m::media::block::set(const mutable_buffer &b58buf,
const const_buffer &block)
{
const sha256::buf hash
{
sha256{block}
};
const string_view b58hash
{
b58encode(b58buf, hash)
};
set(b58hash, block);
return b58hash;
}
void
IRCD_MODULE_EXPORT
ircd::m::media::block::set(const string_view &b58hash,
const const_buffer &block)
{
db::write(blocks, b58hash, block);
}
ircd::const_buffer
IRCD_MODULE_EXPORT
ircd::m::media::block::get(const mutable_buffer &out,
const string_view &b58hash)
{
return db::read(blocks, b58hash, out);
}
//
// media::mxc
//
IRCD_MODULE_EXPORT
ircd::m::media::mxc::mxc(const string_view &server,
const string_view &mediaid)
:server
{
split(lstrip(server, "mxc://"), '/').first
}
,mediaid
{
mediaid?: rsplit(server, '/').second
}
{
if(empty(server))
throw m::BAD_REQUEST
{
"Invalid MXC: missing server parameter."
};
if(empty(mediaid))
throw m::BAD_REQUEST
{
"Invalid MXC: missing mediaid parameter."
};
}
IRCD_MODULE_EXPORT
ircd::m::media::mxc::mxc(const string_view &uri)
:server
{
split(lstrip(uri, "mxc://"), '/').first
}
,mediaid
{
rsplit(uri, '/').second
}
{
if(empty(server))
throw m::BAD_REQUEST
{
"Invalid MXC: missing server parameter."
};
if(empty(mediaid))
throw m::BAD_REQUEST
{
"Invalid MXC: missing mediaid parameter."
};
}
ircd::string_view
IRCD_MODULE_EXPORT
ircd::m::media::mxc::uri(const mutable_buffer &out)
const
{
return fmt::sprintf
{
out, "mxc://%s/%s", server, mediaid
};
}
ircd::string_view
IRCD_MODULE_EXPORT
ircd::m::media::mxc::path(const mutable_buffer &out)
const
{
return fmt::sprintf
{
out, "%s/%s", server, mediaid
};
}

View file

@ -12,8 +12,24 @@ namespace ircd::m::media
{
struct magick;
void init();
void fini();
static void init();
static void fini();
extern log::log log;
extern std::unique_ptr<m::media::magick> magick_support;
extern conf::item<bool> blocks_cache_enable;
extern conf::item<bool> blocks_cache_comp_enable;
extern conf::item<size_t> blocks_cache_size;
extern conf::item<size_t> blocks_cache_comp_size;
extern const db::descriptor blocks_descriptor;
extern const db::description description;
extern std::shared_ptr<db::database> database;
extern db::column blocks;
extern conf::item<seconds> download_timeout;
extern std::set<m::room::id> downloading;
extern ctx::dock downloading_dock;
}
namespace ircd::m::media::thumbnail
@ -27,73 +43,3 @@ namespace ircd::m::media::thumbnail
extern conf::item<std::string> mime_whitelist;
extern conf::item<std::string> mime_blacklist;
}
using namespace ircd;
extern mapi::header IRCD_MODULE;
extern log::log media_log;
extern conf::item<bool> media_blocks_cache_enable;
extern conf::item<bool> media_blocks_cache_comp_enable;
extern conf::item<size_t> media_blocks_cache_size;
extern conf::item<size_t> media_blocks_cache_comp_size;
extern const db::descriptor media_blocks_descriptor;
extern const db::description media_description;
extern std::shared_ptr<db::database> media;
extern db::column blocks;
extern std::unique_ptr<m::media::magick> magick_support;
extern "C" m::room::id
file_room_id(m::room::id::buf &out,
const string_view &server,
const string_view &file);
m::room::id::buf
file_room_id(const string_view &server,
const string_view &file);
const_buffer
block_get(const mutable_buffer &out,
const string_view &b58hash);
void
block_set(const string_view &b58hash,
const const_buffer &block);
string_view
block_set(const mutable_buffer &b58buf,
const const_buffer &block);
m::event::id::buf
block_set(const m::room &,
const m::user::id &,
const const_buffer &block);
extern "C" size_t
read_each_block(const m::room &,
const std::function<void (const const_buffer &)> &);
extern "C" size_t
write_file(const m::room &,
const m::user::id &,
const const_buffer &content,
const string_view &content_type);
std::pair<http::response::head, unique_buffer<mutable_buffer>>
download(const mutable_buffer &head_buf,
const string_view &server,
const string_view &mediaid,
net::hostport remote = {},
server::request::opts *const opts = nullptr);
m::room
download(const string_view &server,
const string_view &mediaid,
const m::user::id &user_id,
const net::hostport &remote,
const m::room::id &room_id);
extern "C" m::room::id::buf
download(const string_view &server,
const string_view &mediaid,
const m::user::id &user_id,
const net::hostport &remote = {});

View file

@ -10,6 +10,8 @@
#include "media.h"
using namespace ircd;
resource
preview_url_resource
{

View file

@ -11,6 +11,7 @@
#include "media.h"
using namespace ircd::m::media::thumbnail; //TODO: XXX
using namespace ircd;
decltype(ircd::m::media::thumbnail::enable)
ircd::m::media::thumbnail::enable
@ -91,8 +92,7 @@ thumbnail_resource
static resource::response
get__thumbnail_local(client &client,
const resource::request &request,
const string_view &server,
const string_view &file,
const m::media::mxc &,
const m::room &room);
resource::response
@ -111,14 +111,9 @@ get__thumbnail(client &client,
"Media ID parameter required"
};
auto &server
const m::media::mxc mxc
{
request.parv[0]
};
const auto &file
{
request.parv[1]
request.parv[0], request.parv[1]
};
// Thumbnail doesn't require auth so if there is no user_id detected
@ -134,7 +129,7 @@ get__thumbnail(client &client,
{
const m::room::id::buf room_id
{
file_room_id(server, file)
m::media::file::room_id(mxc)
};
if(!exists(room_id))
@ -146,10 +141,10 @@ get__thumbnail(client &client,
const m::room::id::buf room_id
{
download(server, file, user_id)
m::media::file::download(mxc, user_id)
};
return get__thumbnail_local(client, request, server, file, room_id);
return get__thumbnail_local(client, request, mxc, room_id);
}
static resource::method
@ -167,8 +162,7 @@ method_get
static resource::response
get__thumbnail_local(client &client,
const resource::request &request,
const string_view &hostname,
const string_view &mediaid,
const m::media::mxc &mxc,
const m::room &room)
{
const auto &method
@ -247,15 +241,15 @@ get__thumbnail_local(client &client,
const size_t read_size
{
read_each_block(room, sink)
m::media::file::read(room, sink)
};
if(unlikely(read_size != file_size || file_size != copied))
throw ircd::error
{
"File %s/%s [%s] size mismatch: expected %zu got %zu copied %zu",
hostname,
mediaid,
mxc.server,
mxc.mediaid,
string_view{room.room_id},
file_size,
read_size,
@ -264,7 +258,7 @@ get__thumbnail_local(client &client,
const bool available
{
magick_support
m::media::magick_support
};
const auto mime_type
@ -309,8 +303,8 @@ get__thumbnail_local(client &client,
log::dwarning
{
"Not thumbnailing %s/%s [%s] '%s' bytes:%zu :%s",
hostname,
mediaid,
mxc.server,
mxc.mediaid,
string_view{room.room_id},
content_type,
file_size,

View file

@ -10,6 +10,8 @@
#include "media.h"
using namespace ircd;
resource
upload_resource__legacy
{
@ -53,9 +55,14 @@ post__upload(client &client,
rand::string(rand::dict::alpha, randbuf)
};
const m::media::mxc mxc
{
server, randstr
};
const m::room::id::buf room_id
{
file_room_id(server, randstr)
m::media::file::room_id(mxc)
};
m::vm::copts vmopts;
@ -78,26 +85,23 @@ post__upload(client &client,
const size_t written
{
write_file(room, request.user_id, buf, content_type)
m::media::file::write(room, request.user_id, buf, content_type)
};
char uribuf[256];
const string_view content_uri
{
fmt::sprintf
{
uribuf, "mxc://%s/%s", server, randstr
}
mxc.uri(uribuf)
};
log::debug
{
"%s uploaded %zu bytes uri: `%s' file_room: %s :%s",
m::media::log, "%s uploaded %zu bytes uri: `%s' file_room: %s :%s",
request.user_id,
request.head.content_length,
content_uri,
string_view{room.room_id},
filename
filename,
};
return resource::response