blob: d987c70d3fcdb08027901fab53ab687a0fa7b118 [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<div class="x_panel">
<div class="x_title">
<ol class="breadcrumb pull-left">
<li ng-if="!settings.isRequest"><a ng-click="navigateToPath('/delivery-services')">Delivery Services</a></li>
<li ng-if="settings.isRequest"><a ng-click="navigateToPath('/delivery-service-requests')">Delivery Service Requests</a></li>
<li ng-if="settings.isRequest" class="active">{{dsRequest.changeType}}</li>
<li class="active">{{deliveryServiceName}}</li>
</ol>
<div class="pull-right" role="group" ng-if="settings.isRequest">
<div class="btn-group" role="group" uib-dropdown is-open="status.isopen">
<button ng-disabled="dsRequest.status == 'rejected' || dsRequest.status == 'complete'" type="button" class="btn btn-link dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
{{dsRequest.status | uppercase }}&nbsp;
<span ng-show="dsRequest.status == 'draft' || dsRequest.status == 'submitted' || dsRequest.status == 'pending'" class="caret"></span>
</button>
<ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
<li role="menuitem"><a ng-if="dsRequest.status == 'submitted'" ng-click="editStatus('draft')">Change status to: DRAFT</a></li>
<li role="menuitem"><a ng-if="dsRequest.status == 'draft'" ng-click="editStatus('submitted')">Change status to: SUBMITTED</a></li>
<li role="menuitem"><a ng-if="dsRequest.status == 'pending'" ng-click="editStatus('complete')">Change status to: COMPLETE</a></li>
</ul>
</div>
</div>
<div class="pull-right" role="group">
<button type="button" class="btn btn-danger" ng-if="!settings.isNew && !settings.isRequest" ng-disabled="!deletable()" ng-click="confirmDelete(deliveryService)">{{settings.deleteLabel}}</button>
<button class="btn btn-success" ng-if="!settings.isRequest" ng-disabled="deliveryServiceForm.$pristine || deliveryServiceForm.$invalid || !saveable()" ng-click="save(deliveryService)">{{settings.saveLabel}}</button>
<button type="button" class="btn btn-primary" ng-if="!settings.isRequest && !settings.isNew" title="Delivery Service Charts" ng-if="showChartsButton" ng-click="openCharts(deliveryService)"><i class="fa fa-bar-chart fa-fw"></i></button>
<a class="btn btn-primary" ng-if="!settings.isRequest" ng-href="/#!/delivery-service-requests?xmlId={{deliveryService.xmlId}}">View Linked Delivery Service Requests</a>
<div class="btn-group" ng-if="!settings.isRequest && !settings.isNew" role="group" uib-dropdown is-open="more.isopen">
<button name="moreBtn" type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
More&nbsp;
<span class="caret"></span>
</button>
<ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
<li role="menuitem"><a ng-click="clone(deliveryService)">Clone Delivery Service</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="viewCharts()">View Charts</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="manageSslKeys()">Manage SSL Keys</a></li>
<li role="menuitem"><a ng-click="manageUrlSigKeys()">Manage URL Sig Keys</a></li>
<li role="menuitem"><a ng-click="manageUriSigningKeys()">Manage URI Signing Keys</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="viewJobs()">Manage Invalidation Requests</a></li>
<li role="menuitem"><a ng-click="viewOrigins()">Manage Origins</a></li>
<li role="menuitem"><a ng-click="viewRegexes()">Manage Regexes</a></li>
<li role="menuitem"><a ng-click="viewCapabilities()">Manage Required Server Capabilities</a></li>
<li name="manageServersMenuItem" role="menuitem"><button class="menu-item-button" type="button" ng-click="viewServers()">Manage Servers</button></li>
<li role="menuitem"><a ng-click="viewStaticDnsEntries()">Manage Static DNS Entries</a></li>
</ul>
</div>
</div>
<div class="clearfix"></div>
</div>
<div class="x_content">
<div id="deliveryServiceURLs">
<fieldset ng-if="!settings.isNew && !settings.isRequest">
<legend>Delivery Service URL(s)</legend>
<p ng-repeat="url in deliveryService.exampleURLs"><a href="{{::url}}" rel="noreferrer" target="_blank">{{::url}}</a> </p>
</fieldset>
</div>
<form id="deliveryServiceForm" name="deliveryServiceForm" class="form-horizontal form-label-left">
<fieldset>
<legend ng-class="{'fieldset-error': generalConfig.$invalid}" ng-click="showGeneralConfig = !showGeneralConfig">General Configuration Settings <i class="fa" ng-class="showGeneralConfig ? 'fa-caret-down' : 'fa-caret-up'"></i></legend>
<ng-form name="generalConfig" ng-show="showGeneralConfig">
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.xmlId), 'has-feedback': hasError(generalConfig.xmlId)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="xmlId">XML_ID (Key) *<div class="helptooltip">
<div class="helptext">This id becomes a part of the CDN service domain in the form <samp>http://cdn.service-key.company.com/</samp>. Must be all lowercase, no spaces or special characters. May contain dashes.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="xmlId" name="xmlId" type="text" class="form-control" placeholder="Unique id used for the delivery service" ng-model="deliveryService.xmlId" required maxlength="48" pattern="[a-z0-9]([a-z0-9\-]*[a-z0-9])?" ng-readonly="(!settings.isRequest && !settings.isNew) || (settings.isRequest && changeType == 'update')">
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'pattern')">Must be a valid DNS label (no special characters, capital letters, periods, underscores, or spaces and cannot begin or end with a hyphen)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.xmlId != dsCurrent.xmlId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.xmlId}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.displayName), 'has-feedback': hasError(generalConfig.displayName)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="displayName">Display Name *<div class="helptooltip">
<div class="helptext">Name of the service that appears in the Traffic portal. No character restrictions.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="displayName" name="displayName" type="text" class="form-control" ng-model="deliveryService.displayName" maxlength="48" required>
<small class="input-error" ng-show="hasPropertyError(generalConfig.displayName, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.displayName, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.displayName != dsCurrent.displayName">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.displayName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.active), 'has-feedback': hasError(generalConfig.active)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="active">Active *<div class="helptooltip">
<div class="helptext">Whether or not this Delivery Service is active on the CDN and is capable of traffic.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="active" name="active" class="form-control" ng-model="deliveryService.active" required>
<option disabled hidden value="">Select...</option>
<option ng-value="true">Active</option>
<option ng-value="false">Not Active</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.active, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.active != dsCurrent.active">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.active ? 'Active' : 'Not Active'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.type), 'has-feedback': hasError(generalConfig.type)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="type">Content Routing Type *<div class="helptooltip">
<div class="helptext">
DNS is the standard routing type for most CDN services. HTTP Redirect is a specialty routing service that is primarily used for video and large file downloads where localization and latency are significant concerns. A "Live" routing type should be used for all live services.
<br>
<br>
<a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#ds-types" target="_blank">See Delivery Service Types.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="type" name="type" class="form-control" ng-model="deliveryService.typeId" ng-options="type.id as type.name for type in types" required>
<option selected disabled hidden value="">Select...</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.type, 'required')">Required</small>
<small ng-show="deliveryService.typeId"><a href="/#!/types/{{deliveryService.typeId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.typeId != dsCurrent.typeId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.type}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.tenantId), 'has-feedback': hasError(generalConfig.tenantId)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="tenantId">Tenant *<div class="helptooltip">
<div class="helptext">Name of company or division of company who owns account. Allows you to group your services and control access. Tenants are setup as a simple hierarchy where you may create parent / child accounts.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<tree-select handle="tenantId" on-update="deliveryService.tenantId=value" tree-data="[tenants[0]]" initial-value="deliveryService.tenantId"></tree-select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.tenantId, 'required')">Required</small>
<small ng-show="deliveryService.tenantId"><a href="/#!/tenants/{{deliveryService.tenantId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.tenantId != dsCurrent.tenantId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.tenant}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.cdn), 'has-feedback': hasError(generalConfig.cdn)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="cdn">CDN *<div class="helptooltip">
<div class="helptext">The CDN to which the Delivery Service belongs.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="cdn" name="cdn" class="form-control" ng-model="deliveryService.cdnId" ng-options="cdn.id as cdn.name for cdn in cdns" required ng-disabled="(!settings.isNew && deliveryService.sslKeyVersion)">
<option hidden disabled selected value="">Select...</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.cdnId, 'required')">Required</small>
<small ng-show="deliveryService.cdnId"><a href="/#!/cdns/{{deliveryService.cdnId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.cdnId != dsCurrent.cdnId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.cdnName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.orgServerFqdn), 'has-feedback': hasError(generalConfig.orgServerFqdn)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="orgServerFqdn">Origin Server Base URL *<div class="helptooltip">
<div class="helptext">The Origin Server’s base URL which includes the protocol (http or https). Example: <samp>http://movies.origin.com</samp>. Must be a domain only, no directories or IP addresses</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="orgServerFqdn" name="orgServerFqdn" type="url" title="Must start with http:// or https:// and be followed by a valid hostname with an optional port (no trailing slash)" class="form-control" placeholder="http(s)//:" ng-model="deliveryService.orgServerFqdn" pattern="https?://[a-z0-9][a-z0-9\-]*(\.[a-z0-9\-][a-z0-9\-]*)*(:\d{1,5})?" required>
<small class="input-error" ng-show="hasPropertyError(generalConfig.orgServerFqdn, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.orgServerFqdn, 'pattern')">Must start with http:// or https:// and be followed by a valid hostname with an optional port (no trailing slash)</small>
<small ng-show="!settings.isNew && !settings.isRequest && deliveryService.orgServerFqdn"><a href="/#!/origins/{{origin.id}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.orgServerFqdn != dsCurrent.orgServerFqdn">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.orgServerFqdn}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.protocol), 'has-feedback': hasError(generalConfig.protocol)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="protocol">Protocol *<div class="helptooltip">
<div class="helptext">
The protocol with which to serve this Delivery Service to the clients:
<br>
<br>
<dl>
<dt>HTTP</dt><dd>Deliver only HTTP traffic</dd>
<dt>HTTPS</dt><dd>Deliver only HTTPS traffic</dd>
<dt>HTTP AND HTTPS</dt><dd>Deliver both types of traffic</dd>
<dt>HTTP TO HTTPS</dt><dd>Redirect HTTP traffic to use HTTPS</dd>
</dl>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="protocol" name="protocol" class="form-control" ng-model="deliveryService.protocol" required>
<option hidden disabled value="">Select...</option>
<option ng-value="0">HTTP</option>
<option ng-value="1">HTTPS</option>
<option ng-value="2">HTTP and HTTPS</option>
<option ng-value="3">HTTP to HTTPS</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.protocol, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.protocol != dsCurrent.protocol">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(protocols, dsCurrent.protocol)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.topology), 'has-feedback': hasError(generalConfig.topology)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="topology">Topology<div class="helptooltip">
<div class="helptext">A topology is used to determine the caching layers and path to a delivery service's origin.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="topology" name="topology" class="form-control" ng-model="deliveryService.topology" ng-options="topology.name as topology.name for topology in topologies">
<option selected value="">None</option>
</select>
<small ng-show="deliveryService.topology"><a href="/#!/topologies/edit?name={{deliveryService.topology}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.topology !== dsCurrent.topology">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.topology}}</pre>
</aside>
</div>
</div>
<div class="form-group">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="restrictTLS">
Restrict TLS Versions
<div class="helptooltip">
<div class="helptext">
Limit the TLS versions that cache servers will accept for HTTPs connections.
<aside class="warning">
<h6>Warning</h6>
<p>Setting TLS Versions that are explicitly supported may break older clients that can't use the specified versions</p>
</aside>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12" style="display:inline-grid;grid-template-columns:auto;justify-content:start;">
<input
type="checkbox"
id="restrictTLS"
name="restrictTLS"
class="form-control"
ng-model="restrictTLS"
style="max-width: max-content; min-width: 1em;"
ng-change="toggleTLSRestrict()"
/>
<small class="input-warning" ng-if="restrictTLS && dsCurrent.protocol === 0">Delivery Service doesn't use HTTPS - this will have no effect</small>
</div>
</div>
<div
class="form-group"
ng-if="restrictTLS"
ng-repeat="ver in deliveryService.tlsVersions track by $index"
ng-class="{'has-error': tlsVersionHasError($index), 'has-feedback': tlsVersionHasError($index)}"
>
<div>
<label class="control-label col-md-2 col-sm-2 col-xs-12" for="tlsVersion1">
TLS Version #{{$index+1}}
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<div>
<div class="input-group add-more-inputs">
<input
id="tlsVersion{{$index+1}}"
name="tlsVersion{{$index+1}}"
type="text"
class="form-control"
ng-model="deliveryService.tlsVersions[$index]"
pattern="[0-9]+\.[0-9]+"
placeholder="1.3"
required
ng-change="validateTLS()"
/>
<span class="form-input-group-btn input-group-btn">
<button
type="button"
title="remove support for this TLS version"
class="btn btn-default"
ng-show="deliveryService.tlsVersions.length > 1"
ng-click="removeTLSVersion($index)"
>
<i class="fa fa-minus"></i>
</button>
<button
type="button"
title="add a supported TLS version"
class="btn btn-default"
ng-click="addTLSVersion($index)"
>
<i class="fa fa-plus"></i>
</button>
</span>
</div>
</div>
<small class="input-error" ng-show="tlsVersionHasPropertyError($index, 'duplicates')">Duplicate TLS Version</small>
<small class="input-error" ng-show="tlsVersionHasPropertyError($index, 'required')">Required</small>
<small class="input-error" ng-show="tlsVersionHasPropertyError($index, 'pattern')">Invalid version number - must be "X.Y"</small>
<small class="input-warning" ng-show="tlsVersionUnknown(ver)">Unknown version</small>
<small class="input-warning" ng-show="tlsVersionInsecure(ver)">TLS Version {{ver}} is known to be insecure!</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="dsCurrent.tlsVersions instanceof Array && dsCurrent.tlsVersions.length === deliveryService.tlsVersions.length && dsCurrent.tlsVersions[$index] !== dsCurrent.tlsVersions[$index]">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.tlsVersions[$index]}}</pre>
</aside>
</div>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.serviceCategory), 'has-feedback': hasError(generalConfig.serviceCategory)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="serviceCategory">Service Category<div class="helptooltip">
<div class="helptext">The type of content being delivered. Some examples are linear and vod.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="serviceCategory" name="serviceCategory" class="form-control" ng-model="deliveryService.serviceCategory" ng-options="serviceCategory.name as serviceCategory.name for serviceCategory in serviceCategories">
<option value="">Select...</option>
</select>
<small ng-show="deliveryService.serviceCategory"><a href="/#!/service-categories/edit?name={{deliveryService.serviceCategory}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.serviceCategory != dsCurrent.serviceCategory">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.serviceCategory}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.longDesc), 'has-feedback': hasError(generalConfig.longDesc)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="longDesc">Long Description<div class="helptooltip">
<div class="helptext">Free text field not currently used in configuration.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="longDesc" name="longDesc" class="form-control" ng-model="deliveryService.longDesc" spellcheck="true" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.longDesc != dsCurrent.longDesc">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.longDesc}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.dscp), 'has-feedback': hasError(generalConfig.dscp)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="dscp">DSCP<div class="helptooltip">
<div class="helptext">The <abbr title="Differentiated Services Code Point">DSCP *</abbr> value with which to mark IP packets outbound to the client.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="dscp" name="dscp" class="form-control" ng-model="deliveryService.dscp" ng-options="dcsp.value as dcsp.label for dcsp in dscps" required>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.dscp, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.dscp != dsCurrent.dscp">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(dscps, dsCurrent.dscp)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.profile), 'has-feedback': hasError(generalConfig.profile)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="profile">Profile<div class="helptooltip">
<div class="helptext">Only used if a Delivery Service uses configurations that specifically require a profile. Example: Multi-Site Origin configurations would require a Delivery Service Profile to be used.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="profile" name="profile" class="form-control" ng-model="deliveryService.profileId" ng-options="profile.id as profile.name for profile in profiles">
<option selected value="">None</option>
</select>
<small ng-show="deliveryService.profileId"><a href="/#!/profiles/{{deliveryService.profileId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.profileId != dsCurrent.profileId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.profileName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.infoUrl), 'has-feedback': hasError(generalConfig.infoUrl)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="infoUrl">Info URL<div class="helptooltip">
<div class="helptext">Free text field used to enter a URL which provides information about the service.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="infoUrl" name="infoUrl" type="url" title="Must be a valid URL." class="form-control" ng-model="deliveryService.infoUrl" maxlength="255">
<small class="input-error invalid-URL-error">Invalid URL</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.infoUrl, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.infoUrl != dsCurrent.infoUrl">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.infoUrl}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.checkPath), 'has-feedback': hasError(generalConfig.checkPath)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="checkPath">Check Path<div class="helptooltip">
<div class="helptext">A path (e.g. <samp>/crossdomain.xml</samp>) with which to verify the connection to the origin server. This can be used by Check Extension scripts to do periodic health checks against the Delivery Service.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="checkPath" name="checkPath" type="text" class="form-control" ng-model="deliveryService.checkPath" maxlength="255">
<small class="input-error" ng-show="hasPropertyError(generalConfig.checkPath, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.checkPath != dsCurrent.checkPath">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.checkPath}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.originShield), 'has-feedback': hasError(generalConfig.originShield)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="originShield">Origin Shield<div class="helptooltip">
<div class="helptext">
Add another forward proxy upstream of the mid caches. Example: <samp>go_direct=true</samp> will allow the Mid to hit the origin directly instead of failing if the origin shield is down.
<aside class="warning">
<h6>Warning</h6>
<p>This feature is experimental, use with caution!</p>
</aside>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="originShield" name="originShield" type="text" class="form-control" ng-model="deliveryService.originShield" maxlength="1024">
<small class="input-error" ng-show="hasPropertyError(generalConfig.originShield, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.originShield != dsCurrent.originShield">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.originShield}}</pre>
</aside>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2 col-sm-2 col-xs-12" for="lastUpdated">
Last Updated
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="lastUpdated" type="text" class="form-control" ng-model="deliveryService.lastUpdated" readonly />
</div>
</div>
</ng-form>
</fieldset>
<fieldset>
<legend ng-class="{'fieldset-error': cacheConfig.$invalid}" ng-click="showCacheConfig = !showCacheConfig">Cache Configuration Settings <i class="fa" ng-class="showCacheConfig ? 'fa-caret-down' : 'fa-caret-up'"></i></legend>
<ng-form name="cacheConfig" ng-show="showCacheConfig">
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.maxOriginConnections), 'has-feedback': hasError(cacheConfig.maxOriginConnections)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="maxOriginConnections">Max Origin Connections<div class="helptooltip">
<div class="helptext">
The maximum number of connections allowed to the origin. Enter <code>0</code> to indicate no maximum.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="maxOriginConnections" name="maxOriginConnections" type="number" class="form-control" ng-model="deliveryService.maxOriginConnections" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(cacheConfig.maxOriginConnections, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.maxOriginConnections != dsCurrent.maxOriginConnections">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.maxOriginConnections}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.maxRequestHeaderBytes), 'has-feedback': hasError(cacheConfig.maxRequestHeaderBytes)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="maxRequestHeaderBytes">Max Request Header Bytes<div class="helptooltip">
<div class="helptext">
The maximum size (in bytes) of the request headers for this particular delivery service. The default value is <code>0</code> which will limit the request headers size (in bytes) to the value defined by the
<a href="https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/files/records.config.en.html#proxy-config-http-request-header-max-size" target="_blank">proxy.config.http.request_header_max_size</a>
parameter.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="maxRequestHeaderBytes" name="maxRequestHeaderBytes" type="number" class="form-control" ng-model="deliveryService.maxRequestHeaderBytes" step="1" min="0" max="2147483647">
<small class="input-error" ng-show="hasPropertyError(cacheConfig.maxRequestHeaderBytes, 'min')">Too Small (must be greater than or equal to 0)</small>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.maxRequestHeaderBytes, 'max')">Too Big (must be lesser than or equal to 2147483647)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.maxRequestHeaderBytes != dsCurrent.maxRequestHeaderBytes">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.maxRequestHeaderBytes}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.signingAlgorithm), 'has-feedback': hasError(cacheConfig.signingAlgorithm)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="signingAlgorithm">Signing Algorithm<div class="helptooltip">
<div class="helptext">
Type of URL signing method to sign the URLs:
<br>
<dl>
<dt>None</dt><dd>URLs will not be signed within this Delivery Service</dd>
<dt>URL Signature Keys</dt><dd>URL Signature token-based authentication is enabled for this Delivery Service.</dd>
<dt>URI Signing Keys</dt><dd>URI Signing token-based authentication is enabled for this Delivery Service.</dd>
</dl>
<br>
<br>
<a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#signing-algorithm" target="_blank">See Token Based Authentication</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="signingAlgorithm" name="signingAlgorithm" class="form-control" ng-change="changeSigningAlgorithm(deliveryService.signingAlgorithm)" ng-model="deliveryService.signingAlgorithm">
<option ng-value="null">None</option>
<option value="url_sig">URL Signature Keys</option>
<option value="uri_signing">URI Signing Keys</option>
</select>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.signingAlgorithm != dsCurrent.signingAlgorithm">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(signingAlgos, dsCurrent.signingAlgorithm)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.rangeRequestHandling), 'has-feedback': hasError(cacheConfig.rangeRequestHandling)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="rangeRequestHandling">Range Request Handling *<div class="helptooltip">
<div class="helptext">
How to treat range requests.
<br>
<br>
<ul>
<li>Do not cache (ranges requested from files that are already cached due to a non range request can still be served)</li>
<li>Use the <a href="https://docs.trafficserver.apache.org/en/7.1.x/admin-guide/plugins/background_fetch.en.html" target="_blank"><code>background_fetch</code> plugin.</a></li>
<li>Use the <code>cache_range_requests</code> plugin.</li>
<li>Use the <a href="https://docs.trafficserver.apache.org/en/9.0.x/admin-guide/plugins/slice.en.html" target="_blank"><code>slice</code> plugin.</a></li>
</ul>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="rangeRequestHandling" name="rangeRequestHandling" class="form-control" ng-model="deliveryService.rangeRequestHandling" ng-change="rangeRequestSelected()" required>
<option ng-value="0">Don't cache Range Requests</option>
<option ng-value="1">Use the background_fetch plugin</option>
<option ng-value="2">Use the cache_range_requests plugin</option>
<option ng-value="3">Use the slice plugin</option>
</select>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.rangeRequestHandling, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.rangeRequestHandling != dsCurrent.rangeRequestHandling">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(rrhs, dsCurrent.rangeRequestHandling)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.rangeSliceBlockSize), 'has-feedback': hasError(cacheConfig.rangeSliceBlockSize)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="rangeSliceBlockSize">Range Slice Block Size<div class="helptooltip">
<div class="helptext">
The block size in bytes that is used for the slice plugin for range requests. Must be between <code>262144</code> - <code>33554432</code>.
Can only be set if the Range Request Handling is set to <code>Use the slice plugin</code>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="rangeSliceBlockSize" name="rangeSliceBlockSize" type="number" class="form-control" ng-model="deliveryService.rangeSliceBlockSize" min="262144" max="33554432" ng-readonly="deliveryService.rangeRequestHandling != 3" ng-required="deliveryService.rangeRequestHandling == 3">
<small class="input-error" ng-show="hasPropertyError(cacheConfig.rangeSliceBlockSize, 'min')">Too Small (must be greater than or equal to 262144)</small>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.rangeSliceBlockSize, 'max')">Too Large (must be smaller than or equal to 33554432)</small>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.rangeSliceBlockSize, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.rangeSliceBlockSize != dsCurrent.rangeSliceBlockSize">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.rangeSliceBlockSize}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.qstringIgnore), 'has-feedback': hasError(cacheConfig.qstringIgnore)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12">Query String Handling *<div class="helptooltip">
<div class="helptext">
How to treat query parameter strings in request URLs:
<br>
<br>
<ul>
<li>Use in cache key and hand up to origin: Each URL is considered unique if and only if the <em>entire</em> URL (i.e. including any query parameter string string) is unique.</li>
<li>Do not use in cache key, but pass up to origin: Two URLs that are the same except for the query parameter string will match and cache HIT, while the origin still sees original query parameter string in the request.</li>
<li>Drop at edge: Two URLs that are the same except for the query string will match and cache HIT, while the origin will not see original query string in the request.</li>
</ul>
<aside>
<h6>Note:</h6>
<p>Choosing to drop query parameter strings at the edge will preclude the use of a Regex Remap Expression. <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#regex-remap-expression" target="_blank">See Regex Remap Expression</a>
<br>
To set the qstring without the use of regex remap, or for further options, <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#query-string-handling" target="_blank">See Qstring Handling</a></p>
</aside>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="qstringIgnore" name="qstringIgnore" class="form-control" ng-model="deliveryService.qstringIgnore" required>
<option ng-value="0" selected>Use query parameter strings in cache key and pass in upstream requests</option>
<option ng-value="1">Do not use query parameter strings in cache key, but do pass in upstream requests</option>
<option ng-value="2">Neither use query parameter strings in cache key, nor pass in upstream requests</option>
</select>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.qstringIgnore, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.qstringIgnore != dsCurrent.qstringIgnore">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(qStrings, dsCurrent.qstringIgnore)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.edgeHeaderRewrite), 'has-feedback': hasError(cacheConfig.edgeHeaderRewrite)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="edgeHeaderRewrite">Edge Header Rewrite Rules<div class="helptooltip">
<div class="helptext">
For non topology-based delivery services, headers can be added or altered at the edge layer of the CDN. You must tell us three things: the action, the header name, and the header value. The action will tell us whether we are adding, removing, or replacing headers. The header name and header value will determine the full header text. Edge header rewrite values will be added before we respond to a request from a client. Examples include:
<br>
<br>
<ul>
<li>Action: Set</li>
<li>Header Name: X-CDN</li>
<li>Header Value: Foo</li>
</ul>
<br>
<br>See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#edge-header-rewrite-rules" target="_blank">Edge Header Rewrite Rules.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="edgeHeaderRewrite" name="edgeHeaderRewrite" class="form-control private-text" ng-model="deliveryService.edgeHeaderRewrite" ng-maxlength="(deliveryService.topology) ? 0 : ''" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.edgeHeaderRewrite, 'maxlength')">Only applicable with non topology-based delivery services</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.edgeHeaderRewrite != dsCurrent.edgeHeaderRewrite">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.edgeHeaderRewrite}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.midHeaderRewrite), 'has-feedback': hasError(cacheConfig.midHeaderRewrite)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="midHeaderRewrite">Mid Header Rewrite Rules<div class="helptooltip">
<div class="helptext">
For non topology-based delivery services, headers can be added or altered at the mid layer of the CDN. You must tell us three things: the action, the header name, and the header value. The action will tell us whether we are adding, removing, or replacing headers. The header name and header value will determine the full header text. Mid header rewrite values will be added before we make a request further up the chain in the server hierarchy (ie. to the origin). Examples include:
<ul>
<li>Action: Set</li>
<li>Header Name: Host</li>
<li>Header Value: code_abc123</li>
</ul>
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#mid-header-rewrite-rules" target="_blank">Mid Header Rewrite Rules.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="midHeaderRewrite" name="midHeaderRewrite" class="form-control private-text" ng-model="deliveryService.midHeaderRewrite" ng-maxlength="(deliveryService.topology) ? 0 : ''" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.midHeaderRewrite, 'maxlength')">Only applicable with non topology-based delivery services</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.midHeaderRewrite != dsCurrent.midHeaderRewrite">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.midHeaderRewrite}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.firstHeaderRewrite), 'has-feedback': hasError(cacheConfig.firstHeaderRewrite)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="firstHeaderRewrite">First Header Rewrite Rules<div class="helptooltip">
<div class="helptext">
For topology-based delivery services, headers can be added or altered at the first layer (aka edge layer) of the CDN. You must tell us three things: the action, the header name, and the header value. The action will tell us whether we are adding, removing, or replacing headers. The header name and header value will determine the full header text. First header rewrite values will be added before we respond to a request from a client. Examples include:
<ul>
<li>Action: Set</li>
<li>Header Name: Host</li>
<li>Header Value: code_abc123</li>
</ul>
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#first-header-rewrite-rules" target="_blank">First Header Rewrite Rules.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="firstHeaderRewrite" name="firstHeaderRewrite" class="form-control private-text" ng-model="deliveryService.firstHeaderRewrite" ng-maxlength="(!deliveryService.topology) ? 0 : ''" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.firstHeaderRewrite, 'maxlength')">Only applicable with topology-based delivery services</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.firstHeaderRewrite != dsCurrent.firstHeaderRewrite">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.firstHeaderRewrite}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.innerHeaderRewrite), 'has-feedback': hasError(cacheConfig.innerHeaderRewrite)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="innerHeaderRewrite">Inner Header Rewrite Rules<div class="helptooltip">
<div class="helptext">
For topology-based delivery services, headers can be added or altered at the inner layer of the CDN. You must tell us three things: the action, the header name, and the header value. The action will tell us whether we are adding, removing, or replacing headers. The header name and header value will determine the full header text. Inner header rewrite values will be added before we make a request further up the chain in the server hierarchy. Examples include:
<ul>
<li>Action: Set</li>
<li>Header Name: Host</li>
<li>Header Value: code_abc123</li>
</ul>
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#inner-header-rewrite-rules" target="_blank">Inner Header Rewrite Rules.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="innerHeaderRewrite" name="innerHeaderRewrite" class="form-control private-text" ng-model="deliveryService.innerHeaderRewrite" ng-maxlength="(!deliveryService.topology) ? 0 : ''" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.innerHeaderRewrite, 'maxlength')">Only applicable with topology-based delivery services</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.innerHeaderRewrite != dsCurrent.innerHeaderRewrite">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.innerHeaderRewrite}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.lastHeaderRewrite), 'has-feedback': hasError(cacheConfig.lastHeaderRewrite)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="lastHeaderRewrite">Last Header Rewrite Rules<div class="helptooltip">
<div class="helptext">
For topology-based delivery services, headers can be added or altered at the last layer of the CDN. You must tell us three things: the action, the header name, and the header value. The action will tell us whether we are adding, removing, or replacing headers. The header name and header value will determine the full header text. Last header rewrite values will be added before we make a request further up the chain in the server hierarchy (ie. to the origin). Examples include:
<ul>
<li>Action: Set</li>
<li>Header Name: Host</li>
<li>Header Value: code_abc123</li>
</ul>
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#last-header-rewrite-rules" target="_blank">Last Header Rewrite Rules.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="lastHeaderRewrite" name="lastHeaderRewrite" class="form-control private-text" ng-model="deliveryService.lastHeaderRewrite" ng-maxlength="(!deliveryService.topology) ? 0 : ''" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.lastHeaderRewrite, 'maxlength')">Only applicable with topology-based delivery services</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.lastHeaderRewrite != dsCurrent.lastHeaderRewrite">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.lastHeaderRewrite}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.regexRemap), 'has-feedback': hasError(cacheConfig.regexRemap)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="regexRemap">Regex remap expression<div class="helptooltip">
<div class="helptext">
Allows remapping of incoming requests URL using regex pattern matching to search/replace text.
<br>
<br>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.regexRemap, 'maxlength')">Too Long</small>
<br>
<aside>
<h6>Note</h6>
<p>You will not be able to save a Regex Remap Expression if you have Query String Handling set to drop query strings at the edge. <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#regex-remap-expression" target="_blank">See Regex Remap Expression</a></p>
</aside>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="regexRemap" name="regexRemap" class="form-control" ng-model="deliveryService.regexRemap" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.regexRemap != dsCurrent.regexRemap">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.regexRemap}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.remapText), 'has-feedback': hasError(cacheConfig.remapText)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="remapText">Raw remap text<div class="helptooltip">
<div class="helptext">For HTTP and DNS Delivery Services, this will get added to the end of the remap line verbatim on cache servers. For ANY_MAP Delivery Services this is the entire remap line.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="remapText" name="remapText" class="form-control private-text" ng-model="deliveryService.remapText" ng-pattern="/^[^\n\r]*$/" rows="3"></textarea>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.remapText, 'pattern')">No Line Breaks</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.remapText != dsCurrent.remapText">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.remapText}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(cacheConfig.multiSiteOrigin), 'has-feedback': hasError(cacheConfig.multiSiteOrigin)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="multiSiteOrigin">Use Multi-Site Origin Feature *<div class="helptooltip">
<div class="helptext">
Enables/disables the Multi-Site Origin feature for this Delivery Service.
<br>
<br>
<a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#ds-multi-site-origin" target="_blank">See Multi-Site Origin.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="multiSiteOrigin" name="multiSiteOrigin" class="form-control" ng-model="deliveryService.multiSiteOrigin" required>
<option ng-value="false" selected>Do not use Multi-Site Origin</option>
<option ng-value="true">Use Multi-Site Origin</option>
</select>
<small class="input-error" ng-show="hasPropertyError(cacheConfig.multiSiteOrigin, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.multiSiteOrigin != dsCurrent.multiSiteOrigin">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.multiSiteOrigin ? 'Use Multi-Site Origin' : 'Do not use Multi-Site Origin'}}</pre>
</aside>
</div>
</div>
</ng-form>
</fieldset>
<fieldset>
<legend ng-class="{'fieldset-error': routingConfig.$invalid}" ng-click="showRoutingConfig = !showRoutingConfig">Routing Configuration Settings <i class="fa" ng-class="showRoutingConfig ? 'fa-caret-down' : 'fa-caret-up'"></i></legend>
<ng-form name="routingConfig" ng-show="showRoutingConfig">
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.routingName), 'has-feedback': hasError(routingConfig.routingName)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="routingName">Routing Name *<div class="helptooltip">
<div class="helptext">The routing name to use for the delivery <abbr title="Fully Qualified Domain Name">FQDN</abbr>, e.g. <samp>routing-name.deliveryservice.cdn-domain</samp>. It must be a valid hostname without periods.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="routingName" name="routingName" type="text" class="form-control" placeholder="Routing name used for the delivery service resulting in FQDN = <routing name>.<key>.<CDN domain>" ng-model="deliveryService.routingName" maxlength="48" pattern="[a-z0-9]([a-z\-0-9]*[a-z0-9])?" required ng-disabled="(!settings.isNew && deliveryService.sslKeyVersion)">
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'pattern')">Must be a valid DNS label (no special characters, capital letters, periods, underscores, or spaces and cannot begin or end with a hyphen)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.routingName != dsCurrent.routingName">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.routingName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ipv6RoutingEnabled), 'has-feedback': hasError(routingConfig.ipv6RoutingEnabled)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ipv6RoutingEnabled">IPv6 Routing Enabled *<div class="helptooltip">
<div class="helptext">Enabled by default, disabling this allows you to turn off CDN responses to IPv6 requests</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="ipv6RoutingEnabled" name="ipv6RoutingEnabled" class="form-control" ng-model="deliveryService.ipv6RoutingEnabled" required>
<option ng-value="true">Enabled</option>
<option ng-value="false">Disabled</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.ipv6RoutingEnabled, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ipv6RoutingEnabled != dsCurrent.ipv6RoutingEnabled">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ipv6RoutingEnabled ? 'Enabled' : 'Disabled'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ecsEnabled), 'has-feedback': hasError(routingConfig.ecsEnabled)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ecsEnabled">EDNS0 Client Subnet Enabled *<div class="helptooltip">
<div class="helptext">Disabled by default, enabling this enables EDNS0 client subnet on the Delivery Service level.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="ecsEnabled" name="ecsEnabled" class="form-control" ng-model="deliveryService.ecsEnabled" required>
<option ng-value="true">Enabled</option>
<option ng-value="false">Disabled</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.ecsEnabled, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ecsEnabled != dsCurrent.ecsEnabled">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ecsEnabled ? 'Enabled' : 'Disabled'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoProvider), 'has-feedback': hasError(routingConfig.geoProvider)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoProvider">Geolocation Provider *<div class="helptooltip">
<div class="helptext">Choose which Geolocation database provider - company that collects data on the location of IP addresses - to use.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="geoProvider" name="geoProvider" class="form-control" ng-model="deliveryService.geoProvider" required>
<option ng-value="0" selected>MaxMind</option>
<option ng-value="1">Neustar</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoProvider, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoProvider != dsCurrent.geoProvider">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(geoProviders, dsCurrent.geoProvider)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.missLat), 'has-feedback': hasError(routingConfig.missLat)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="missLat">Geo Miss Default Latitude *<div class="helptooltip">
<div class="helptext">Default latitude for this Delivery Service. When client localization fails for both Coverage Zone and Geo Lookup, the client will be routed as if it was at this latitude.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input step="any" id="missLat" name="missLat" type="number" class="form-control" ng-model="deliveryService.missLat" required min="-90" max="90" title="Must be a valid latitude, in degrees."/>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLat, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLat, 'min')">Too Small (must be greater than or equal to -90)</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLat, 'max')">Too Big (must be less than or equal to 90)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.missLat != dsCurrent.missLat">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.missLat}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.missLong), 'has-feedback': hasError(routingConfig.missLong)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="missLong">Geo Miss Default Longitude *<div class="helptooltip">
<div class="helptext">Default longitude for this Delivery Service. When client localization fails for both Coverage Zone and Geo Lookup, the client will be routed as if it was at this longitude.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input step="any" id="missLong" name="missLong" type="number" class="form-control" ng-model="deliveryService.missLong" required min="-180" max="180" title="Must be a valid longitude, in degrees."/>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLong, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLong, 'min')">Too Small (must be greater than or equal to -180)</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.missLong, 'max')">Too Big (must be less than or equal to 180)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.missLong != dsCurrent.missLong">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.missLong}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimit), 'has-feedback': hasError(routingConfig.geoLimit)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimit">Geo Limit *<div class="helptooltip">
<div class="helptext">
Some services are intended to be limited by geography. The possible settings are:
<br>
<br>
<dl>
<dt>None</dt><dd>Do not limit by geography.</dd>
<dt>Coverage Zone File only</dt><dd>If the requesting IP is not in the Coverage Zone File, do not serve the request.</dd>
<dt>Coverage Zone File and Country Code(s)</dt><dd>If the requesting IP is not in the Coverage Zone File or not in the United States, do not serve the request.</dd>
</dl>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="geoLimit" name="geoLimit" class="form-control" ng-model="deliveryService.geoLimit" required>
<option ng-value="0" selected>None</option>
<option ng-value="1">Coverage Zone File only</option>
<option ng-value="2">Coverage Zone File and Country Code(s)</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoLimit, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimit != dsCurrent.geoLimit">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(geoLimits, dsCurrent.geoLimit)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimitCountries), 'has-feedback': hasError(routingConfig.geoLimitCountries)}" ng-show="deliveryService.geoLimit === 1 || deliveryService.geoLimit === 2">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimitCountries">Geo Limit Countries<div class="helptooltip">
<div class="helptext">How (if at all) is this service to be limited by geography. Example Country Codes: <abbr title="Canada">CA</abbr>, <abbr title="India">IN</abbr>, <abbr title="Puerto Rico">PR</abbr>.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="geoLimitCountries" name="geoLimitCountries" type="text" class="form-control" ng-model="deliveryService.geoLimitCountries" maxlength="255" pattern="[A-Z]+(,[A-Z]+)*">
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoLimitCountries, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimitCountries != dsCurrent.geoLimitCountries">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.geoLimitCountries}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimitRedirectURL), 'has-feedback': hasError(routingConfig.geoLimitRedirectURL)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimitRedirectURL">Geo Limit Redirect URL<div class="helptooltip">
<div class="helptext">
Traffic Router will redirect to this URL when Geo Limit check fails.
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html?highlight=Geo%20Limit#geo-limit-redirect-url" target="_blank">GeoLimit Failure Redirect</a> feature...
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="geoLimitRedirectURL" name="geoLimitRedirectURL" title="Must be a valid URL" type="url" class="form-control" ng-model="deliveryService.geoLimitRedirectURL">
<small class="input-error invalid-URL-error">Invalid URL</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimitRedirectURL != dsCurrent.geoLimitRedirectURL">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.geoLimitRedirectURL}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.dnsBypassIp), 'has-feedback': hasError(routingConfig.dnsBypassIp)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="dnsBypassIp">DNS Bypass IP<div class="helptooltip">
<div class="helptext">
IPv4 address to which to overflow requests when the Max Mbps or Max Tps for this Delivery Service are exceeded.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="dnsBypassIp" name="dnsBypassIp" type="text" class="form-control" ng-model="deliveryService.dnsBypassIp" maxlength="255" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">
<small class="input-error" ng-show="hasPropertyError(routingConfig.dnsBypassIp, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.dnsBypassIp, 'pattern')">Invalid IP</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.dnsBypassIp != dsCurrent.dnsBypassIp">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.dnsBypassIp}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.dnsBypassIp6), 'has-feedback': hasError(routingConfig.dnsBypassIp6)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="dnsBypassIp6">DNS Bypass IPv6<div class="helptooltip">
<div class="helptext">
IPv6 address to which to overflow requests when the Max Mbps or Max Tps for this Delivery Service are exceeded.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="dnsBypassIp6" name="dnsBypassIp6" type="text" class="form-control" ng-model="deliveryService.dnsBypassIp6" maxlength="255">
<small class="input-error" ng-show="hasPropertyError(routingConfig.dnsBypassIp6, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.dnsBypassIp6 != dsCurrent.dnsBypassIp6">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.dnsBypassIp6}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.dnsBypassCname), 'has-feedback': hasError(routingConfig.dnsBypassCname)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="dnsBypassCname">DNS Bypass CNAME<div class="helptooltip">
<div class="helptext">
Domain name to which to overflow requests when the Max Mbps or Max Tps for this Delivery Service are exceeded.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="dnsBypassCname" name="dnsBypassCname" type="text" class="form-control" ng-model="deliveryService.dnsBypassCname" maxlength="255" pattern="\S*">
<small class="input-error" ng-show="hasPropertyError(routingConfig.dnsBypassCname, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.dnsBypassCname, 'pattern')">No spaces</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.dnsBypassCname != dsCurrent.dnsBypassCname">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.dnsBypassCname}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.dnsBypassTtl), 'has-feedback': hasError(routingConfig.dnsBypassTtl)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="dnsBypassTtl">DNS Bypass TTL<div class="helptooltip">
<div class="helptext"><abbr title="Time To Live">TTL</abbr> for the DNS bypass domain or IP address when thresholds are exceeded.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="dnsBypassTtl" name="dnsBypassTtl" type="number" class="form-control" ng-model="deliveryService.dnsBypassTtl" step="1" min="0">
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.dnsBypassTtl != dsCurrent.dnsBypassTtl">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.dnsBypassTtl}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.maxDnsAnswers), 'has-feedback': hasError(routingConfig.maxDnsAnswers)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="maxDnsAnswers">Max DNS Answers<div class="helptooltip">
<div class="helptext">
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#max-dns-answers"> ATS documentation on Max DNS Answers: DNS-routed Delivery Service</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="maxDnsAnswers" name="maxDnsAnswers" type="number" class="form-control" placeholder="Max number of IP addresses in DNS answer (0 means all)" ng-model="deliveryService.maxDnsAnswers" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(routingConfig.maxDnsAnswers, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.maxDnsAnswers != dsCurrent.maxDnsAnswers">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.maxDnsAnswers}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ccrDnsTtl), 'has-feedback': hasError(routingConfig.ccrDnsTtl)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ccrDnsTtl">Delivery Service DNS TTL<div class="helptooltip">
<div class="helptext">The <abbr title="Time To Live">TTL</abbr> on the DNS record for the Traffic Router A and AAAA records. Setting too high or too low will result in poor caching performance.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="ccrDnsTtl" name="ccrDnsTtl" type="number" class="form-control" ng-model="deliveryService.ccrDnsTtl" step="1" min="0">
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ccrDnsTtl != dsCurrent.ccrDnsTtl">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ccrDnsTtl}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.globalMaxMbps), 'has-feedback': hasError(routingConfig.globalMaxMbps)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="globalMaxMbps">Global Max Mbps<div class="helptooltip">
<div class="helptext">The maximum bits per second this Delivery Service can serve across all EDGE caches before traffic will be diverted to the bypass destination. For a DNS Delivery Service, the Bypass Ipv4 or Ipv6 will be used (depending on whether this was an A or AAAA request), and for HTTP Delivery Services the Bypass <abbr title="Fully Qualified Domain Name">FQDN</abbr> will be used.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="globalMaxMbps" name="globalMaxMbps" type="number" class="form-control" placeholder="Max megabits per second allowed globally" ng-model="deliveryService.globalMaxMbps" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(routingConfig.globalMaxMbps, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.globalMaxMbps != dsCurrent.globalMaxMbps">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.globalMaxMbps}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.globalMaxTps), 'has-feedback': hasError(routingConfig.globalMaxTps)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="globalMaxTps">Global Max Tps<div class="helptooltip">
<div class="helptext">The maximum transactions this Delivery Service can serve across all EDGE caches before traffic will be diverted to the bypass destination. For a DNS Delivery Service, the Bypass Ipv4 or Ipv6 will be used (depending on whether this was an A or AAAA request), and for HTTP Delivery Services the Bypass <abbr title="Fully Qualified Domain Name">FQDN</abbr> will be used.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="globalMaxTps" name="globalMaxTps" type="number" class="form-control" placeholder="Max transactions per second allowed globally" ng-model="deliveryService.globalMaxTps" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(routingConfig.globalMaxTps, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.globalMaxTps != dsCurrent.globalMaxTps">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.globalMaxTps}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.fqPacingRate), 'has-feedback': hasError(routingConfig.fqPacingRate)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="fqPacingRate">Fair Queueing Pacing Rate Bps<div class="helptooltip">
<div class="helptext">The maximum bytes per second a cache will deliver on any single TCP connection. This uses the Linux kernel's Fair Queuing (<code>setsockopt(SO_MAX_PACING_RATE)</code>) to limit the rate of delivery.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="fqPacingRate" name="fqPacingRate" type="number" class="form-control" placeholder="Rate-limit connections to this Bytes per second" ng-model="deliveryService.fqPacingRate" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(routingConfig.fqPacingRate, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.fqPacingRate != dsCurrent.fqPacingRate">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.fqPacingRate}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.trResponseHeaders), 'has-feedback': hasError(routingConfig.trResponseHeaders)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="trResponseHeaders">Traffic Router Additional Response Headers<div class="helptooltip">
<div class="helptext">
List of header name:value pairs. One name:value pair per line. Listed pairs will be included in all Traffic Router HTTP(S) responses.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="trResponseHeaders" name="trResponseHeaders" class="form-control" ng-model="deliveryService.trResponseHeaders" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.trResponseHeaders != dsCurrent.trResponseHeaders">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.trResponseHeaders}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.trRequestHeaders), 'has-feedback': hasError(routingConfig.trRequestHeaders)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="trRequestHeaders">Traffic Router Log Request Headers<div class="helptooltip">
<div class="helptext">
List of header keys. One header key per line. Listed headers will be included in Traffic Router access log entries under the <samp>rh=</samp> token.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="trRequestHeaders" name="trRequestHeaders" class="form-control" ng-model="deliveryService.trRequestHeaders" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.trRequestHeaders != dsCurrent.trRequestHeaders">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.trRequestHeaders}}</pre>
</aside>
</div>
</div>
</ng-form>
</fieldset>
<div class="modal-footer">
<button type="button" class="btn btn-danger" ng-if="!settings.isNew" ng-disabled="!deletable()" ng-click="confirmDelete(deliveryService)">{{settings.deleteLabel}}</button>
<button class="btn btn-success" ng-disabled="deliveryServiceForm.$pristine || deliveryServiceForm.$invalid || !saveable()" ng-click="save(deliveryService)">{{settings.saveLabel}}</button>
<button class="btn btn-primary" ng-if="settings.isRequest && fulfillable()" ng-disabled="deliveryServiceForm.$invalid || deliveryServiceForm.$dirty" ng-click="fulfillRequest(deliveryService)">Fulfill Request</button>
<button class="btn btn-primary" ng-if="settings.isRequest && dsRequest.status == 'pending'" ng-click="editStatus('complete')">Complete Request</button>
</div>
</form>
</div>
</div>