<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 
<base href="https://wiki.asterisk.org/wiki" /> 
<title>Message Title</title>  
<style type="text/css">@media only screen and (max-device-width: 480px) {.mobile-only {
        width: auto !important;
        height: auto !important;
        overflow: visible !important;
        line-height: normal !important;
        font-size: inherit !important;
        mso-hide: all;
}

.desktop-only {
        display: none !important;
}

/* iPhone 3GS fix for unwanted 20px right margin */
body { min-width: 100% !important; padding: 0; margin: 0; }

#center-content-table { max-width: none; !important; }
#header-pattern-container { padding: 10px 10px 10px 10px !important; line-height: 20px !important; }
#header-avatar-image-container { padding-right: 8px !important; }
#email-content-container { padding: 0 !important; }
.mobile-expand { border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; padding-left: 26px !important;}
.mobile-resize-text { font-size: 16px !important; line-height: 22px !important; }
#page-title-pattern-header { font-size: 20px !important; line-height: 28px !important; }
#page-title-pattern-icon-image-container-cell { padding-top: 7px !important; }
#inline-user-pattern { display: block !important; }
#inline-user-pattern-avatar { padding-top: 3px !important; }
.contextual-area-pattern { border-bottom: 1px solid #ccc !important; padding: 15px 10px 0 10px !important;}
.users-involved-pattern-column-table { width: 100% !important;  }
.users-involved-pattern-avatar-table-cell { padding: 3px 5px 5px 0 !important; }
.users-involved-pattern-column-container { padding-right: 0 !important; }
.contextual-excerpt-pattern, #users-involved-pattern { border: 0 !important; }

/** Aui Typography upsized for mobile **/
#content-excerpt-pattern-container, #contextual-excerpt-pattern-text-container { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h1, #contextual-excerpt-pattern-text-container h1 { font-size: 24px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h2, #contextual-excerpt-pattern-text-container h2 { font-size: 20px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h3, #contextual-excerpt-pattern-text-container h3 { font-size: 18px !important; line-height: 24px !important; }
#content-excerpt-pattern-container h4, #contextual-excerpt-pattern-text-container h4 { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h5, #contextual-excerpt-pattern-text-container h5 { font-size: 14px !important; line-height: 20px !important; }
#content-excerpt-pattern-container h6, #contextual-excerpt-pattern-text-container h6 { font-size: 14px !important; line-height: 20px !important; }
.user-mention { line-height: 18px !important; }
/** Aui Typography end **/

/* Show appropriate footer logo on mobile, display links vertically */
#footer-pattern { padding: 15px 10px !important; }
#footer-pattern-logo-desktop-container { padding: 0 !important; }
#footer-pattern-logo-desktop { width: 0 !important; height: 0 !important; }
#footer-pattern-logo-mobile {
    padding-top: 10px !important;
    width: 30px !important;
    height: 27px !important;
    display: inline !important;
}
#footer-pattern-text {
    display: block !important;
}
#footer-pattern-links-container { line-height: 0 !important;}
.footer-pattern-links.mobile-resize-text,
.footer-pattern-links.mobile-resize-text,
#footer-pattern-text.mobile-resize-text,
#footer-pattern-links-container.no-footer-links {
    font-size: 14px !important;
    line-height: 20px !important;
}
.footer-link { display: block !important; }
#footer-pattern-links-container table { display: inline-block !important; float: none !important; }
#footer-pattern-links-container, #footer-pattern-text { text-align: center !important; }
#footer-pattern-links { padding-bottom: 5px !important; }

/** Team Calendar overrides, these should be removed when notifications are updated in Team Calendars. For now CSS
    overrides are being used because the structure of the content can't change without rereleasing the plugin */
.mail-calendar-container .day-header + table tr td:first-child {
    vertical-align: top !important;
    padding-top: 5px !important;
}}
@media (min-width: 900px) {#center-content-table { width: 900px; }}
@media all {#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
body{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
#background-table {margin:0; padding:0; width:100% !important; }
/* Needed to override highlighting on date and time links in iOS */
.grey a {color: #707070; text-decoration: none; }/* These styles are appended to the head element of a notification in order to prevent Apple Mail and similar
   clients from underlining the due dates with a blue hyperlink */
/* a lozenge outside an inline task should always be #333, lozenges inside an inline task should be
   colored according to their upcoming due dates, a completed task date lozenge or deleted task date
   lozenge should always be #707070 */
.date-time-lozenge a {color: #333333; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-upcoming a {color: #DF6F00; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-past a {color: #D04437; text-decoration: none; }
.inline-task-text-container.content-deleted-color .date-time-lozenge a,
.inline-task-text-container.checked .date-time-lozenge a {
    color: #707070; text-decoration: none;
}}
</style> 
</head>
<body>
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; background-color: #f5f5f5"> 
<tbody> 
<tr> 
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px"> 
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 9px"><a href="https://wiki.asterisk.org/wiki/display/~mjordan?src=email" style="color: #3b73af; text-decoration: none"><img id="header-avatar-image" class="image_fix" src="cid:avatar_ce51dcf276530e4a4b00548e2a6d0905" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /></a></td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">Matt Jordan <strong>edited</strong> a page</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<!-- End Header pattern --> 
<tr> 
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px"> 
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-spacing: 0; border-collapse: separate"> 
<tbody> 
<tr> 
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px"> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table id="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container" valign="top" style="padding: 0px; border-collapse: collapse; width: 16px; vertical-align: top"> 
<table cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container-cell" style="padding: 0px; border-collapse: collapse; width: 16px; padding: 9px 8px 0px 0px; mso-text-raise: 5px; mso-line-height-rule: exactly"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="page icon" style="vertical-align: top;; color: #3b73af; text-decoration: none"><img style="vertical-align: top; display: block;" src="cid:page-icon" alt="page icon" title="page icon" height="16" width="16" border="0" /></a></td> 
</tr> 
</tbody> 
</table> </td>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" id="page-title-pattern-header-container"><span id="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="Asterisk 14 Project - URI Media Playback" style="color: #3b73af; text-decoration: none">Asterisk 14 Project - URI Media Playback</a></span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table class="content-excerpt-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td class="content-excerpt-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 0 24px"> 
<div class="contentLayout2 diff-block-target"> 
<table width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody>
<tr class="columnLayout two-right-sidebar" data-layout="two-right-sidebar"> 
<td valign="top" class="cell normal" data-type="normal" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<h1 id="Asterisk14Project-URIMediaPlayback-ProjectOverview" style="margin: 10px 0 0 0; margin-top: 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 0">Project Overview</h1> 
<p style="margin: 10px 0 0 0">One of the features that was discussed for the <a class="confluence-link unresolved" href="#" style="color: #3b73af; text-decoration: none">Asterisk 13 Projects</a> was the ability to playback media from a URI to a channel or bridge. See <a href="http://lists.digium.com/pipermail/asterisk-app-dev/2014-April/000425.html" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">http://lists.digium.com/pipermail/asterisk-app-dev/2014-April/000425.html</a> for more information.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">The conversation on the mailing list included both playback of a URI, as well as allowing for a unicast stream of media to be injected into a channel/bridge. At this time, that would be considered a separate project from this one.</p> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">The primary reason to add this feature is scalability. Allowing sounds to be placed on a remote HTTP server allows a cluster of Asterisk servers to access and pull down the sounds as needed. This is much easier for system administration, as the sounds don't have to all be pushed to individual Asterisk machines.</p> 
<h1 id="Asterisk14Project-URIMediaPlayback-RequirementsandSpecification" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Requirements and Specification</h1> 
<h3 id="Asterisk14Project-URIMediaPlayback-Extensions" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Extensions</h3> 
<p style="margin: 10px 0 0 0">Normally, Asterisk eschews usage of a file extension and instead picks the best extension available based on the native formats of the channel. In the case of a remote URI, this impractical as the URI represents a unique location to retrieve. The optimal file extension may not be present, and checking for each file extension may be costly.</p> 
<p style="margin: 10px 0 0 0">As such, the extension should be provided of the resource to retrieve; however, that may not result in a playable file depending on the channel formats. That is expected behaviour.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-URISchemes" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">URI Schemes</h3> 
<p style="margin: 10px 0 0 0">Playback of a remote URI should support both HTTP and HTTPS.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-Caching" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Caching</h3> 
<p style="margin: 10px 0 0 0">When a sound file has been retrieved, it should be cached on the local server. The timestamp of the file on the server (retrieved using <code style="font-family: monospace">cURL</code> <code style="font-family: monospace">CURLINFO_FILETIME</code> ) should be cached with the file. When a playback attempts to play a URI, the timestamp on the server should be checked. If the timestamp on the server is the same as what is on the local file system, the cached version of the file should be played back instead.</p> 
<p style="margin: 10px 0 0 0">CLI commands <span class="diff-html-removed" id="removed-diff-0" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">, AMI actions, </span>and an ARI resource should be provided to view the local cached files, their timestamps, and their originating URIs. Similar mechanisms should be provided to flush the entire cache.</p> 
</div> </td> 
<td valign="top" width="30%" class="cell aside" data-type="aside" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<p style="margin: 10px 0 0 0; margin-top: 0"></p> 
<table class="diff-macro bodyless" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/toc.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Table of Contents</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">maxlevel</td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">3</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"></p> 
</div> </td> 
</tr> 
</tbody>
</table> 
<table width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody>
<tr class="columnLayout single" data-layout="single"> 
<td valign="top" class="cell normal" data-type="normal" style="padding: 0px; border-collapse: collapse"> 
<div class="innerCell"> 
<h3 id="Asterisk14Project-URIMediaPlayback-Video" style="margin: 10px 0 0 0; margin-top: 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 0">Video</h3> 
<p style="margin: 10px 0 0 0">Video is particularly difficult, as it typically requires multiple files (one video, one audio) to be useful. Container formats are beyond the scope of this project. To support video, remote playback of URIs should support a parallel form of extraction using the pipe <code style="font-family: monospace">|</code> character:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.h264|http://myserver.com/monkeys.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">The behaviour of the files retrieved in such a fashion are as follows:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>Playback does not begin until all files are retrieved.</li> 
<li>Files are treated individually in the cache.</li> 
<li>While files with different names can be played back, the first file in the parallel list will be the actual "core sound file" played back. That is, assuming <code style="font-family: monospace">monkeys.h264</code> and <code style="font-family: monospace">monkeys.wav</code> already existed on the server, the <code style="font-family: monospace">Playback</code> operation would operate on sound file <code style="font-family: monospace">monkeys</code>, which would play both the audio and video files.</li> 
</ul> 
<h3 id="Asterisk14Project-URIMediaPlayback-PlaybackofaURI" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Playback of a URI</h3> 
<p style="margin: 10px 0 0 0">Playback of a URI can be done via any of the supported playback operations, through any API. This functionality should be a part of the Asterisk core, and available through any of the media playback operations.</p> 
<h5 id="Asterisk14Project-URIMediaPlayback-Dialplan" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">Dialplan</h5> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that this can be combined with multiple URIs or sounds to form a playlist:</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Playback(http://myserver.com/monkeys.wav&http://myserver.com/weasels.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Since an <code style="font-family: monospace">&</code> is valid for a URI but is also used as a separator in dialplan, ampersands in a URI cannot be supported.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">We cannot URI encode the ampersands, as a URI decode would not be able to tell the difference between the ampersands encoded for the purposes of multiple file playback and ampersands encoded as they are part of the non-query portion of the URI.</p> <p style="margin: 10px 0 0 0">Escaping things tends to lead to more errors, so unless we really need query parameters in a URI, we should probably avoid it for now.</p> </td> 
</tr> 
</tbody> 
</table> 
<h5 id="Asterisk14Project-URIMediaPlayback-AGI" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">AGI</h5> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">CONTROL STREAM FILE http://myserver.com/monkeys.wav "" 3000</pre> </td> 
</tr> 
</tbody> 
</table> 
<h5 id="Asterisk14Project-URIMediaPlayback-ARI" style="margin: 10px 0 0 0; color: #707070; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">ARI</h5> 
<p style="margin: 10px 0 0 0">Playback can be done on either a channel or a bridge. Since the resource being requested is a URI, it should be presented in the body of the request encoded using <code style="font-family: monospace">text/uri-list</code> (see <a href="https://www.ietf.org/rfc/rfc2483.txt" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">RFC 2483</a>)<span class="diff-html-added" id="added-diff-0" style="font-size: 100%; background-color: #ddfade;">. Note that we still need to provide a media query parameter that specifies the resource type to play - the actual 'entity' being played back is simply specified in the body of the request.</span> </p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">http://localhost:8088/ari/channels/12345/play/p1<span class="diff-html-added" id="added-diff-1" style="font-size: 100%; background-color: #ddfade;">?media=uri:list</span>

Content-Type: text/uri-list
http://myserver.com/monkeys.wav</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">This format works nicely with video files, as it can specify multiple files to retrieve. <span class="diff-html-removed" id="removed-diff-1" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Playback can then occur in the fashion previously described.</span><span class="diff-html-added" id="added-diff-2" style="font-size: 100%; background-color: #ddfade;">Note that these files should be played back sequentially as a playlist (which is not yet supported, but hopefully will be by the time we get here!)</span> </p> 
<span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">It may be useful to also have a JSON style payload for this. Currently, having a JSON payload that specified URIs to retrieve doesn't add any value over the </span> 
<table class="diff-macro diff-html-removed" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ffe7e7;border-color: #df9898;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">http://localhost:8088/ari/channels/12345/play/p2<span class="diff-html-added" id="added-diff-3" style="font-size: 100%; background-color: #ddfade;">?media=uri:list</span>

Content-Type: text/uri-list
# Audio
http://myserver.com/monkeys.wav
# Video
http://myserver.com/monkeys.h264</pre> </td> 
</tr> 
</tbody> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-removed" id="removed-diff-2" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</span></th> 
</tr> 
</thead> 
</table> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" id="added-diff-4" style="font-size: 100%; background-color: #ddfade;">Note that when the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Content-Type</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> is </span><code style="font-family: monospace"><span class="diff-html-changed" id="changed-diff-0" style="background-color: #d6f0ff;">text/uri-list</span></code> </p> 
<span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span> 
<span class="diff-html-removed" id="removed-diff-3" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">content type; however, if we eventually support a playlist (which is something that </span> 
<em><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">really</span></em> 
<span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> needs to happen), the you may want to specify sequential URIs to play, or URIs mixed with other sounds. Since those other sounds would typically be given as query parameters, you'd ideally want a body that expressed the entire playlist.</span> 
<br /> 
<span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Once playlist happen, this document should be updated with a way to express URIs in such a scheme</span> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" id="added-diff-5" style="font-size: 100%; background-color: #ddfade;">, the resource specified by the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">uri</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> media scheme is simply tossed away, as we can only have a single list of URIs. Note that this approach is somewhat limiting in that supporting multiples</span> </p> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Another option is to provide the URIs in JSON. This would allow parallel playback of files for video support. Note that the JSON must follow the following schema:</span> </p> 
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">http://localhost:8088/ari/channels/12345/play/p3

{
    "media": "playlist",
    "playlist": [
                  { "media_group": [
                              {
                                "scheme": "uri",
                                "resource": "http://myserver.com/monkeys.wav"
                              },
                              {
                                "scheme": "uri",
                                "resource": "http://myserver.com/monkeys.h264"
                              }
                            ]
                          }
                 { "media_group": [
                              { "scheme": "uri",
                                "resource": "http://myserver.com/awesome-sound.wav",
                              }
                            ]
                          }
                ]
}
    </span>
</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">There's some obvious differences here:</span> </p> 
<ol style="margin: 10px 0 0 0"> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">schema</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> type </span><strong><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">must</span></strong><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> be </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">playlist</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">. We can't use a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">uri</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> schema type, as doing so would prevent combining </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">URI</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> resources with other media resource types for playlists.</span> </li> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The playlist must be strongly typed. Otherwise, swagger code generation turns into a nightmare. As such, that means a new strongly named body parameter must be used</span><span class="diff-html-changed" id="changed-diff-1" style="background-color: #d6f0ff;">.</span> </li> 
</ol> 
<h1 id="Asterisk14Project-URIMediaPlayback-Configuration" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Configuration</h1> 
<p style="margin: 10px 0 0 0">No configuration should be needed.</p> 
<h1 id="Asterisk14Project-URIMediaPlayback-Design" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Design</h1> 
<h2 id="Asterisk14Project-URIMediaPlayback-func_curl" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">func_curl</h2> 
<h3 id="Asterisk14Project-URIMediaPlayback-FileRetrieval" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 10px">File Retrieval</h3> 
<p style="margin: 10px 0 0 0">The <code style="font-family: monospace">CURL</code> function should be updated to be able to retrieve files. This allows other portions of Asterisk to use the underlying <code style="font-family: monospace">func_curl</code> implementation to actually retrieve files, which keeps the cURL-ing of data co-located. Currently, any resource pulled using <code style="font-family: monospace">CURL</code> is stored as a string in the dialplan ... which doesn't work well for sound files for obvious reasons. The <code style="font-family: monospace">CURL</code> function also uses a read operation to retrieve data, which is somewhat odd since we are retrieving a resource. In order to not break backwards compatibility, a write function will be added that stores the information as the specified file.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">Writing a file to an arbitrary location specified by the dialplan is dangerous for obvious reasons. The write function should only be enabled for direct access by external actors if <code style="font-family: monospace">live_dangerously</code> is set to True. Some tweaking may be necessary to make remote sound file playbacks work, since the file location is provided by the actual system even though the thread servicing the request is from an external actor.</p> </td> 
</tr> 
</tbody> 
</table> 
<h4 id="Asterisk14Project-URIMediaPlayback-Usage" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">Usage</h4> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Set(CURL(http://myserver.com/sounds/awesome-sauce.wav)=/var/spool/asterisk/tmp/awesome-sauce.wav)</pre> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-TimestampRetrieval" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Timestamp Retrieval</h3> 
<p style="margin: 10px 0 0 0">In order to know whether or not we need to update a cached file, we will look at the timestamp on the remote file and compare it to the local timestamp. To do that, <code style="font-family: monospace">func_curl</code> needs to be updated to allow for retrieval of the timestamp of the remote resource.</p> 
<p style="margin: 10px 0 0 0"> <code style="font-family: monospace">CURL_OPT</code> will be updated with a new boolean option, <code style="font-family: monospace">timestamp</code>. If set to boolean <code style="font-family: monospace">True</code>, then the next invocation of the <code style="font-family: monospace">CURL</code> function will not retrieve the resource, but rather the timestamp of that resource. Setting it to <code style="font-family: monospace">False</code> will once again retrieve the requested resource.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">For threading issues, a dummy channel will need to be provided to the invocation of <code style="font-family: monospace">CURL_OPT</code> and <code style="font-family: monospace">CURL</code>. Otherwise, a global data store is used, which would be bad for multiple Playback calls for obvious reasons. The dummy channel will act as a datastore for the <code style="font-family: monospace">CURL_OPT</code> values and - when provided to <code style="font-family: monospace">CURL</code> - will cause the <code style="font-family: monospace">CURL</code> function to use the dummy channel's datastore instead of the global datastore.</p> </td> 
</tr> 
</tbody> 
</table> 
<h4 id="Asterisk14Project-URIMediaPlayback-Usage.1" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0">Usage</h4> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">same => n,Set(CURL_OPT(timestamp)=True)
same => n,NoOp(${CURL(http://myserver.com/monkeys.wav)}) ; Output the time monkeys.wav was updated
same => n,Set(CURL_OPT(timestamp)=False)</pre> </td> 
</tr> 
</tbody> 
</table> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-http_media_cache" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Core - http_media_cache</h2> 
<p style="margin: 10px 0 0 0">This new file in the Asterisk core will provide the actual HTTP caching of the cURL'd media. It should wrap the <code style="font-family: monospace">bucket</code> API, providing schema wizards for <code style="font-family: monospace">http</code> and <code style="font-family: monospace">https</code>, and associate saved files with the URI in the bucket. The timestamp of the resource should be stored in the bucket. If a request for the item in the HTTP cache occurs, the version referenced by the bucket should be used unless:</p> 
<ol style="margin: 10px 0 0 0"> 
<li>It does not exist.</li> 
<li>The remote resource's timestamp is later.</li> 
</ol> 
<p style="margin: 10px 0 0 0">In either case, the remote resource should be retrieved, stored in the cache, and returned.</p> 
<p style="margin: 10px 0 0 0">Note that while the concept of an HTTP cache could be used for a variety of purposes, having it specifically for media allows us to use it from the <code style="font-family: monospace">app</code> and <code style="font-family: monospace">file</code> APIs without worrying about what might be stored in the cache.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-API" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">API</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*
 * \brief Return whether or not a URI is currently stored in the cache
 *
 * \param uri The URI to the resource to query
 *
 * \retval 0 The item is not in the cache
 * \retval 1 The item is in the cache
 */
int ast_http_media_cache_exists(const char *uri);

/*
 * \brief Retrieve media from a URI or in the cache
 *
 * \param preferred_file_name If not yet retrieved from the remote server, use the preferred file name
 *                            for the media file. Note that this does not include the extension of the
 *                            file, if any.
 * \param file_path Buffer to hold the location of the media on the local file system, minus the extension
 * \param len Length of \c file_path
 *
 * \retval 0 on success
 * \retval -1 on error
 */
int ast_http_media_cache_retrieve(const char *uri, const char *preferred_file_name, char *file_path, size_t len);

/*
 * \brief Remove an item from the cache
 *
 * \param uri The item to remove
 *
 * \retval 0 success
 * \retval -1 error
 */
int ast_http_media_cache_delete(const char *uri);</pre> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-CLICommands" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">CLI Commands</h3> 
<h4 id="Asterisk14Project-URIMediaPlayback-httpshowcache" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0; margin-top: 10px"> <span class="diff-html-added" id="added-diff-6" style="font-size: 100%; background-color: #ddfade;">http show cache</span> </h4> 
<p style="margin: 10px 0 0 0">Just for fun! It'd be good to see what is in the cache, the timestamps, etc.</p> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">*CLI>http show cache

URI                                  Last update                Local file
http://myserver.com/awesome.wav      2014-10-30 00:52:25 UTC    /var/spool/asterisk/http_cache/ahsd98d1.wav
http://myserver.com/monkeys.wav      2014-09-14 10:10:00 UTC    /var/spool/asterisk/http_cache/77asdf7a.wav
http://myserver.com/monkeys.h264     2014-09-14 10:10:00 UTC    /var/spool/asterisk/http-cache/77asdf7a.h264 <span class="diff-html-added" id="added-diff-7" style="font-size: 100%; background-color: #ddfade;">

3 items found.</span>
</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0">Note that the last two files would have been created using a preferred file prefix. This allow the <code style="font-family: monospace">file</code> and <code style="font-family: monospace">app</code> core to "find" both the audio and the video file when opening up the stream returned by the <code style="font-family: monospace">file_path</code> by the <code style="font-family: monospace">http_media_cache</code>.</p> 
<h4 id="Asterisk14Project-URIMediaPlayback-httpclearcache" style="margin: 10px 0 0 0; font-size: 14px; line-height: 20px; margin: 20px 0 0 0"> <span class="diff-html-added" id="added-diff-8" style="font-size: 100%; background-color: #ddfade;">http clear cache</span> </h4> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">This is really a handy way for a system administrator to force files to be pulled down.</span> </p> 
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">*CLI>http clear cache

3 items purged.

*CLI>http show cache

URI                                  Last update                Local file
0 items found.</span>
</pre> </td> 
</tr> 
</tbody> 
</table> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-Usageofast_openstream" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Core - Usage of ast_openstream</h2> 
<p style="margin: 10px 0 0 0">Prior to call <code style="font-family: monospace">ast_openstream</code>, users who want to support URI playback should first:</p> 
<ul style="margin: 10px 0 0 0"> 
<li>Determine if the provided "file" is actually a URI. A simple 'strncmp' is sufficient for this.</li> 
<li>If so, ask the cache for the actual file. Use that for subsequent calls to <code style="font-family: monospace">ast_openstream</code> and <code style="font-family: monospace">ast_openvstream</code>.</li> 
<li>If not, move on as normal.</li> 
</ul> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/note.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Note</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">There are other callers of <code style="font-family: monospace">ast_openstream</code>, but it's probably not worth updating <code style="font-family: monospace">ExternalIVR</code> (sorry <img class="emoticon emoticon-sad" src="/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/emoticons/sad.png" data-emoticon-name="sad" alt="(sad)" style="vertical-align: middle" />)</p> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-Core-file.c::ast_streamfile" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">Core - file.c::ast_streamfile</h3> 
<p style="margin: 10px 0 0 0">This covers most functionality, as most dialplan applications (and other things) end up calling <code style="font-family: monospace">ast_streamfile</code>.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-AGI-res_agi.c::handle_streamfile|handle_getoption" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">AGI - res_agi.c::handle_streamfile | handle_getoption</h3> 
<p style="margin: 10px 0 0 0">AGI implementations of basic sound playback, which emulate their dialplan counterparts. These will need to be updated in the same way as <code style="font-family: monospace">ast_streamfile</code>.</p> 
<h2 id="Asterisk14Project-URIMediaPlayback-Core-HTTPserver" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Core - HTTP server</h2> 
<p style="margin: 10px 0 0 0">Support for a new Content-Type, <code style="font-family: monospace">text/uri-list</code>, needs to be added to the HTTP server. Since we typically parse the body as JSON using <code style="font-family: monospace">ast_http_get_json</code>, this should be a new public function <code style="font-family: monospace">ast_http_get_uri_list</code> that pulls a body as a <code style="font-family: monospace">text/uri-list</code>. Since we now have core support for URIs, a bit of basic support for a list of URIs should be added to <code style="font-family: monospace">uri.h</code> and used by the HTTP server.</p> 
<h3 id="Asterisk14Project-URIMediaPlayback-http.h" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">http.h</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Get the text/uri-list body of a request
 *
 * \param ser TCP/TLS session object
 * \param headers List of HTTP headers
 *
 * \retval NULL on error or a body not encoded as text/uri-list
 * \retval A list of URIs. This an ao2 object that must be disposed of by the caller of the function.
 */
struct ast_uri_list *ast_http_get_uri_list(struct ast_tcptls_session_instance *ser, struct ast_variable *headers);</pre> </td> 
</tr> 
</tbody> 
</table> 
<h3 id="Asterisk14Project-URIMediaPlayback-uri.h" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0">uri.h</h3> 
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*!
 * \brief Get the string representation of a URI
 *
 * \param The URI
 *
 * \retval The string representation of the URI.
 */
const char *ast_uri_to_string(struct ast_uri *uri);

struct ast_uri_list;
struct ast_uri_list_iterator;

/*!
 * \brief Create a URI list
 *
 * \retval A new \c ast_uri_list on success. This is an ao2 object.
 * \retval NULL on error
 */
struct ast_uri_list *ast_uri_list_create(void);

/*!
 * \brief Append a \c ast_uri to a \c ast_uri_list
 *
 * \param uri The \c ast_uri to append
 */
void ast_uri_list_append(struct ast_uri *uri);

/*!
 * \brief Create an iterator for a \c ast_uri_list
 *
 * \param uri_list The \c ast_uri_list to iterate over
 *
 * \retval A \c ast_uri_list_iterator on success
 * \retval NULL on error
 */
struct ast_uri_list_iterator *ast_uri_list_iterator_create(struct ast_uri_list *uri_list);

/*!
 * \brief Dispose of a \c ast_uri_list_iterator
 *
 * \param iterator The \c ast_uri_list_iterator to destroy
 */
void ast_uri_list_iterator_destroy(struct ast_uri_list_iterator *iterator);

/*!
 * \brief Retrieve the next \c ast_uri in an \c ast_uri_list
 *
 * \param iterator The \c ast_uri_list_iterator for the list
 *
 * \retval NULL if no more items in the list
 * \retval The next \c ast_uri otherwise
 */
struct ast_uri *ast_uri_list_iterator_next(struct ast_uri_list_iterator *iterator);</pre> </td> 
</tr> 
</tbody> 
</table> 
<h2 id="Asterisk14Project-URIMediaPlayback-ARI.1" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" id="added-diff-9" style="font-size: 100%; background-color: #ddfade;">ARI</span> </h2> 
<h3 id="Asterisk14Project-URIMediaPlayback-SwaggerSchema" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0; margin-top: 10px"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Swagger Schema</span> </h3> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Providing a 'type' for the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">media</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> parameter is a bit tricky. We have the following situation:</span> </p> 
<ul style="margin: 10px 0 0 0"> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">If the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">media</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> parameter does not specify a resource type of </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">uri</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">, treat it as a string.</span> </li> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">If the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">media</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> parameter does specify a resource type of </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">uri</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">, look to the body as a URI list.</span> </li> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">If the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">media</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> parameter is in the body, however, it must be of type </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">string</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">. Hence, we cannot specify the URIs directly in the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">media</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> parameter. Thus, to specify URIs, a body parameter of </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">playlist</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> must be provided.</span> </li> 
</ul> 
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">playbacks.json</span></td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">language</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">js</span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">    "models": {
        "Playback": {
        ...
        }
        "MediaResource": {
            "id": "MediaResource",
            "description": "A single media resource to operate on",
            "properties": {
                "scheme": {
                    "type": "string",
                    "description": "The type for this media resource.",
                    "required": true
                },
                "resource": {
                    "type": "string",
                    "description": "The actual media resource to manipulate.",
                    "required": true
                }
            }
        }
        "MediaGroup": {
            "id": "MediaGroup",
            "description": "One or more MediaResources that are associated together as a logical unit",
            "properties": {
                "media_group": {
                    "type": "array",
                    "description": "Array of MediaResources to treat as a single logical unit",
                    "required": true,
                    "items": {
                        "$ref": "MediaResource"
                    }
                 }
            }
        }   
        "Playlist": {
            "id": "Playlist",
            "description": "One or more MediaGroups to play sequentially",
            "properties": {
                "playlist": {
                    "type": "array",
                    "description": "Array of MediaGroups to play sequentially",
                    "required": true,
                    "items": {
                        "$ref": "MediaGroup"
                    }
                 }
             }
        }
    }</span><span class="diff-html-changed" id="changed-diff-2" style="background-color: #d6f0ff;"> </span>
</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" id="added-diff-10" style="font-size: 100%; background-color: #ddfade;">Note that the following for </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">channels.json</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> would be repeated for </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">bridges.json</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">:</span> </p> 
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse"> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">channels.json</span></td> 
</tr> 
<tr> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">language</span></td> 
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">js</span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">        {
            "path": "/channels/{channelId}/play",
            "description": "Play media to a channel",
            "operations": [
                {
                    "httpMethod": "POST",
                    "summary": "Start playback of media.",
                    "notes": "The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, uri:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)",
                    "nickname": "play",
                    "responseClass": "Playback",
                    "parameters": [
                        ...
                        {
                            "name": "playlist",
                            "description": "A play list to play.",
                            "paramType": "body",
                            "required": false,
                            "allowMultiple": false,
                            "$ref": "Playlist"
                        }
                    ],
                    "errorResponses": [
                        {
                            "code": 404,
                            "reason": "Channel not found"
                        },
                        {
                            "code": 409,
                            "reason": "Channel not in a Stasis application"
                        }
                    ]
                }
            ]
        }, </span>
</pre> </td> 
</tr> 
</tbody> 
</table> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> </span> </p> 
<h3 id="Asterisk14Project-URIMediaPlayback-MustacheTemplates" style="margin: 10px 0 0 0; font-size: 16px; line-height: 25px; margin: 30px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Mustache Templates</span> </h3> 
<p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The Mustache templates generated will need to be modified to check for </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">text/uri-list</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> as a possible body type:</span> </p> 
<ul style="margin: 10px 0 0 0"> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The existing </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">body_parsing.mustache</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> should be renamed to note that it parses JSON. The caller of the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">body_parsing</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> routines should be made to only look at the results if the function returns non-NULL.</span> 
<ul style="margin: 10px 0 0 0"> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">If it does return NULL, it should also check for a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">text/uri-list</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> using the new function in </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">http.h</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">.</span> </li> 
</ul> </li> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">A new </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">text_uri_body_parser</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> should be added that parses a body into a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">struct ast_uri_list</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">.</span> </li> 
<li> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">This is where it gets a bit tricky. The existing JSON parsers that are auto-generated are able to perform their duty as they </span><strong><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">know</span></strong><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> how the query parameters are typed in the body, and that </span> </li> 
</ul> 
<h1 id="Asterisk14Project-URIMediaPlayback-TestPlan" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Test Plan</h1> 
<h2 id="Asterisk14Project-URIMediaPlayback-UnitTests" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">Unit Tests</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Category</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Test</th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold">Description</th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/exists</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Nominal test that verifies a valid item in the cache can be found</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">non_existent</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test that verifies that an item in the cache that doesn't exist isn't located</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_scheme</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we reject a URI with an unknown or unsupported scheme</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/exists</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_params</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Pass in bad parameters, make sure we get back a "huh?"</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Retrieve a file from the Asterisk HTTP server (using magic!) and make sure it is in the cache. Retrieve it again and make sure we didn't do an HTTP request twice.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">non_existent</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for a file that doesn't exist. Get an error back.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_scheme</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for something that has a bad URI scheme.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">bad_params</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for something with no URI and no file_path. Make sure we reject it.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">new_file</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Retrieve a media file, cache it. Update the file, ask for the file again; make sure it gets the new copy.</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/retrieve</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">preferred_file_name</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Ask for a file with a preferred file name; verify that we retrieve the file and set the file name accordingly (with the right extension).</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/delete</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Put something in the cache. Call delete; verify the cache is purged.</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/http_media_cache/empty</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">nominal</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Call delete on an empty cache; make sure everything is cool.</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">to_string</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test that a constructed URI can be converted back to a string</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_ctor</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can make a URI list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_append_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test appending URIs to a list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">list_append_off_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test appending things that aren't a URI, and make sure we fail appropriately</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_ctor</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test nominal creation of an iterator</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_ctor_off_nominal</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test off-nominal creation of an iterator with a bad list</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">/main/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">iterator_iteration</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Test nominal iteration over lists. Include empty lists.</td> 
</tr> 
</tbody> 
</table> 
</div> 
<h2 id="Asterisk14Project-URIMediaPlayback-AsteriskTestSuite" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Asterisk Test Suite</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Test</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Level</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Description</p> </th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <code style="font-family: monospace">funcs/func_curl/read</code> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">Asterisk Test Suite</p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">A regression test that verifies that the current read functionality of <code style="font-family: monospace">CURL</code> is maintained</p> </td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <code style="font-family: monospace">funcs/func_curl/write</code> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0">Asterisk Test Suite</p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can cURL a file down and store it</td> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">funcs/func_curl/curl_opt/timestamp</code></td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that we can retrieve the timestamp from a resource</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/apps/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the <code style="font-family: monospace">Playback</code> dialplan application can playback a remote URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/apps/control_playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the <code style="font-family: monospace">ControlPlayback</code> dialplan application can playback a remote URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/fastagi/stream-file-uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the AGI Stream File command can play a URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/fastagi/control-stream-file-uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that the AGI Control Stream File command can play a URI</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/channels/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource can be created from a URI for a Channel</td> 
</tr> 
<tr> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"><code style="font-family: monospace">tests/rest_api/bridges/playback/uri</code></td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Asterisk Test Suite</td> 
<td colspan="1" class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left">Verify that a Playback resource can be created from a URI for a Bridge</td> 
</tr> 
</tbody> 
</table> 
</div> 
<h1 id="Asterisk14Project-URIMediaPlayback-ProjectPlanning" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Project Planning</h1> 
<h2 id="Asterisk14Project-URIMediaPlayback-JIRAIssues" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 10px">JIRA Issues</h2> 
<p style="margin: 10px 0 0 0"> </p> 
<h2 id="Asterisk14Project-URIMediaPlayback-Contributors" style="margin: 10px 0 0 0; font-size: 20px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Contributors</h2> 
<div class="table-wrap" style="margin: 10px 0 0 0; overflow-x: auto"> 
<table class="confluenceTable" style="border-collapse: collapse; border: 1px solid #ddd;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-collapse: collapse; margin: 10px 0 0 0; overflow-x: auto; margin-top: 0"> 
<tbody> 
<tr> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">Name</p> </th> 
<th class="confluenceTh" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;background-color: #F0F0F0; font-weight: bold;; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left; background-color: #f0f0f0; font-weight: bold"> <p style="margin: 10px 0 0 0; margin-top: 0; background-color: #f0f0f0; font-weight: bold">E-mail Address</p> </th> 
</tr> 
<tr> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <span class="confluence-userlink user-mention" style="background-color: #f5f5f5; border: 1px solid #ddd; padding: 0 2px; border-radius: 3px; display: inline-block; mso-line-height-rule: exactly; line-height: 16px; white-space: nowrap"><span style="color: #999; font-size: 12px; line-height: 16px; mso-line-height-rule: exactly; padding-right:2px; vertical-align:top; mso-text-raise:3px;">@</span><a href="/wiki/display/~mjordan" style="color: #3b73af; text-decoration: none">Matt Jordan</a></span> </p> </td> 
<td class="confluenceTd" style="border: 1px solid #DDD; padding: 5px 7px; min-width: 0.6em; text-align: left; vertical-align: top;; padding: 0px; border-collapse: collapse; border: 1px solid #ddd; padding: 7px 10px; vertical-align: top; text-align: left"> <p style="margin: 10px 0 0 0; margin-top: 0"> <a href="mailto:mjordan@digium.com" class="external-link" rel="nofollow" style="color: #3b73af; text-decoration: none">mjordan@digium.com</a> </p> </td> 
</tr> 
</tbody> 
</table> 
</div> 
<h1 id="Asterisk14Project-URIMediaPlayback-ReferenceInformation" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">Reference Information</h1> 
<p style="margin: 10px 0 0 0"> </p> 
</div> </td> 
</tr> 
</tbody>
</table> 
</div> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand action-padding last-row-padding" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff; padding-bottom: 10px; padding-bottom: 10px"> 
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 15px 0 0 24px; vertical-align: middle"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="View page Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="View page Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aview-page-email-adg-footer-item%3Aicon" alt="View page Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?src=email" title="View page" style="color: #3b73af; text-decoration: none">View page</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Add comment Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aadd-comment-to-content-email-adg-footer-item%3Aicon" alt="Add comment Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+Project+-+URI+Media+Playback?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none">Add comment</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30279111&src=email" title="Like Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Like Icon" src="cid:com.atlassian.confluence.plugins.confluence-like%3Aview-email-adg-content-item%3Aicon" alt="Like Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30279111&src=email" title="Like" style="color: #3b73af; text-decoration: none">Like</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; height: 5px; line-height: 5px; padding: 0 15px 0 16px; background-color: #fff; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; mso-line-height-rule: exactly"> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px"> 
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="footer-pattern-links-container" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST&src=email" title="" style="color: #3b73af; text-decoration: none">Stop watching space</a></td>
<td class="footer-pattern-links-bull" style="padding: 0px; border-collapse: collapse; padding: 0 5px; color: #999">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action?src=email" title="" style="color: #3b73af; text-decoration: none">Manage notifications</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px; display: none">This message was sent by Atlassian Confluence 5.6.1</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<table id="sealed-section" border="0" cellpadding="0" cellspacing="0" width="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; display: none"> 
<tbody> 
<tr> 
<td style="padding: 0px; border-collapse: collapse; border: 0; font-size: 0px; line-height: 0; mso-line-height-rule: exactly"></td> 
</tr> 
</tbody> 
</table>
</body>
</html>