Skip to content

Embedding downloadable files

Liios edited this page Apr 28, 2021 · 1 revision

HTML

To embed a file you need to use a link with a download attribute in your template:

<a href="file-embed.html"
   download="source.html"
   data-content-type="text/html"
   title="File embedded"
   relationship="Source">Click me!</a>

The attributes are:

  • href: uri to the file source. Required.
  • download: The file name as presented in the PDF viewer. Required.
  • data-content-type: The mime type of the embedded file. Defaults to application/octet-stream.
  • title: Optional short description of the file. Strongly recommended for PDF/A3 documents.
  • relationship: Should only be used in PDF/A3 documents. The relationship of the embedded file to the link. Must be one of the following:
    • Source - Example: source markup of the document.
    • Supplement
    • Data - Example tabular data.
    • Alternative - Example audio providing an alternative view of the material.
    • Unspecified - Fallback catch all.

NOTE: If the relationship attribute is present the files modification date is set to the servers current date (Calendar.getInstance()). The modification date is required by PDF/A3.

Java

Java-wise, you will need to implement a custom resource access controller as the one by default forbids access to FILE_EMBED type external resources.

A naive implementation would be:

private boolean allowFileEmbed(String uri, ExternalResourceType type) {
  if (type == null) {
    return false;
  }
  switch (type) {
    case BINARY:
    case CSS:
    case FONT:
    case IMAGE_RASTER:
    case XML_XHTML:
    case XML_SVG:
    case PDF:
    case SVG_BINARY:
    case FILE_EMBED:
      return true;
  }
  return false;
}

Then you provide it to your builder for both priorities:

builder.useExternalResourceAccessControl(
  MyCustomResourceAccessController::allowFileEmbed, 
  ExternalResourceControlPriority.RUN_BEFORE_RESOLVING_URI);
builder.useExternalResourceAccessControl(
  MyCustomResourceAccessController::allowFileEmbed,
  ExternalResourceControlPriority.RUN_AFTER_RESOLVING_URI);

Keep in mind it's a potential attack vector and a very easy one to exploit so sanitize your files before you embed them.