47 lines
2.0 KiB
D
47 lines
2.0 KiB
D
module attachment.api;
|
|
|
|
import handy_http_primitives;
|
|
import handy_http_data.json;
|
|
import std.conv;
|
|
|
|
import profile.data;
|
|
import profile.data_impl_sqlite;
|
|
import profile.service;
|
|
import auth.service;
|
|
import auth.model;
|
|
import util.data;
|
|
import attachment.data;
|
|
import attachment.model;
|
|
|
|
/**
|
|
* Handles downloading of an attachment. Because the browser is doing the
|
|
* downloading instead of a Javascript client, this means we have to embed the
|
|
* user's auth token in the query parameters and deal with it differently from
|
|
* normal authenticated requests.
|
|
* Params:
|
|
* request = The HTTP request.
|
|
* response = The HTTP response.
|
|
*/
|
|
void handleDownloadAttachment(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
Optional!AuthContext authCtx = extractAuthContextFromQueryParam(request, response);
|
|
if (authCtx.isNull) return;
|
|
User user = authCtx.value.user;
|
|
string profileName = request.getPathParamOrThrow!string("profile");
|
|
ProfileRepository repo = new FileSystemProfileRepository(user.username);
|
|
ProfileContext profileCtx = repo.findByName(profileName)
|
|
.mapIfPresent!(p => ProfileContext(p, user))
|
|
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
|
|
ProfileDataSource ds = getProfileDataSource(profileCtx);
|
|
|
|
ulong attachmentId = request.getPathParamOrThrow!ulong("attachmentId");
|
|
AttachmentRepository attachmentRepo = ds.getAttachmentRepository();
|
|
Attachment attachment = attachmentRepo.findById(attachmentId)
|
|
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND, "Attachment not found."));
|
|
ubyte[] content = attachmentRepo.getContent(attachment.id)
|
|
.orElseThrow(() => new HttpStatusException(
|
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
"Couldn't get content for attachment."
|
|
));
|
|
response.headers.add("Content-Disposition", "attachment; filename=\"" ~ attachment.filename ~ "\"");
|
|
response.writeBodyBytes(content, attachment.contentType);
|
|
} |