HTTP Webserver Details

Custom HTTP Status codes (Apache)

For live presentations a request for a media fragment may result in one of the following errors (depending on the time of the media and the current state of the available DVR window):

Error Description
Fragment Not Found The requested fragment is older than the first fragment available in the DVR window.
Fragment Missing The requested fragment is missing from the DVR window.
Fragment Not Available The requested fragment is newer than the last fragment available in the DVR window.

You can customize the following status codes returned by the webserver module for live presentations. Note that this is customized per playout format.

Configuration key HTTP status code
Fmp4IssFragmentNotFound 404
Fmp4IssFragmentMissing 412
Fmp4IssFragmentNotAvailable 412
Fmp4HdsFragmentNotFound 404
Fmp4HdsFragmentMissing 503
Fmp4HdsFragmentNotAvailable 503
Fmp4HlsFragmentNotFound 404
Fmp4HlsFragmentMissing 404
Fmp4HlsFragmentNotAvailable 404
Fmp4MpdFragmentNotFound 410
Fmp4MpdFragmentMissing 404
Fmp4MpdFragmentNotAvailable 404

The customization in Apache is specified on a per-directory (including sub directories) basis using the Directory tag. An example Apache configuration (using the defaults):

<Directory "/var/www/live/usp_test/video/errors_rewrite">
  Fmp4IssFragmentNotFound 404
  Fmp4IssFragmentMissing 412
  Fmp4IssFragmentNotAvailable 412

HTTP Response Headers

Changed in version 1.10.4.

USP distinguishes two cases: VOD and live. Unified Origin only sets any response headers when they are applicable and there is no (feasible) way to set them with regular means (like mod_headers). For instance, only the live origin knows when a fragment is going to expire based on real-time information and DVR window settings. But for VOD contents, where no intrinsic expiration constraints exist, we do not insert default values and so that Cache-Control and/or Expires headers can be customized in webserver configuration.

Last Modified Time

For VOD the Last-Modified header is always set to the last modified time of the server manifest file (.ism). Note that this applies to the manifest/playlist files as well as any fragments/segments.

For live the Last-Modified time is set to:

  • the modification time of the server manifest (.isml) for client manifest, master playlist and initialization segments
  • the time of ingest of the fragment with the highest timestamp for media playlists
  • the time of ingest of the fragment (for fragments)


Changed in version 1.10.4.

Both VOD and live have an ETag value that is a hash of URL's response content. Depending on the request, the hashed data comprises the manifests or generated MP4 data, but excludes the (static) elementary stream (media data). The ETag changes only when the payload changes (for example as a result real-time changes, dynamic filtering or playout control) and If-None-Match yields 304 only if nothing changed.

Expires and Cache-Control: max-age="..."

Changed in version 1.10.4.

For VOD no Cache-Control or Expires headers are set.

For live the Cache-Control and Expires are set to:

  • dynamic manifests like HLS media playlists expire when a new segment is expected to be ingested (the sum of the last fragment's ingest time and its duration)
  • fragments are set to expire when they leave the DVR window
  • fragments near the live edge expire when new revisions become available as a result of timing information in successive 'lookahead_fragments'
  • for static manifests like HLS master playlist and contents outside the DVR window no Cache-Control or Expires headers are set

Note that requests requests beyond the DVR window (but still within the archive) would technically have negative max-age, since they have already expired, but in this case, no Cache-Control or Expires headers are set.

Prior versions of Unified Origin had different behaviour and would always expire at least 1 second ahead of request time, which mitigated instantly flushing a downstream (CDN) cache.

Unfortunately, always setting the headers obfuscated the origin's intentional header logic. It also violated the principle to only add headers when there isn't a better mechanism to do so, making it harder to insert custom values (with mod_headers or mod_expires).

To configure the old behaviour, enable Apache mod_expires and add following to the web configuration:

ExpiresActive On
ExpiresByType "video/mp4"  "A1"
ExpiresByType "video/MP2T" "A1"

or simply:

ExpiresActive On
ExpiresDefault "access plus 1 second"

For more info, see:

Starting and stopping Apache

There are a couple of ways to stop, start or restart Apache, which are described here.

Please note that a restart (signal: HUP) will stop all connections, incoming and outgoing.

A 'graceful restart' (signal: USR1) will not, so outgoing streams continue. However, a Live ingest (the encoder POSTing to the publishing point) will stop, even with a graceful restart. There is no way to reset Apache and keep the ingest intact.


Please note that logrotate will reset all connections, as it does a restart of Apache. This might cause a problem with a Live ingest.

There are two ways to address this:

  • turn off log rotation for the ingest (the encoder POST will only log when it ends, so the logging is minimal anyway)
  • use rotatelogs.