Leevid PowerCPS Server

Leevid PowerCPS Server™ speeds Internet access, enhances website performance, and delivers unprecedented web hosting capabilities.

什么是 Leevid PowerCPS Server?

Traffic Server is a high-performance web proxy cache that improves network efficiency and performance by caching frequently-accessed information at the edge of the network. This brings content physically closer to end users, while enabling faster delivery and reduced bandwidth use. Traffic Server is designed to improve content delivery for enterprises, Internet service providers (ISPs), backbone providers, and large intranets by maximizing existing and available bandwidth.

Administrators’ Guide

Apache Traffic Server™ speeds Internet access, enhances website performance, and delivers unprecedented web hosting capabilities.

This chapter discusses how:

Contents:

Getting Started

Before you start

Before you get started with Traffic Server you may have to decide which version you want to use. Traffic Server follows the Semantic Versioning guidelines, in summary

A version is made of a version-triplet: MAJOR.MINOR.PATCH

As of v4.0.0, there are no longer any development (or unstable) releases. All releases are considered stable and ready for production use, releases within a major version are always upgrade compatible. More details are available on the Wiki page.

Sometimes we speak of trunk, master or HEAD, all of which are used interchangeably: trunk or master or sometimes TIP or HEAD, refer to the latest code in a Git Version Control System. Master is always kept releasable, and compatible with the current major release version. Incompatible changes are sometimes committed on a next-major release branch, for example we have the 5.0.x branch where changes incompatible with 4.x are managed.

If your distribution does not come with a prepackaged Traffic Server, please go to downloads to choose the version that you consider most appropriate for yourself. If you want to really be on the bleeding edge you can clone our git repository.

Please note that while we do have a GitHub Mirror that you can also use to submit pull requests, it may not be entirely up-to-date.

Building Traffic Server

In order to build Traffic Server from source you will need the following (development) packages:

  • pkgconfig
  • libtool
  • gcc (>= 4.3 or clang > 3.0)
  • make (GNU Make!)
  • openssl
  • tcl
  • expat
  • pcre
  • libcap
  • flex (for TPROXY)
  • hwloc
  • lua
  • curses
  • curl (both for traffic_top)

if you’re building from a git clone, you’ll also need

  • git
  • autoconf
  • automake

We will show-case a build from git:

git clone https://git-wip-us.apache.org/repos/asf/trafficserver.git

Next, we cd trafficserver and run:

autoreconf -if

This will generate a configure file from configure.ac, so now we can run that:

./configure --prefix=/opt/ats

Note well, that by default Traffic Server uses the user nobody, as well as user’s primary group as Traffic Server user. If you want to change that, you can override it here:

./configure --prefix=/opt/ats --with-user=tserver

If dependencies are not in standard paths (/usr/local or /usr), you need to pass options to configure to account for that:

./configure --prefix=/opt/ats --with-user=tserver --with-lua=/opt/csw

Most configure path-options accept a format of "INCLUDE_PATH:LIBRARY_PATH":

./configure --prefix=/opt/ats --with-user=tserver --with-lua=/opt/csw \
   --with-pcre=/opt/csw/include:/opt/csw/lib/amd64

We can run make to build the project. We highly recommend to run make check to verify the build’s general sanity:

make
make check

We can finally run make install to install (you may have to switch to root to do this):

sudo make install

We also recommend to run a regression test. Please note that this will only work successfully with the default layout:

cd /opt/ats
sudo bin/traffic_server -R 1

After you have installed Traffic Server on your system, you can do any of the following:

Start Traffic Server

To start Traffic Server manually, issue the trafficserver command, passing in the attribute start. This command starts all the processes that work together to process Traffic Server requests as well as manage, control, and monitor the health of the Traffic Server system.

To run the trafficserver start command, e.g.:

bin/trafficserver start

At this point your server is up and running in the default configuration of a Reverse Proxy and HTTP Redirects.

Start Traffic Line

Traffic Line provides a quick way of viewing Traffic Server statistics and configuring the Traffic Server system via command-line interface. To execute individual commands or script multiple commands, refer to traffic_line.

Traffic Line commands take the following form:

bin/traffic_line -command argument

For a list of traffic_line commands, enter:

bin/traffic_line -h

Please note that traffic_line, while a fine tool for an administrator, is a poor choice for automation, especially that of monitoring. See our chapter on Monitoring Traffic for how to do that better.

Stop Traffic Server

To stop Traffic Server, always use the trafficserver command, passing in the attribute stop. This command stops all the Traffic Server processes (traffic_manager, traffic_server, and traffic_cop). Do not manually stop processes, as this can lead to unpredictable results.:

bin/trafficserver stop

HTTP Proxy Caching

Web proxy caching enables you to store copies of frequently-accessed web objects (such as documents, images, and articles) and then serve this information to users on demand. It improves performance and frees up Internet bandwidth for other tasks.

Understanding HTTP Web Proxy Caching

Internet users direct their requests to web servers all over the Internet. A caching server must act as a web proxy server so it can serve those requests. After a web proxy server receives requests for web objects, it either serves the requests or forwards them to the origin server (the web server that contains the original copy of the requested information). The Traffic Server proxy supports explicit proxy caching, in which the user’s client software must be configured to send requests directly to the Traffic Server proxy. The following overview illustrates how Traffic Server serves a request.

  1. Traffic Server receives a client request for a web object.

  2. Using the object address, Traffic Server tries to locate the requested object in its object database (cache).

  3. If the object is in the cache, then Traffic Server checks to see if the object is fresh enough to serve. If it is fresh, then Traffic Server serves it to the client as a cache hit (see the figure below).

    A cache hit

    A cache hit

  4. If the data in the cache is stale, then Traffic Server connects to the origin server and checks if the object is still fresh (a revalidation). If it is, then Traffic Server immediately sends the cached copy to the client.

  5. If the object is not in the cache (a cache miss) or if the server indicates the cached copy is no longer valid, then Traffic Server obtains the object from the origin server. The object is then simultaneously streamed to the client and the Traffic Server local cache (see the figure below). Subsequent requests for the object can be served faster because the object is retrieved directly from cache.

    A cache miss

    A cache miss

Caching is typically more complex than the preceding overview suggests. In particular, the overview does not discuss how Traffic Server ensures freshness, serves correct HTTP alternates, and treats requests for objects that cannot/should not be cached. The following sections discuss these issues in greater detail.

Ensuring Cached Object Freshness

When Traffic Server receives a request for a web object, it first tries to locate the requested object in its cache. If the object is in cache, then Traffic Server checks to see if the object is fresh enough to serve. For HTTP objects, Traffic Server supports optional author-specified expiration dates. Traffic Server adheres to these expiration dates; otherwise, it picks an expiration date based on how frequently the object is changing and on administrator-chosen freshness guidelines. Objects can also be revalidated by checking with the origin server to see if an object is still fresh.

HTTP Object Freshness

Traffic Server determines whether an HTTP object in the cache is fresh by:

  • Checking the Expires or max-age header

    Some HTTP objects contain Expires headers or max-age headers that explicitly define how long the object can be cached. Traffic Server compares the current time with the expiration time to determine if the object is still fresh.

  • Checking the Last-Modified / Date header

    If an HTTP object has no Expires header or max-age header, then Traffic Server can calculate a freshness limit using the following formula:

    freshness_limit = ( date - last_modified ) * 0.10
    

    where date is the date in the object’s server response header and last_modified is the date in the Last-Modified header. If there is no Last-Modified header, then Traffic Server uses the date the object was written to cache. The value 0.10 (10 percent) can be increased or reduced to better suit your needs (refer to Modifying Aging Factor for Freshness Computations).

    The computed freshness limit is bound by a minimum and maximum value - refer to Setting Absolute Freshness Limits for more information.

  • Checking the absolute freshness limit

    For HTTP objects that do not have Expires headers or do not have both Last-Modified and Date headers, Traffic Server uses a maximum and minimum freshness limit (refer to Setting Absolute Freshness Limits).

  • Checking revalidate rules in the cache.config file

    Revalidate rules apply freshness limits to specific HTTP objects. You can set freshness limits for objects originating from particular domains or IP addresses, objects with URLs that contain specified regular expressions, objects requested by particular clients, and so on (refer to cache.config).

Modifying Aging Factor for Freshness Computations

If an object does not contain any expiration information, then Traffic Server can estimate its freshness from the Last-Modified and Date headers. By default, Traffic Server stores an object for 10% of the time that elapsed since it last changed. You can increase or reduce the percentage according to your needs.

To modify the aging factor for freshness computations

  1. Change the value for proxy.config.http.cache.heuristic_lm_factor.
  2. Run the traffic_line -x command to apply the configuration changes.
Setting absolute Freshness Limits

Some objects do not have Expires headers or do not have both Last-Modified and Date headers. To control how long these objects are considered fresh in the cache, specify an absolute freshness limit.

To specify an absolute freshness limit

  1. Edit the variables
  2. Run the traffic_line -x command to apply the configuration changes.
Specifying Header Requirements

To further ensure freshness of the objects in the cache, configure Traffic Server to cache only objects with specific headers. By default, Traffic Server caches all objects (including objects with no headers); you should change the default setting only for specialized proxy situations. If you configure Traffic Server to cache only HTTP objects with Expires or max-age headers, then the cache hit rate will be noticeably reduced (since very few objects will have explicit expiration information).

To configure Traffic Server to cache objects with specific headers

  1. Change the value for proxy.config.http.cache.required_headers.
  2. Run the traffic_line -x command to apply the configuration changes.
Cache-Control Headers

Even though an object might be fresh in the cache, clients or servers often impose their own constraints that preclude retrieval of the object from the cache. For example, a client might request that a object not be retrieved from a cache, or if it does, then it cannot have been cached for more than 10 minutes. Traffic Server bases the servability of a cached object on Cache-Control headers that appear in both client requests and server responses. The following Cache-Control headers affect whether objects are served from cache:

  • The no-cache header, sent by clients, tells Traffic Server that it should not serve any objects directly from the cache; therefore, Traffic Server will always obtain the object from the origin server. You can configure Traffic Server to ignore client no-cache headers - refer to Configuring Traffic Server to Ignore Client no-cache Headers for more information.
  • The max-age header, sent by servers, is compared to the object age. If the age is less than max-age, then the object is fresh and can be served.
  • The min-fresh header, sent by clients, is an acceptable freshness tolerance. This means that the client wants the object to be at least this fresh. Unless a cached object remains fresh at least this long in the future, it is revalidated.
  • The max-stale header, sent by clients, permits Traffic Server to serve stale objects provided they are not too old. Some browsers might be willing to take slightly stale objects in exchange for improved performance, especially during periods of poor Internet availability.

Traffic Server applies Cache-Control servability criteria *after* HTTP freshness criteria. For example, an object might be considered fresh but will not be served if its age is greater than its max-age.

Revalidating HTTP Objects

When a client requests an HTTP object that is stale in the cache, Traffic Server revalidates the object. A revalidation is a query to the origin server to check if the object is unchanged. The result of a revalidation is one of the following:

  • If the object is still fresh, then Traffic Server resets its freshness limit and serves the object.
  • If a new copy of the object is available, then Traffic Server caches the new object (thereby replacing the stale copy) and simultaneously serves the object to the client.
  • If the object no longer exists on the origin server, then Traffic Server does not serve the cached copy.
  • If the origin server does not respond to the revalidation query, then Traffic Server serves the stale object along with a 111 Revalidation Failed warning.

By default, Traffic Server revalidates a requested HTTP object in the cache if it considers the object to be stale. Traffic Server evaluates object freshness as described in HTTP Object Freshness. You can reconfigure how Traffic Server evaluates freshness by selecting one of the following options:

  • Traffic Server considers all HTTP objects in the cache to be stale: always revalidate HTTP objects in the cache with the origin server.
  • Traffic Server considers all HTTP objects in the cache to be fresh: never revalidate HTTP objects in the cache with the origin server.
  • Traffic Server considers all HTTP objects without Expires or Cache-control headers to be stale: revalidate all HTTP objects without Expires or Cache-Control headers.

To configure how Traffic Server revalidates objects in the cache, you can set specific revalidation rules in cache.config.

To configure revalidation options

  1. Edit the following variable in records.config
  2. Run the traffic_line -x command to apply the configuration changes.
Scheduling Updates to Local Cache Content

To further increase performance and to ensure that HTTP objects are fresh in the cache, you can use the Scheduled Update option. This configures Traffic Server to load specific objects into the cache at scheduled times. You might find this especially beneficial in a reverse proxy setup, where you can preload content you anticipate will be in demand.

To use the Scheduled Update option, you must perform the following tasks.

  • Specify the list of URLs that contain the objects you want to schedule for update,
  • the time the update should take place,
  • and the recursion depth for the URL.
  • Enable the scheduled update option and configure optional retry settings.

Traffic Server uses the information you specify to determine URLs for which it is responsible. For each URL, Traffic Server derives all recursive URLs (if applicable) and then generates a unique URL list. Using this list, Traffic Server initiates an HTTP GET for each unaccessed URL. It ensures that it remains within the user-defined limits for HTTP concurrency at any given time. The system logs the completion of all HTTP GET operations so you can monitor the performance of this feature.

Traffic Server also provides a Force Immediate Update option that enables you to update URLs immediately without waiting for the specified update time to occur. You can use this option to test your scheduled update configuration (refer to Forcing an Immediate Update).

Configuring the Scheduled Update Option

To configure the scheduled update option

  1. Edit update.config to enter a line in the file for each URL you want to update.
  2. Edit the following variables
  3. Run the traffic_line -x command to apply the configuration changes.
Forcing an Immediate Update

Traffic Server provides a Force Immediate Update option that enables you to immediately verify the URLs listed in update.config. The Force Immediate Update option disregards the offset hour and interval set in update.config and immediately updates the URLs listed.

To configure the Force Immediate Update option

  1. Edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.

重要

When you enable the Force Immediate Update option, Traffic Server continually updates the URLs specified in update.config until you disable the option. To disable the Force Immediate Update option, set proxy.config.update.force to 0 (zero).

Pushing Content into the Cache

Traffic Server supports the HTTP PUSH method of content delivery. Using HTTP PUSH, you can deliver content directly into the cache without client requests.

Configuring Traffic Server for PUSH Requests

Before you can deliver content into your cache using HTTP PUSH, you must configure Traffic Server to accept PUSH requests.

To configure Traffic Server to accept PUSH requests

  1. Edit ip_allow.config to allow PUSH.
  2. Edit the following variable in records.config, enable the push_method.
  3. Run the command traffic_line -x to apply the configuration changes.
Understanding HTTP PUSH

PUSH uses the HTTP 1.1 message format. The body of a PUSH request contains the response header and response body that you want to place in the cache. The following is an example of a PUSH request:

PUSH http://www.company.com HTTP/1.0
Content-length: 84

HTTP/1.0 200 OK
Content-type: text/html
Content-length: 17

<HTML>
a
</HTML>

重要

Your header must include Content-length - Content-length must include both header and body byte count.

Tools that will help manage pushing

There is a perl script for pushing, tspush, which can help you understanding how to write scripts for pushing content yourself.

Pinning Content in the Cache

The Cache Pinning Option configures Traffic Server to keep certain HTTP objects in the cache for a specified time. You can use this option to ensure that the most popular objects are in cache when needed and to prevent Traffic Server from deleting important objects. Traffic Server observes Cache-Control headers and pins an object in the cache only if it is indeed cacheable.

To set cache pinning rules

  1. Make sure the following variable in records.config is set

  2. Add a rule in cache.config for each URL you want Traffic Server to pin in the cache. For example:

    url_regex=^https?://(www.)?apache.org/dev/ pin-in-cache=12h
  3. Run the command traffic_line -x to apply the configuration changes.

To Cache or Not to Cache?

When Traffic Server receives a request for a web object that is not in the cache, it retrieves the object from the origin server and serves it to the client. At the same time, Traffic Server checks if the object is cacheable before storing it in its cache to serve future requests.

Caching HTTP Objects

Traffic Server responds to caching directives from clients and origin servers, as well as directives you specify through configuration options and files.

Client Directives

By default, Traffic Server does not cache objects with the following request headers:

  • Authorization: header

  • Cache-Control: no-store header

  • Cache-Control: no-cache header

    To configure Traffic Server to ignore the Cache-Control: no-cache header, refer to Configuring Traffic Server to Ignore Client no-cache Headers

  • Cookie: header (for text objects)

    By default, Traffic Server caches objects served in response to requests that contain cookies (unless the object is text). You can configure Traffic Server to not cache cookied content of any type, cache all cookied content, or cache cookied content that is of image type only. For more information, refer to Caching Cookied Objects.

Configuring Traffic Server to Ignore Client no-cache Headers

By default, Traffic Server strictly observes client Cache-Control: no-cache directives. If a requested object contains a no-cache header, then Traffic Server forwards the request to the origin server even if it has a fresh copy in cache. You can configure Traffic Server to ignore client no-cache directives such that it ignores no-cache headers from client requests and serves the object from its cache.

To configure Traffic Server to ignore client no-cache headers

  1. Edit the following variable in records.config
  2. Run the command traffic_line -x to apply the configuration changes.
Origin Server Directives

By default, Traffic Server does not cache objects with the following response headers:

Configuring Traffic Server to Ignore Server no-cache Headers

By default, Traffic Server strictly observes Cache-Control: no-cache directives. A response from an origin server with a no-cache header is not stored in the cache and any previous copy of the object in the cache is removed. If you configure Traffic Server to ignore no-cache headers, then Traffic Server also ignores no-store headers. The default behavior of observing no-cache directives is appropriate in most cases.

To configure Traffic Server to ignore server no-cache headers

  1. Edit the variable proxy.config.http.cache.ignore_server_no_cache
  2. Run the command traffic_line -x to apply the configuration changes.
Configuring Traffic Server to Ignore WWW-Authenticate Headers

By default, Traffic Server does not cache objects that contain WWW-Authenticate response headers. The WWW-Authenticate header contains authentication parameters the client uses when preparing the authentication challenge response to an origin server.

When you configure Traffic Server to ignore origin server WWW-Authenticate headers, all objects with WWW-Authenticate headers are stored in the cache for future requests. However, the default behavior of not caching objects with WWW-Authenticate headers is appropriate in most cases. Only configure Traffic Server to ignore server WWW-Authenticate headers if you are knowledgeable about HTTP 1.1.

To configure Traffic Server to ignore server WWW-Authenticate headers

  1. Edit the variable proxy.config.http.cache.ignore_authentication
  2. Run the command traffic_line -x to apply the configuration changes.
Configuration Directives

In addition to client and origin server directives, Traffic Server responds to directives you specify through configuration options and files.

You can configure Traffic Server to do the following:

Disabling HTTP Object Caching

By default, Traffic Server caches all HTTP objects except those for which you have set never-cache as action rules in the cache.config file. You can disable HTTP object caching so that all HTTP objects are served directly from the origin server and never cached, as detailed below.

To disable HTTP object caching manually

  1. Set the variable proxy.config.http.enabled to 0.
  2. Run the command traffic_line -x to apply the configuration changes.
Caching Dynamic Content

A URL is considered dynamic if it ends in ``.asp`` or contains a question mark (?), a semicolon (;), or cgi. By default, Traffic Server caches dynamic content. You can configure the system to ignore dyanamic looking content, although this is recommended only if the content is truely dyanamic, but fails to advertise so with appropriate Cache-Control headers.

To configure Traffic Server’s cache behaviour in regard to dynamic content

  1. Edit the following variable in records.config
  2. Run the command traffic_line -x to apply the configuration changes.
Caching Cookied Objects

By default, Traffic Server caches objects served in response to requests that contain cookies. This is true for all types of objects except for text. Traffic Server does not cache cookied text content because object headers are stored along with the object, and personalized cookie header values could be saved with the object. With non-text objects, it is unlikely that personalized headers are delivered or used.

You can reconfigure Traffic Server to:

  • Not cache cookied content of any type.
  • Cache cookied content that is of image type only.
  • Cache all cookied content regardless of type.

To configure how Traffic Server caches cookied content

  1. Edit the variable proxy.config.http.cache.cache_responses_to_cookies
  2. Run the command traffic_line -x to apply the configuration changes.
Forcing Object Caching

You can force Traffic Server to cache specific URLs (including dynamic URLs) for a specified duration, regardless of Cache-Control response headers.

To force document caching

  1. Add a rule for each URL you want Traffic Server to pin to the cache cache.config:

    url_regex=^https?://(www.)?apache.org/dev/ ttl-in-cache=6h
  2. Run the command traffic_line -x to apply the configuration changes.

Caching HTTP Alternates

Some origin servers answer requests to the same URL with a variety of objects. The content of these objects can vary widely, according to whether a server delivers content for different languages, targets different browsers with different presentation styles, or provides different document formats (HTML, XML). Different versions of the same object are termed alternates and are cached by Traffic Server based on Vary response headers. You can specify additional request and response headers for specific Content-Types that Traffic Server will identify as alternates for caching. You can also limit the number of alternate versions of an object allowed in the cache.

Configuring How Traffic Server Caches Alternates

To configure how Traffic Server caches alternates, follow the steps below

  1. Edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.

注解

If you specify Cookie as the header field on which to vary in the above variables, make sure that the variable proxy.config.http.cache.cache_responses_to_cookies is set appropriately.

Limiting the Number of Alternates for an Object

You can limit the number of alternates Traffic Server can cache per object (the default is 3).

重要

Large numbers of alternates can affect Traffic Server cache performance because all alternates have the same URL. Although Traffic Server can look up the URL in the index very quickly, it must scan sequentially through available alternates in the object store.

To limit the number of alternates

  1. Edit the variable proxy.config.cache.limits.http.max_alts
  2. Run the command traffic_line -x to apply the configuration changes.
Using Congestion Control

The Congestion Control option enables you to configure Traffic Server to stop forwarding HTTP requests to origin servers when they become congested. Traffic Server then sends the client a message to retry the congested origin server later.

To use the Congestion Control option, you must perform the following tasks:

  1. Set the variable proxy.config.http.congestion_control.enabled to 1
    • Create rules in the congestion.config file to specify:
    • which origin servers Traffic Server tracks for congestion
    • the timeouts Traffic Server uses, depending on whether a server is congested
    • the page Traffic Server sends to the client when a server becomes congested
    • if Traffic Server tracks the origin servers per IP address or per hostname
  2. Run the command traffic_line -x to apply the configuration changes.
Using Transaction Buffering Control

By default I/O operations are run at full speed, as fast as either Traffic Server, the network, or the cache can go. This can be problematic for large objects if the client side connection is significantly slower. In such cases the content will be buffered in ram while waiting to be sent to the client. This could potentially also happen for POST requests if the client connection is fast and the origin server connection slow. If very large objects are being used this can cause the memory usage of Traffic Server to become very large.

This problem can be ameloriated by controlling the amount of buffer space used by a transaction. A high water and low water mark are set in terms of bytes used by the transaction. If the buffer space in use exceeds the high water mark, the connection is throttled to prevent additional external data from arriving. Internal operations continue to proceed at full speed until the buffer space in use drops below the low water mark and external data I/O is re-enabled.

Although this is intended primarily to limit the memory usage of Traffic Server it can also serve as a crude rate limiter by setting a buffer limit and then throttling the client side connection either externally or via a transform. This will cause the connection to the origin server to be limited to roughly the client side connection speed.

Traffic Server does network I/O in large chunks (32K or so) and therefore the granularity of transaction buffering control is limited to a similar precision.

The buffer size calculations include all elements in the transaction, including any buffers associated with transform plugins.

Transaction buffering control can be enabled globally by using configuration variables or by TSHttpTxnConfigIntSet() in a plugin.

Value Variable TSHttpTxnConfigIntSet key
Enable buffering proxy.config.http.flow_control.enabled TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED
Set high water proxy.config.http.flow_control.high_water TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER
Set low water proxy.config.http.flow_control.low_water TS_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER

Be careful to always have the low water mark equal or less than the high water mark. If you set only one, the other will be set to the same value.

If using TSHttpTxnConfigIntSet(), it must be called no later than TS_HTTP_READ_RESPONSE_HDR_HOOK.

Reducing Origin Server Requests (Avoiding the Thundering Herd)

When an object can not be served from cache, the request will be proxied to the origin server. For a popular object, this can result in many near simultaneous requests to the origin server, potentially overwhelming it or associated resources. There are several features in Traffic Server that can be used to avoid this scenario.

Read While Writer

When Traffic Server goes to fetch something from origin, and upon receiving the response, any number of clients can be allowed to start serving the partially filled cache object once background_fill_completed_threshold % of the object has been received. The difference is that Squid allows this as soon as it goes to origin, whereas ATS can not do it until we get the complete response header. The reason for this is that we make no distinction between cache refresh, and cold cache, so we have no way to know if a response is going to be cacheable, and therefore allow read-while-writer functionality.

The configurations necessary to enable this in ATS are:

All four configurations are required, for the following reasons:

  • enable_read_while_writer turns the feature on. It’s off (0) by default
  • The background fill feature should be allowed to kick in for every possible request. This is necessary, in case the writer (“first client session”) goes away, someone needs to take over the session. Hence, you should set the background fill timeouts and threshold to zero; this assures they never times out and always is allowed to kick in.
  • The proxy.config.cache.max_doc_size should be unlimited (set to 0), since the object size may be unknown, and going over this limit would cause a disconnect on the objects being served.

Once all this enabled, you have something that is very close, but not quite the same, as Squid’s Collapsed Forwarding.

Fuzzy Revalidation

Traffic Server can be set to attempt to revalidate an object before it becomes stale in cache. records.config contains the settings:

For every request for an object that occurs “fuzz.time” before (in the example above, 240 seconds) the object is set to become stale, there is a small chance (fuzz.probability == 0.5%) that the request will trigger a revalidation request to the origin. For objects getting a few requests per second, this would likely not trigger, but then this feature is not necessary anyways since odds are only 1 or a small number of connections would hit origin upon objects going stale. The defaults are a good compromise, for objects getting roughly 4 requests / second or more, it’s virtually guaranteed to trigger a revalidate event within the 240s. These configs are also overridable per remap rule or via a plugin, so can be adjusted per request if necessary.

Note that if the revalidation occurs, the requested object is no longer available to be served from cache. Subsequent requests for that object will be proxied to the origin.

Finally, the fuzz.min_time is there to be able to handle requests with a TTL less than fuzz.time – it allows for different times to evaluate the probability of revalidation for small TTLs and big TTLs. Objects with small TTLs will start “rolling the revalidation dice” near the fuzz.min_time, while objects with large TTLs would start at fuzz.time. A logarithmic like function between determines the revalidation evaluation start time (which will be between fuzz.min_time and fuzz.time). As the object gets closer to expiring, the window start becomes more likely. By default this setting is not enabled, but should be enabled anytime you have objects with small TTLs. Note that this option predates overridable configurations, so you can achieve something similar with a plugin or remap.config conf_remap.so configs.

These configurations are similar to Squid’s refresh_stale_hit configuration option.

Open Read Retry Timeout

The open read retry configurations attempt to reduce the number of concurrent requests to the origin for a given object. While an object is being fetched from the origin server, subsequent requests would wait open_read_retry_time milliseconds before checking if the object can be served from cache. If the object is still being fetched, the subsequent requests will retry max_open_read_retries times. Thus, subsequent requests may wait a total of (max_open_read_retries x open_read_retry_time) milliseconds before establishing an origin connection of its own. For instance, if they are set to 5 and 10 respectively, connections will wait up to 50ms for a response to come back from origin from a previous request, until this request is allowed through.

These settings are inappropriate when objects are uncacheable. In those cases, requests for an object effectively become serialized. The subsequent requests would await at least open_read_retry_time milliseconds before being proxies to the origin.

Similarly, this setting should be used in conjunction with Read While Writer for big (those that take longer than (max_open_read_retries x open_read_retry_time) milliseconds to transfer) cacheable objects. Without the read-while-writer settings enabled, while the initial fetch is ongoing, not only would subsequent requests be delayed by the maximum time, but also, those requests would result in another request to the origin server.

Since ATS now supports setting these settings per-request or remap rule, you can configure this to be suitable for your setup much more easily.

The configurations are (with defaults):

CONFIG proxy.config.http.cache.max_open_read_retries INT -1
CONFIG proxy.config.http.cache.open_read_retry_time INT 10

The default means that the feature is disabled, and every connection is allowed to go to origin instantly. When enabled, you will try max_open_read_retries times, each with a open_read_retry_time timeout.

Reverse Proxy and HTTP Redirects

Reverse Proxy and HTTP Redirects

As a reverse proxy cache, Traffic Server serves requests on behalf of origin servers. Traffic Server is configured in such a way that it appears to clients like a normal origin server.

Understanding Reverse Proxy Caching

With forward proxy caching, Traffic Server handles web requests to distant origin servers on behalf of the clients requesting the content. Reverse proxy caching (also known as server acceleration or virtual web hosting) is different because Traffic Server acts as a proxy cache on behalf of the origin servers that store the content. Traffic Server is configured to be the origin server which the client is trying to connect to. In a typical scenario the advertised hostname of the origin server resolves to Traffic Server, which acts as the real origin server.

Reverse Proxy Solutions

There are many ways to use Traffic Server as a reverse proxy. Below are a few example scenarios.

You can use Traffic Server in reverse proxy mode to:

  • Offload heavily-used origin servers
  • Deliver content efficiently in geographically distant areas
  • Provide security for origin servers that contain sensitive information
Offloading Heavily-Used Origin Servers

Traffic Server can absorb requests to the main origin server and improve the speed & quality of web serving by reducing load and hot spots on backup origin servers. For example, a web hoster can maintain a scalable Traffic Server serving engine with a set of low-cost, low-performance, less-reliable PC origin servers as backup servers. In fact, a single Traffic Server can act as the virtual origin server for multiple backup origin servers, as shown in the figure below.

Traffic Server as reverse proxy for a pair of origin servers

Traffic Server as reverse proxy for a pair of origin servers

Delivering Content in Geographically-Dispersed Areas

Traffic Server can be used in reverse proxy mode to accelerate origin servers that provide content to areas not located within close geographical proximity. Caches are typically easier to manage and are more cost-effective than replicating data. For example, Traffic Server can be used as a mirror site on the far side of a trans-Atlantic link to serve users without having to fetch the request and content across expensive international connections. Unlike replication, for which hardware must be configured to replicate all data and to handle peak capacity, Traffic Server dynamically adjusts to optimally use the serving and storing capacity of the hardware. Traffic Server is also designed to keep content fresh automatically, thereby eliminating the complexity of updating remote origin servers.

Providing Security for an Origin Server

Traffic Server can be used in reverse proxy mode to provide security for an origin server. If an origin server contains sensitive information that you want to keep secure inside your firewall, then you can use a Traffic Server outside the firewall as a reverse proxy for that origin server. When outside clients try to access the origin server, the requests instead go to Traffic Server. If the desired content is not sensitive, then it can be served from the cache. If the content is sensitive and not cacheable, then Traffic Server obtains the content from the origin server (the firewall allows only Traffic Server access to the origin server). The sensitive content resides on the origin server, safely inside the firewall.

How Does Reverse Proxy Work?

When a browser makes a request, it normally sends that request directly to the origin server. When Traffic Server is in reverse proxy mode, it intercepts the request before it reaches the origin server. Typically, this is done by setting up the DNS entry for the origin server (i.e., the origin server’s ‘advertised’ hostname) so it resolves to the Traffic Server IP address. When Traffic Server is configured as the origin server, the browser connects to Traffic Server rather than the origin server. For additional information, see HTTP Reverse Proxy.

注解

To avoid a DNS conflict, the origin server’s hostname and its advertised hostname must not be the same.

HTTP Reverse Proxy

In reverse proxy mode, Traffic Server serves HTTP requests on behalf of a web server. The figure below illustrates how Traffic Server in reverse proxy mode serves an HTTP request from a client browser.

HTTP reverse proxy

HTTP reverse proxy

The figure above demonstrates the following steps:

  1. A client browser sends an HTTP request addressed to a host called www.host.com on port 80. Traffic Server receives the request because it is acting as the origin server (the origin server’s advertised hostname resolves to Traffic Server).
  2. Traffic Server locates a map rule in the remap.config file and remaps the request to the specified origin server (realhost.com).
  3. Traffic Server opens an HTTP connection to the origin server. (If the request is not able to be served from cache)
  4. If the request is a cache hit and the content is fresh, then Traffic Server sends the requested object to the client from the cache. Otherwise, Traffic Server obtains the requested object from the origin server, sends the object to the client, and saves a copy in its cache.

To configure HTTP reverse proxy, you must perform the following tasks:

In addition to the tasks above, you can also Setting Optional HTTP Reverse Proxy Options.

Handling Origin Server Redirect Responses

Origin servers often send redirect responses back to browsers redirecting them to different pages. For example, if an origin server is overloaded, then it might redirect browsers to a less loaded server. Origin servers also redirect when web pages that have moved to different locations. When Traffic Server is configured as a reverse proxy, it must readdress redirects from origin servers so that browsers are redirected to Traffic Server and not to another origin server.

To readdress redirects, Traffic Server uses reverse-map rules. Unless you have proxy.config.url_remap.pristine_host_hdr enabled (the default) you should generally set up a reverse-map rule for each map rule. To create reverse-map rules, refer to Using Mapping Rules for HTTP Requests.

Using Mapping Rules for HTTP Requests

Traffic Server uses two types of mapping rules for HTTP reverse proxy.

map rule

A map rule translates the URL in client requests into the URL where the content is located. When Traffic Server is in reverse proxy mode and receives an HTTP client request, it first constructs a complete request URL from the relative URL and its headers. Traffic Server then looks for a match by comparing the complete request URL with its list of target URLs in the remap.config file. For the request URL to match a target URL, the following conditions must be true:

  • The scheme of both URLs must be the same
  • The host in both URLs must be the same. If the request URL contains an unqualified hostname, then it will never match a target URL with a fully-qualified hostname.
  • The ports in both URLs must be the same. If no port is specified in a URL, then the default port for the scheme of the URL is used.
  • The path portion of the target URL must match a prefix of the request URL path

If Traffic Server finds a match, then it translates the request URL into the replacement URL listed in the map rule: it sets the host and path of the request URL to match the replacement URL. If the URL contains path prefixes, then Traffic Server removes the prefix of the path that matches the target URL path and substitutes it with the path from the replacement URL. If two mappings match a request URL, then Traffic Server applies the first mapping listed in the remap.config file.

reverse-map rule

A reverse-map rule translates the URL in origin server redirect responses to point to Traffic Server so that clients are redirected to Traffic Server instead of accessing an origin server directly. For example, if there is a directory /pub on an origin server at www.molasses.com and a client sends a request to that origin server for /pub, then the origin server might reply with a redirect by sending the Header Location: http://www.test.com/pub/ to let the client know that it was a directory it had requested, not a document (a common use of redirects is to normalize URLs so that clients can bookmark documents properly).

Traffic Server uses reverse_map rules to prevent clients (that receive redirects from origin servers) from bypassing Traffic Server and directly accessing the origin servers. In many cases the client would be hitting a wall because realhost.com actually does not resolve for the client. (E.g.: Because it’s running on a port shielded by a firewall, or because it’s running on a non-routable LAN IP)

Both map and reverse-map rules consist of a target (origin) URL and a replacement (destination) URL. In a map rule, the target URL points to Traffic Server and the replacement URL specifies where the original content is located. In a reverse-map rule, the target URL specifies where the original content is located and the replacement URL points to Traffic Server. Traffic Server stores mapping rules in the remap.config file located in the Traffic Server config directory.

Creating Mapping Rules for HTTP Requests

To create mapping rules

  1. Enter the map and reverse-map rules into the remap.config file
  2. Run the command traffic_line -x to apply the configuration changes.
Enabling HTTP Reverse Proxy

To enable HTTP reverse proxy, follow the steps below.

  1. Edit the following variable in records.config
  2. Run the command traffic_line -x to apply the configuration changes.
Setting Optional HTTP Reverse Proxy Options

Traffic Server provides several reverse proxy configuration options in records.config that enable you to:

Don’t forget to run the command traffic_line -x to apply the configuration changes.

Redirecting HTTP Requests

You can configure Traffic Server to redirect HTTP requests without having to contact any origin servers. For example, if you redirect all requests for http://www.ultraseek.com to http://www.server1.com/products/portal/search/, then all HTTP requests for www.ultraseek.com go directly to www.server1.com/products/portal/search.

You can configure Traffic Server to perform permanent or temporary redirects. Permanent redirects notify the browser of the URL change (by returning the HTTP status code ``301``) so that the browser can update bookmarks. Temporary redirects notify the browser of the URL change for the current request only (by returning the HTTP status code ``307`` ).

To set redirect rules

  1. For each redirect you want to set enter a mapping rule in the remap.config file
  2. Run the command traffic_line -x to apply the configuration changes.
Example

The following permanently redirects all HTTP requests for www.server1.com to www.server2.com:

redirect http://www.server1.com http://www.server2.com

Forward Proxy

The Apache Traffic Server is a general purpose proxy. As such it can also be used as forward proxy.

A forward proxy is can be used as a central tool in your infrastructure to access the web. In combination with a cache that means overall reduced bandwidth usage.

If your forward proxy is not also configured as Transparent Proxying your clients will have to be configured to actually use it.

The main difference between a forward and a transparent proxy is that User Agents know that they are accessing a proxy, thus forming their requests like so:

GET http://example.com/index.php?id=1337 HTTP/1.1

This request, then is translated by the proxy to:

GET /index?id=1337 HTTP/1.1
Host: example.com

Apache Traffic Server offers two ways to User Agents: They can either be pointed directly to the default 8080 port. Alternatively, they can be pointed to the more dynamic proxy.config.url_remap.default_to_server_pac

This port will then serve a JavaScript like configuration that User Agents can use to determine where to send their requests to.

Configuration

In order to configure Apache Traffic Server as forward proxy you will have to edit records.config and set

If your proxy is serving as pure forward proxy, you will also want to set

Other configuration variables to consider:

Security Considerations

It’s important to note that once your Apache Traffic Server is configured as forward proxy it will indiscriminately accept proxy requests from anyone. That means, if it’s reachable on the internet, you have configured an Open Proxy. Most of the time, this is not what you want, so you’ll have to make sure it’s either only reachable within your NAT or is secured by firewall rules that permit only those clients to access it which you want to it to access.

Transparent Proxying

Building ATS for transparency

In most cases, if your environment supports transparency then configure will automatically enable it. For other environments you may need to twiddle the configure options.

--enable-posix-cap
This enables POSIX capabilities, which are required for transparency. These are compiled in by default. To check your system, look for the header file sys/capability.h and the system library libcap. These are in the packages libcap and libcap-devel or libcap-dev (depending on the Distribution) contra-respectively.
--enable-tproxy[=value]
Enable TPROXY support, which is the Linux kernel feature used for transparency. This should be present in the base installation, there is no package associated with it. * auto Do automatic checks for the the TPROXY header file (linux/in.h) and enable TPROXY support if the IP_TRANSPARENT definition is present. This is the default if this option is not specified or value is omitted. * no Do not check for TPROXY support, disable support for it. * force Do not check for TPROXY support, enable it using the $ats@ built in value for IP_TRANSPARENT. This is useful for systems that have it in the kernel for but some reason do not have the appropriate system header file. * number Do not check for TPROXY support, use number as the IP_TRANSPARENT value. There are, at present, no known standard distributions of Linux that support TPROXY but use a value different from the built in ATS default. However, a custom built kernel may do so and in that case the specific value can be specified.

In the default case, ATS configuration will automatically check for TPROXY support via the presence of the linux/in.h header file and compile in TPROXY support if it is available. If that fails, you may be able to recover by using one of the options above. Note that transparency may be built in by default but it is not active unless explicitly enabled in the ATS configuration files.

Inline on a Linux Bridge

A Linux can be configured to operate in bridge mode. Two or more physical interfaces are assigned to the bridge. A single IP address is shared across the interfaces. By default any packet that arrives on one interface is immediately routed out another bridge interface.

Linux packages required:

  • bridge-utils
  • ebtables

In our example of setting up bridge mode we will use a local address of 192.168.1.11/24 and interfaces eth0 and eth1 as the bridge interfaces (more detailed documentation is available here). You may omit the ‘#’ character and everything after it.

brctl addbr br0 # create bridge device
brctl stp br0 off # Disable spanning tree protocol
brctl addif br0 eth0 # Add eth0 to bridge
brctl addif br0 eth1 # Add eth1 to bridge

ifconfig eth0 0 0.0.0.0 # Get rid of interface IP addresses
ifconfig eth1 0 0.0.0.0 # ditto # Set the bridge IP address and enable it
ifconfig br0 192.168.1.11 netmask 255.255.255.0 up

If you have not already done so, remember to add a default route, such as this one for a gateway of 192.168.1.1.

ip route add default via 192.168.1.1

At this point it is a good idea to test connectivity to verify the basic bridge is functional.

Once the bridge is verified to work, this is the basic traffic pattern of interest.

Picture of traffic flow through a bridge with ATS

Picture of traffic flow through a bridge with ATS

The green arrows are packets originating from the client and the red arrows are packets originating from the origin server. All traffic not directed to the local address will pass through the bridge. We need to break into some of the traffic and subject it to routing so that it can be routed to ATS. This requires ebtables. The flows we want to intercept are green 1 (from client to bridge) and red 1 (origin server to bridge).

In this example we will intercept port 80 (HTTP) traffic. We will use the BROUTING chain because it is traversed only for packets that originated externally and arrived on a (forwarding enabled) interface. Although it looks like this will intercept all port 80 traffic it will only affect the two flows described above. -j redirect marks the packet as being diverted to the bridge and not forwarded, and the DROP target puts the packets in the normal iptables routing so that we can use standard device tests on them [1]. Although this example handles only port 80, other ports are the same except for the port value. Note also the port here is the port from the point of view of the clients and origin servers, not the Traffic Server server port.

ebtables -t broute -F # Flush the table
# inbound traffic
ebtables -t broute -A BROUTING -p IPv4 --ip-proto tcp --ip-dport 80 \
  -j redirect --redirect-target DROP
# returning outbound traffic
ebtables -t broute -A BROUTING -p IPv4 --ip-proto tcp --ip-sport 80 \
  -j redirect --redirect-target DROP

Traffic Server operates at layer 3 so we need to use iptables to handle IP packets appropriately.:

iptables -t mangle -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 \
  -j TPROXY --on-ip 0.0.0.0 --on-port 8080 --tproxy-mark 1/1
iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --sport 80 \
   -j MARK --set-mark 1/1

At this point the directionality of the interfaces matters. For the example eth1 is the inbound (client side) interface, while eth0 is the outbound (origin server side) interface. We mark both flows of packets so that we can use policy routing on them. For inbound packets we need to use TPROXY to force acceptance of packets to foreign IP addresses. For returning outbound packets there will be a socket open bound to the foreign address, we need only force it to be delivered locally. The value for --on-ip is 0 because the target port is listening and not bound to a specific address. The value for --on-port must match the Traffic Server server port. Otherwise its value is arbitrary. --dport and --sport specify the port from the point of view of the clients and origin servers.

Once the flows are marked we can force them to be delivered locally via the loopback interface via a policy routing table.:

ip rule add fwmark 1/1 table 1
ip route add local 0.0.0.0/0 dev lo table 1

The marking used is arbitrary but it must be consistent between iptables and the routing rule. The table number must be in the range 1..253.

To configure Traffic Server set the following values in records.config

You may also need to set proxy.config.cluster.ethernet_interface to “br0” (the name of the bridge interface from the BridgeCommands).

Additional troubleshooting
  • Check to make sure that iptables is not filtering (blocking) incoming HTTP connections.

    It is frequently the case that the default tables prevent incoming HTTP. You can clear all filters with the commands:

    iptables -t filter --flush FORWARD
    iptables -t filter --flush INPUT

    That is a bit drastic and should only be used for testing / debugging. A live system will likely need some filters in place but that is beyond the scope of this document. If this fixes the problem, then your filter set is too restrictive.

    Note that this problem will prevent the basic bridge (without ATS) from allowing HTTP traffic through.

  • Verify that IP packet forwarding is enabled.

    You can check this with:

    cat /proc/sys/net/ipv4/ip_forward
    

    The output should be a non-zero value (usually ‘1’). If it is zero, you can set it with:

    echo '1' > /proc/sys/net/ipv4/ip_forward

    This can setting can be persisted by putting it in /etc/sysctl.conf:

    net/ipv4/ip_forward=1
    

Footnotes

[1]The --redirect-target can be omitted, but then the iptables rules would need to use --physdev instead of just -i. The actual packet processing is identical.
Inline on a Linux router

The routed set up presumes the set of clients are on distinct networks behind a single physical interface. For the purposes of this example will we presume

  • The clients are on network 172.28.56.0/24
  • The router connects the networks 172.28.56.0/24 and 192.168.1.0/24
  • Interface eth0 is on the network 192.168.1.0/24
  • Interface eth1 is on the network 172.28.56.0/24
  • The router is already configured to route traffic correctly for the clients.

In this example we will intercept port 80 (HTTP) traffic that traverses the router. The first step is to use iptables to handle IP packets appropriately.

# reflow client web traffic to TPROXY
iptables -t mangle -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j TPROXY \
   --on-ip 0.0.0.0 --on-port 8080 --tproxy-mark 1/1
# Let locally directed traffic pass through.
iptables -t mangle -A PREROUTING -i eth0 --source 192.168.56.0/24 -j ACCEPT
iptables -t mangle -A PREROUTING -i eth0 --destination 192.168.56.0/24 -j ACCEPT
# Mark presumed return web traffic
iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --sport 80 -j MARK --set-mark 1/1

We mark packets so that we can use policy routing on them. For inbound packets we use TPROXY to make it possible to accept packets sent to foreign IP addresses. For returning outbound packets there will be a socket open bound to the foreign address, we need only force it to be delivered locally. The value for --on-ip is 0 because the target port is listening and not bound to a specific address. The value for --on-port must match the Traffic Server server port. Otherwise its value is arbitrary. --dport and --sport specify the port from the point of view of the clients and origin servers. The middle two lines exempt local web traffic from being marked for Traffic Server – these rules can be tightened or loosened as needed. They server by matching traffic and exiting the iptables processing via ACCEPT before the last line is checked.

Once the flows are marked we can force them to be delivered locally via the loopback interface via a policy routing table.

ip rule add fwmark 1/1 table 1
ip route add local 0.0.0.0/0 dev lo table 1

The marking used is arbitrary but it must be consistent between iptables and the routing rule. The table number must be in the range 1..253.

To configure Traffic Server set the following values in records.config

proxy.config.http.server_port
STRING Default: value from --on-port
proxy.config.http.server_port_attr
STRING Default: =
proxy.config.reverse_proxy.enabled
INT Default: 1
proxy.config.url_remap.remap_required
INT Default: 0
WCCP Configuration

WCCP is de-facto semi-standard used by routers to redirect network traffic to caches. It is available on most Cisco™ routers although it does not appear to be officially supported by Cisco. The primary benefits of WCCP are

  • If already have a router that supports WCCP inline you do not have to change your network topology.
  • WCCP fails open so that if the Traffic Server machine fails, it is bypassed and users continue to have Internet access.

Use of WCCP only makes sense for client side transparency [1] because if the clients are explicitly proxied by Traffic Server there’s no benefit to WCCP fail open, as the clients will continue to directly access the unresponsive Traffic Server host. It would be better to adjust the routing tables on the router for explicit proxying.

Because the router serves as the inline network element, Traffic Server must run on a separate host. This host can be located anywhere as long as Traffic Server is either on the same network segment or a GRE tunnel can be maintained between the Traffic Server host and the router.

important This document presumes that the router is already properly configured to handle traffic between the clients and the origin servers. If you are not certain, verify it before attempting to configure Traffic Server with WCCP. This is also a good state to which to revert should the configuration go badly.

Configuration overview

Setting WCCP is a three step process, first configuring the router, the Traffic Server host, and Traffic Server.

image1 The router will not respond to WCCP protocol packets unless explicitly configured to do so. Via WCCP, the router can be made to perform packet interception and redirection needed by Traffic Server transparency. The WCCP protocol in effect acts as means of controlling a rough form of policy routing with positive heartbeat cutoff.

The Traffic Server host system must also be configured using iptables to accept connections on foreign addresses. This is done roughly the same way as the standard transparency use.

Finally Traffic Server itself must be configured for transparency and use of WCCP. The former is again very similar to the standard use, while WCCP configuration is specific to WCCP and uses a separate configuration file, referred to by the records.config file.

The primary concern for configuration in which of three basic topologies are to be used.

  • Dedicated – Traffic Server traffic goes over an interface that is not used for client nor origin server traffic.
  • Shared – Traffic Server traffic shares an interface with client or server traffic.
  • Inside Shared – Traffic Server and client traffic share an interface.
  • Outside Shared – Traffic Server and origin server traffic share an interface.

In general the dedicated topology is preferred. However, if the router has only two interfaces one of the shared topologies will be required [2] Click the links above for more detailed configuration information on a specific topology.

Shared interface issues

A shared interface topology has additional issues compared to a dedicated topology that must be handled. Such a topology is required if the router has only two interfaces, and because of these additional issues it is normally only used in such cases, although nothing prevents it use even if the router has three or more interfaces.

The basic concept for a shared interface is to use a tunnel to simulate the dedicated interface case. This enables the packets to be distinguished at layer 3. For this reason, layer 2 redirection cannot be used because the WCCP configuration cannot distinguish between packets returning from the origin server and packets returning from Traffic Server as they are distinguished only by layer 2 addressing [3]. Fortunately the GRE tunnel used for packet forwarding and return can be used as the simulated interface for Traffic Server.

Frequently encountered problems
MTU and fragmentation

In most cases the basic configuration using a tunnel in any topology can fail due to issues with fragmentation. The socket logic is unable to know that its packets will eventually be put in to a tunnel which will by its nature have a smaller MTU than the physical interface which it uses. This can lead to pathological behavior or outright failure as the packets sent are just a little too big. It is not possible to solve easily by changing the MTU on the physical interface because the tunnel interface uses that to compute its own MTU.

References
[1]Server side transparency should also be used, but it is not as significant. In its absence, however, origin servers may see the source address of connections suddenly change from the Traffic Server address to client addresses, which could cause problems. Further, the primary reason for not having server side transparency is to hide client addresses which is defeated if the Traffic Server host fails.
[2]If your router has only one interface, it’s hardly a router.
[3]This is not fundamentally impossible, as the packets are distinct in layer

Transparent Proxying is the ability of a proxy (such as ATS) to intercept connections between clients and servers without being visible.

The general network structure that will be used in this documentation looks like this –

ATS basic traffic flow of Transparent Proxy

ATS basic traffic flow of Transparent Proxy

There must be a gateway device through which passes all network traffic from the client to the Internet (or external cloud). The gateway is responsible for effectively splicing ATS in to selected streams of that traffic. Each traffic stream is split in to two, with ATS terminating both sides. That is, stream green-1, red-2, is split in to the green connection and the red connection. Note that ATS may or may not be on the gateway system, the redirected traffic can flow over other network infrastructure.

Because ATS uses two connections transparency can be set independently on the client and origin server (Internet / external cloud) side. We will define what is generally called “transparent proxy” as two aspects, inbound transparency and outbound transparency.

Inbound transparency is a proxy that is transparent to connections that are inbound to the proxy, i.e. a connection initiated by a client which connects to the proxy (green-1). Similarly, outbound transparency is a proxy that is transparent to connections that are outbound from the proxy, i.e. a connection initiated by the proxy to an origin server (red-2).

In most treatments these two types of transparency are treated as unitarily but that is not required. This implementation supports transparency independently on the two (client, origin server) sides (use cases.

It is critical to note that any transparency requires specialized routing and cannot be done solely by configuring ATS. ATS transparency also requires support from the Linux kernel and therefore currently only works on sufficiently recent Linux kernels that support the following features –

  • TPROXY
  • POSIX capabilities

In addition the specialized routing will require using iptables and in some cases ebtables.

Standard build procedures should work for transparency support but if not consult these more detailed instructions

Transparency is configured per server port not globally. This is done via the configuration values proxy.config.http.server_ports. In addition, proxy.config.reverse_proxy.enabled must be enabled if the client side is transparent. That should be fixed in a future patch.

In the first case use the attribute character (replacing the default ‘X’)

Attribute Transparency Style Reverse Proxy

=
Full transparency: either
>
Inbound (client) transparency: enabled
<
Outbound (origin server) transparency: either

In the outbound transparent case clients must connect directly to ATS either through an explicit proxy mechanism or by advertising the IP address of the ATS server via DNS as the origin server address.

Some tested scenarios –

Explicit Proxy Caching

If you want to use Traffic Server as an explicit proxy cache, you must configure client software (i.e., browsers) to send requests directly to Traffic Server.

If you do not configure Traffic Server to use the transparency option (with which client requests are intercepted en route to origin servers by a switch/router and rerouted to the Traffic Server machine), then clients must configure their web browsers to send HTTP requests to the Traffic Server proxy cache by configuring their browsers to download proxy configuration instructions from a PAC file (Proxy Auto-Configuration file).

Configuring Browsers Manually

To manually configure a browser to send HTTP requests to Traffic Server, clients must provide the following information:

  • The fully-qualified hostname or IP address of the Traffic Server node
  • The Traffic Server proxy server port (port 8080)

In addition, clients can specify not to use Traffic Server for certain sites - in such cases, requests to the listed sites go directly to the origin server. The procedures for manual configuration vary among browser versions; refer to specific browser documentation for complete proxy configuration instructions. You do not need to set any special configuration options on Traffic Server if you want to accept requests from manually-configured browsers.

Using a PAC File

A PAC file is a specialized JavaScript function definition that a browser calls to determine how requests are handled. Clients must specify (in their browser settings) the URL from which the PAC file is loaded. You can store a PAC file on Traffic Server (or on any server in your network) and then provide the URL for this file to your clients.

If you want to store a PAC file on the Traffic Server system, then you must perform the following configuration:

  • Either copy an existing PAC file into the Traffic Server config directory or enter a script that defines the proxy server configuration settings in the proxy.pac file provided. The file is empty by default. A sample script is provided in Sample PAC File.
  • Specify the port Traffic Server uses to serve the PAC file. The default port is 8083, see proxy.config.admin.autoconf_port.
Sample PAC File

The following sample PAC file instructs browsers to connect directly to all hosts without a fully-qualified domain name and to all hosts in the local domain. All other requests go to the Traffic Server named myproxy.company.com.:

function FindProxyForURL(url, host)
{
  if (isPlainHostName(host)) || (localHostOrDomainIs(host, ".company.com")) {
    return "DIRECT";
  }
  else
    return "PROXY myproxy.company.com:8080; DIRECT";
}

Hierarchical Caching

Understanding Cache Hierarchies

A cache hierarchy consists of cache levels that communicate with each other. Traffic Server supports several types of cache hierarchies. All cache hierarchies recognize the concept of parent and child. A parent cache is a cache higher up in the hierarchy, to which Traffic Server can forward requests. A child cache is a cache for which Traffic Server is a parent.

Traffic Server supports the following hierarchical caching options:

Parent Caching

If a Traffic Server node cannot find a requested object in its cache, then it searches a parent cache (which itself can search other caches) before finally retrieving the object from the origin server. You can configure a Traffic Server node to use one or more parent caches so that if one parent is unavailable, then another parent is availale to service requests. This is called Parent Failover. Traffic Server will support parent caching for HTTP and HTTPS requests.

Note: If you do not want all requests to go to the parent cache, then simply configure Traffic Server to route certain requests (such as requests containing specific URLs) directly to the origin server. Simply set parent proxy rules in parent.config

The figure below illustrates a simple cache hierarchy with a Traffic Server node configured to use a parent cache. In the following scenario, a client sends a request to a Traffic Server node that is a child in the cache hierarchy (because it’s configured to forward missed requests to a parent cache). The request is a cache miss, so Traffic Server then forwards the request to the parent cache, where it is a cache hit. The parent sends a copy of the content to the Traffic Server, where it is cached and then served to the client. Future requests for this content can now be served directly from the Traffic Server cache (until the data is stale or expired).

Parent caching

Parent caching

Note: If the request is a cache miss on the parent, then the parent retrieves the content from the origin server (or from another cache, depending on the parent’s configuration). The parent caches the content and then sends a copy to Traffic Server (its child), where it is cached and served to the client.

Parent Failover

Traffic Server supports use of several parent caches. This ensures that if one parent cache is not available, another parent cache can service client requests.

When you configure your Traffic Server to use more than one parent cache, Traffic Server detects when a parent is not available and sends missed requests to another parent cache. If you specify more than two parent caches, then the order in which the parent caches are queried depends upon the parent proxy rules configured in the file:parent.config configuration file. By default, the parent caches are queried in the order they are listed in the configuration file.

Configuring Traffic Server to Use a Parent Cache

To configure Traffic Server to use one or more parent caches, you must complete the following steps:

  • Enable the parent caching option.
  • Identify the parent cache you want to use to service missed requests. To use parent failover, you must identify more than one parent cache so that when a parent cache is unavailable, requests are sent to another parent cache.

注解

You need to configure the child cache only. No additional configuration is needed for the Traffic Server parent cache.

Configure Traffic Server to use a parent cache by editing the following variable proxy.config.http.parent_proxy_routing_enable in records.config file.

Edit the parent.config file located in the Traffic Server config directory to set parent proxy rules to specify the parent cache to which you want missed requests to be forwarded;

The following example configures Traffic Server to route all requests containing the regular expression politics and the path /viewpoint directly to the origin server (bypassing any parent hierarchies):

url_regex=politics prefix=/viewpoint go_direct=true

The following example configures Traffic Server to direct all missed requests with URLs beginning with http://host1 to the parent cache parent1. If parent1 cannot serve the requests, then requests are forwarded to parent2. Because round-robin=true, Traffic Server goes through the parent cache list in a round-robin based on client IP address.:

dest_host=host1 scheme=http parent="parent1;parent2" round-robin=strict

Run the command traffic_line -x to apply the configuration changes.

Configuring the Cache

The Traffic Server cache consists of a high-speed object database called the object store that indexes objects according to URLs and their associated headers.

The Traffic Server Cache

The Traffic Server cache consists of a high-speed object database called the object store. The object store indexes objects according to URLs and associated headers. This enables Traffic Server to store, retrieve, and serve not only web pages, but also parts of web pages - which provides optimum bandwidth savings. Using sophisticated object management, the object store can cache alternate versions of the same object (versions may differ because of dissimilar language or encoding types). It can also efficiently store very small and very large documents, thereby minimizing wasted space. When the cache is full, Traffic Server removes stale data to ensure the most requested objects are kept readily available and fresh.

Traffic Server is designed to tolerate total disk failures on any of the cache disks. If the disk fails completely, then Traffic Server marks the entire disk as corrupt and continues using the remaining disks. An alarm is then created to indicate which disk failed. If all of the cache disks fail, then Traffic Server goes into proxy-only mode.

You can perform the following cache configuration tasks:

  • Change the total amount of disk space allocated to the cache: refer to Changing Cache Capacity.
  • Partition the cache by reserving cache disk space for specific protocols and origin servers/domains: refer to Partitioning the Cache.
  • Delete all data in the cache: refer to Clearing the Cache.
  • Override cache directives for a requested domain name, regex on a url, hostname or ip, with extra filters for time, port, method of the request (and more). ATS can be configured to never cache; always cache; ignore no-cache directives, etc. These are configured in cache.config.
The RAM Cache

Traffic Server maintains a small RAM cache of extremely popular objects. This RAM cache serves the most popular objects as quickly as possible and reduces load on disks, especially during temporary traffic peaks. You can configure the RAM cache size to suit your needs, as described in Changing the Size of the RAM Cache below.

The RAM cache supports two cache eviction algorithms, a regular LRU (Least Recently Used) and the more advanced CLFUS (Clocked Least Frequently Used by Size, which balances recentness, frequency and size to maximize hit rate – similar to a most frequently used algorithm). The default is to use CLFUS, and this is controlled via proxy.config.cache.ram_cache.algorithm.

Both the LRU and CLFUS RAM caches support a configuration to increase scan resistance. In a typical LRU, if you request all possible objects in sequence, you will effectively churn the cache on every request. The option proxy.config.cache.ram_cache.use_seen_filter can be set to add some resistance against this problem.

In addition, CLFUS also supports compressing in the RAM cache itself. This can be useful for content which is not compressed by itself (e.g. images). This should not be confused with Content-Encoding: gzip, this feature is only thereto save space internally in the RAM cache itself. As such, it is completely transparent to the User-Agent. The RAM cache compression is enabled with the option proxy.config.cache.ram_cache.compress. The default is 0, which means no compression. Other possible values are 1 for fastlz, 2 for libz and 3 for liblzma.

Changing the Size of the RAM Cache

Traffic Server provides a dedicated RAM cache for fast retrieval of popular small objects. The default RAM cache size is automatically calculated based on the number and size of the cache partitions you have configured. If you’ve partitioned your cache according to protocol and/or hosts, then the size of the RAM cache for each partition is proportional to the size of that partition.

You can increase the RAM cache size for better cache hit performance. However, if you increase the size of the RAM cache and observe a decrease in performance (such as increased latencies), then it’s possible that the operating system requires more memory for network resources. In such instances, you should return the RAM cache size to its previous value.

To change the RAM cache size:

  1. Stop Traffic Server.
  2. Set the variable proxy.config.cache.ram_cache.size to specify the size of the RAM cache. The default value of -1 means that the RAM cache is automatically sized at approximately 1MB per gigabyte of disk.
  3. Restart Traffic Server. If you increase the RAM cache to a size of 1GB or more, then restart with the trafficserver command (refer to Start Traffic Server).
Changing Cache Capacity

You can increase or reduce the total amount of disk space allocated to the cache without clearing the content. To check the size of the cache (in bytes), enter the command traffic_line -r proxy.process.cache.bytes_total.

Increasing Cache Capacity

To increase the total amount of disk space allocated to the cache on existing disks or to add new disks to a Traffic Server node, follow the steps below:

  1. Stop Traffic Server.
  2. Add hardware, if necessary.
  3. Edit storage.config to increase the amount of disk space allocated to the cache on existing disks or describe the new hardware you are adding.
  4. Restart Traffic Server.
Reducing Cache Capacity

To reduce the total amount of disk space allocated to the cache on an existing disk or to remove disks from a Traffic Server node, follow the steps below:

  1. Stop Traffic Server.
  2. Remove hardware, if necessary.
  3. Edit storage.config to reduce the amount of disk space allocated to the cache on existing disks or delete the reference to the hardware you’re removing.
  4. Restart Traffic Server.

重要

In storage.config, a formatted or raw disk must be at least 128 MB.

Partitioning the Cache

You can manage your cache space more efficiently and restrict disk usage by creating cache volumes with different sizes for specific protocols. You can further configure these volumes to store data from specific origin servers and/or domains. The volume configuration must be the same on all nodes in a cluster.

Creating Cache Partitions for Specific Protocols

You can create separate volumes for your cache that vary in size to store content according to protocol. This ensures that a certain amount of disk space is always available for a particular protocol. Traffic Server currently supports the http partition type for HTTP objects.

To partition the cache according to protocol:

  1. Enter a line in the volume.config file for each volume you want to create
  2. Restart Traffic Server.
Making Changes to Partition Sizes and Protocols

After you’ve configured your cache volumes based on protocol, you can make changes to the configuration at any time. Before making changes, note the following:

  • You must stop Traffic Server before you change the cache volume size and protocol assignment.
  • When you increase the size of a volume, the contents of the volume are not deleted. However, when you reduce the size of a volume, the contents of the volume are deleted.
  • When you change the volume number, the volume is deleted and then recreated, even if the size and protocol type remain the same.
  • When you add new disks to your Traffic Server node, volume sizes specified in percentages will increase proportionately.
  • A lot of changes to volume sizes might result in disk fragmentation, which affects performance and hit rate. You should clear the cache before making many changes to cache volume sizes (refer to Clearing the Cache).
Partitioning the Cache According to Origin Server or Domain

After you have partitioned the cache according to size and protocol, you can assign the volumes you created to specific origin servers and/or domains. You can assign a volumes to a single origin server or to multiple origin servers. However, if a volumes is assigned to multiple origin servers, then there is no guarantee on the space available in the volumes for each origin server. Content is stored in the volumes according to popularity. In addition to assigning volumes to specific origin servers and domains, you must assign a generic volume to store content from all origin servers and domains that are not listed. This generic volume is also used if the partitions for a particular origin server or domain become corrupt. If you do not assign a generic volume, then Traffic Server will run in proxy-only mode.

注解

You do not need to stop Traffic Server before you assign volumes to particular hosts or domains. However, this type of configuration is time-consuming and can cause a spike in memory usage. Therefore, it’s best to configure partition assignment during periods of low traffic.

To partition the cache according to hostname and domain:

  1. Configure the cache volumes according to size and protocol, as described in Creating Cache Partitions for Specific Protocols.
  2. Create a separate volume based on protocol for each host and domain, as well as an additional generic partition to use for content that does not belong to these origin servers or domains. The volumes do not need to be the same size.
  3. Enter a line in the hosting.config file to allocate the volume(s) used for each origin server and/or domain
  4. Assign a generic volume to use for content that does not belong to any of the origin servers or domains listed in the file. If all volumes for a particular origin server become corrupt, then Traffic Server will also use the generic volume to store content for that origin server as per hosting.config.
  5. Run the command traffic_line -x to apply the configuration changes.
Configuring the Cache Object Size Limit

By default, Traffic Server allows objects of any size to be cached. You can change the default behavior and specify a size limit for objects in the cache via the steps below:

  1. Set proxy.config.cache.max_doc_size to specify the maximum size allowed for objects in the cache in bytes. 0 (zero) if you do not want a size limit.
  2. Run the command traffic_line -x to apply the configuration changes.
Clearing the Cache

When you clear the cache, you remove all data from the entire cache - including data in the host database. You should clear the cache before performing certain cache configuration tasks, such as partitioning. You cannot clear the cache when Traffic Server is running.

To clear the cache:

  1. Stop Traffic Server (refer to Stopping Traffic Server)

  2. Enter the following command to clear the cache:

    traffic_server -Cclear
    

    The clear command deletes all data in the object store and the host database. Traffic Server does not prompt you to confirm the deletion.

  3. Restart Traffic Server (refer to Starting Traffic Server).

Removing an Object From the Cache

Traffic Server accepts the custom HTTP request method PURGE when removing a specific object from cache. If the object is found in the cache and is successfully removed, then Traffic Server responds with a 200 OK HTTP message; otherwise, a 404 File Not Found message is returned.

In the following example, Traffic Server is running on the domain example.com and you want to remove the image remove_me.jpg from cache. Because by default we do not permit PURGE requests from any other IP, we connect to the daemon via localhost:

$ curl -X PURGE -H 'Host: example.com' -v "http://localhost/remove_me.jpg"
* About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 80 (#0)

> PURGE /remove_me.jpg HTTP/1.1
> User-Agent: curl/7.19.7
> Host: example.com
> Accept: */*
>
< HTTP/1.1 200 Ok
< Date: Thu, 08 Jan 2010 20:32:07 GMT
< Connection: keep-alive

The next time Traffic Server receives a request for the removed object, it will contact the origin server to retrieve it (i.e., it has been purged from the Traffic Server cache).

Note: The procedure above only removes an object from a specific Traffic Server cache. Users may still see the old (removed) content if it was cached by intermediary caches or by the end-users’ web browser.

Inspecting the Cache

Traffic Server provides a Cache Inspector utility that enables you to view, delete, and invalidate URLs in the cache (HTTP only). The Cache Inspector utility is a powerful tool that’s capable of deleting all the objects in your cache; therefore, make sure that only authorized administrators are allowed to access this utility, see Controlling Client Access to the Proxy Cache and the @src_ip option in remap.config.

Accessing the Cache Inspector Utility

To access the Cache Inspector utility, follow the steps below:

  1. Set proxy.config.http_ui_enabled to 1.

  2. To access the cache inspector in reverse proxy mode, you must add a remap rule to remap.config to expose the URL. This should be restricted to a limited set of hosts using the @src_ip option. To restrict access to the network 172.28.56.0/24, use

    map http://yourhost.com/myCI/ http://{cache} @action=allow @src_ip=172.28.56.1-172.28.56.254
  3. From the Traffic Server bin directory, enter the following command to re-read the configuration file: traffic_line -x

  4. Open your web browser and configure it to use your Traffic Server as a proxy server. Type the following URL:

    http://yourhost/myCI/
  5. The Cache page opens.

Using the Cache Page

The Cache page provides several options that enable you to view and delete the contents of your cache:

  • Click Lookup url to search for a particular URL in the cache. When Traffic Server finds the URL in the cache, it displays details about the object that corresponds to the URL (such as the header length and the number of alternates). From the display page, you can delete the URL from the cache.
  • Click Delete url to delete a particular URL or list of URLs from the cache. Traffic Server indicates if a delete is successful.
  • Click Regex lookup to search for URLs that match one or more regular expressions. From the display page, you can delete the URLs listed. For example, enter the following to search for all URLs that end in html and are prefixed with http://www.dianes.com: http://www.dianes.com/.*\.html$
  • Click Regex delete to delete all URLs that match a specified regular expression. For example, enter the following to delete all HTTP URLs that end in html: http://.*\.html$
  • Click Regex invalidate to invalidate URLs that match a specified regular expression. When you invalidate a URL, Traffic Server marks the object that corresponds to the URL as stale in the cache. Traffic Server then contacts the origin server to check if the object is still fresh (revalidates) before serving it from the cache.

注解

Only one administrator should delete and invalidate cache entries from the Cache page at any point in time. Changes made by multiple administrators at the same time can lead to unpredictable results.

Monitoring Traffic

Traffic Server provides several options for monitoring system performance and analyzing network traffic.

Traffic Server Monitoring Tools

Traffic Server provides the following tools to monitor system performance and analyze network traffic:

  • Traffic Server can send email that’s triggered by alarms that signal any detected failure conditions; refer to Working with Traffic Manager Alarms.
  • The Traffic Line command-line interface provides an alternative method of viewing Traffic Server performance and network traffic information; refer to Viewing Statistics from Traffic Line.
  • The Traffic Shell command-line tool provides yet another alternative method of viewing Traffic Server performance and network traffic information; refer to Starting Traffic Shell.
Working with Traffic Manager Alarms

Traffic Server signals an alarm when it detects a problem. For example, the space allocated to event logs could be full or Traffic Server may not be able to write to a configuration file.

Configuring Traffic Server to Email Alarms

To configure Traffic Server to send an email to a specific address whenever an alarm occurs, follow the steps below:

  1. In the records.config file
  2. Set the proxy.config.alarm_email variable to the email address alarms will be routed to.
  3. Run the command traffic_line -x to apply the configuration changes.
Using a Script File for Alarms

Alarm messages are built into Traffic Server - you cannot change them. However, you can write a script file to execute certain actions when an alarm is signaled. Traffic Server provides a sample script file named example_alarm_bin.sh in the bin directory; simply modify the file to suit your needs.

Viewing Statistics from Traffic Line

You can use the Traffic Line command-line interface to view statistics about Traffic Server performance and web traffic. In addition to viewing statistics, you can also configure, stop, and restart the Traffic Server system. For additional information, refer to Configure Traffic Server Using Traffic Line and Description. You can view specific information about a Traffic Server node or cluster by specifying the variable that corresponds to the statistic you want to see.

To view a statistic, enter the following command::

traffic_line -r variable

where variable is the variable representing the information you want to view. For a list of variables you can specify, refer to Traffic Line Variables.

For example, the following command displays the document hit rate for the Traffic Server node::

traffic_line -r proxy.node.cache_hit_ratio

If the Traffic Server bin directory is not in your path, then prepend the Traffic Line command with ./ (for example: traffic_line -r variable).

Configuring Traffic Server

Traffic Server provides several options for configuring the system.

Configure Traffic Server Using Traffic Line

Traffic Line enables you to quickly and easily change your Traffic Server configuration via command-line interface. Alternatively, you can also use traffic_shell to configure Traffic Server.

View Configuration Options in Traffic Line

To view a configuration setting, enter the following command:

traffic_line -r var

where var is the variable associated with the configuration option. For a list of variables, refer to Configuration Variables.

Change Configuration Options in Traffic Line

To change the value of a configuration setting, enter the following command:

traffic_line -s var -v value

where var is the variable associated with the configuration option and value is the value you want to use. For a list of the variables, see Configuration Variables.

Configure Traffic Server Using Configuration Files

As an alternative to using Traffic Line or Traffic Shell, you can change Traffic Server configuration options by manually editing specific variables in the records.config file. After modifying the records.config file, Traffic Server must reread the configuration files: enter the Traffic Line command traffic_line -x. You may need to restart Traffic Server to apply some of the configuration changes.

The following is a sample portion of the records.config file:

Sample records.config file

Sample records.config file

In addition to the records.config file, Traffic Server provides other configuration files that are used to configure specific features. You can manually edit all configuration files as described in Configuration File Reference.

Traffic Server Cluster

Traffic Server scales from a single node to multiple nodes that form a cluster allowing you to improve system performance and reliability.

Understanding Traffic Server Clusters

A Traffic Server cluster consists of multiple Traffic Server nodes. The nodes in a cluster share configuration information and can form a single logical cache. Traffic Server detects the addition and deletion of nodes in the cluster automatically and can detect when a node is unavailable. Traffic Server uses its own protocol for clustering, which is multicast for node location and heartbeat, but unicast for all data exchange within the cluster. Traffic Server has two clustering modes:

Management-Only Clustering

In management-only clustering mode, Traffic Server cluster nodes share configuration information. You can administer all the nodes at the same time. Traffic Server uses a multicast management protocol to provide a single system image of your Traffic Server cluster. Information about cluster membership, configuration, and exceptions is shared across all nodes, and the traffic_manager process automatically propagates configuration changes to all the nodes.

Full Clustering

In full-clustering mode, as well as sharing configuration information, a Traffic Server cluster distributes its cache across its nodes into a single, virtual object store, rather than replicating the cache node by node. Traffic Server can provide an enormous aggregate cache size and can maximize cache hit rate by storing objects only once across the entire cluster.

A fully clustered Traffic Server maps objects to specific nodes in the cluster. When a node receives a request, it checks to see if the request is a hit somewhere in the cluster. If the request is a hit on a different node, the node handling the request obtains the object from the hit node and serves it to the client. Traffic Server uses its own communication protocol to obtain an object from sibling cluster nodes.

If a node fails or is shut down and removed, Traffic Server removes references to the missing node on all nodes in the cluster.

Full clustering recommends a dedicated network interface for cluster communication to get better performance.

Enabling Clustering Mode

Before you put a node into a cluster, please make sure the following things are in order:

  • You are using the same operation system on all nodes:
    • Using the same distribution, e.g.: RHEL 5.5
    • Have same kernel, e.g.: 2.6.18-194.17.1.el5
    • The same architecture, e.g.: x86_64
  • You have the same version of Traffic Server installed
  • The same hardware
  • On the same switch or same VLAN.

Traffic Server does not apply the clustering mode change to all the nodes in the cluster. You must change the clustering mode on each node individually. You may following these instructions:

  1. Setup the same cluster name, with proxy.config.proxy_name, e.g. MyCluster.
  2. Set proxy.local.cluster.type to 1, to enable cluster mode. The following values of this configuration are valid
Value Description
1 full-clustering mode
2 management-only mode
3 no clustering (default)
  1. Setup a proxy.config.cluster.ethernet_interface, e.g.: eth0. This should be replaced by your real interface; we recommends a dedicated interface here. Refer to proxy.local.cluster.type for a full description.

  2. Enable configuration changes:

    traffic_line -x
    
  3. Restart traffic server:

    traffic_line -L
    

    The traffic_server and traffic_manager processes will need to restart after the change of proxy.local.cluster.type and proxy.config.cluster.ethernet_interface have taken place.

Traffic Server will join the cluster in about 10 seconds, and you can run traffic_line -r proxy.process.cluster.nodes to check the hosts in the cluster, or check out the cluster.config in the configuration directory. This configuration is generated by the system, and should not be edited. It contains a list of the machines that are currently members of the cluster, for example:

# 3
127.1.2.3:80
127.1.2.4:80
127.1.2.5:80

After successfully joining of a cluster, all changes of global configurations on any node, will take effect on all nodes. This means you can make changes on any cluster node member, and they are automatically distributed to all members.

Deleting Nodes from a Cluster

To delete a node from the Traffic Server cluster, just roll back proxy.local.cluster.type to the default value 3 and reload.

Performance tweak for busy Cluster

Starting from v3.2.0, Apache Traffic Server can handle multiple internal cluster connections, and we can tweak the number of Cluster threads. Each of the thread will keep one connection to all of peering cluster machines.

Increasing Cluster threads

In the cluster environment, the current performance of the cluster threads will consume the same cpu usage as a normal network thread. It’s reasonable to keep roughly the same number of cluster threads as network threads. For example, if you are running a system with 10 network processing threads, you can set the number of cluster threads by modifying proxy.config.cluster.threads to 10. E.g.:

traffic_line -s proxy.config.cluster.threads -v 10

Security Options

Traffic Server provides a number of security features.

Controlling Client Access to the Proxy Cache

You can configure Traffic Server to allow only certain clients to use the proxy cache by editing a configuration file.

  1. Add a line in ip_allow.config for each IP address or range of IP addresses allowed to access Traffic Server.
  2. Run the command traffic_line -x to apply the configuration changes.
Configuring DNS Server Selection (Split DNS)

The Split DNS option enables you to configure Traffic Server to use multiple DNS servers, as dictated by your security requirements. For example, you might configure Traffic Server to use one set of DNS servers to resolve hostnames on your internal network, while allowing DNS servers outside the firewall to resolve hosts on the Internet. This maintains the security of your intranet, while continuing to provide direct access to sites outside your organization.

To configure Split DNS, you must do the following:

  • Specify the rules for performing DNS server selection based on the destination domain, the destination host, or a URL regular expression.
  • Enable the Split DNS option.

To do this, we

  1. Add rules to splitdns.config.
  2. In records.config set the variable proxy.config.dns.splitDNS.enabled to 1 to enable split DNS.
  3. Run the command traffic_line -x to apply the configuration changes.
Using SSL Termination

The Traffic Server SSL termination option enables you to secure connections in reverse proxy mode between a client and a Traffic Server and/or Traffic Server and an origin server.

The following sections describe how to enable and configure the SSL termination option.

Client and Traffic Server Connections

The figure below illustrates communication between a client and Traffic Server (and between Traffic Server and an origin server) when the SSL termination option is enabled & configured for client/Traffic Server connections only.

Client and Traffic Server communication using SSL termination

Client and Traffic Server communication using SSL termination

The figure above depicts the following:

  1. The client sends an HTTPS request for content. Traffic Server receives the request and performs the SSL ‘handshake’ to authenticate the client (depending on the authentication options configured) and determine the encryption method that will be used. If the client is allowed access, then Traffic Server checks its cache for the requested content.
  2. If the request is a cache hit and the content is fresh, then Traffic Server encrypts the content and sends it to the client. The client decrypts the content (using the method determined during the handshake) and displays it.
  3. If the request is a cache miss or cached content is stale, then Traffic Server communicates with the origin server via HTTP and obtains a plain text version of the content. Traffic Server saves the plain text version of the content in its cache, encrypts the content, and sends it to the client. The client decrypts and displays the content.

To configure Traffic Server to use the SSL termination option for client/Traffic Server connections, you must do the following:

  • Obtain and install an SSL server certificate from a recognized certificate authority. The SSL server certificate contains information that enables the client to authenticate Traffic Server and exchange encryption keys.
  • Configure SSL termination options:
    • Set the port number used for SSL communication using proxy.config.http.server_ports.
    • Edit ssl_multicert.config to specify the filename and location of the SSL certificates and private keys.
    • (Optional) Configure the use of client certificates: Client certificates are located on the client. If you configure Traffic Server to require client certificates, then Traffic Server verifies the client certificate during the SSL handshake that authenticates the client. If you configure Traffic Server to not require client certificates, then access to Traffic Server is managed through other Traffic Server options that have been set (such as rules in ip_allow.config).
    • (Optional) Configure the use of Certification Authorities (CAs). CAs add security by verifying the identity of the person requesting a certificate.

In order to accomplish this, we

  1. Edit the following variables in the SSL Termination section of records.config
  2. Run the command traffic_line -L to restart Traffic Server on the local node or traffic_line -M to restart Traffic Server on all the nodes in a cluster.
Traffic Server and Origin Server Connections

The figure below illustrates communication between Traffic Server and an origin server when the SSL termination option is enabled for Traffic Server/origin server connections.

Traffic Server and origin server communication using SSL termination

Traffic Server and origin server communication using SSL termination

The figure above depicts the following:

Step 1: If a client request is a cache miss or is stale, then Traffic Server sends an HTTPS request for the content to the origin server. The origin server receives the request and performs the SSL handshake to authenticate Traffic Server and determine the encryption method to be used.

Step 2: If Traffic Server is allowed access, then the origin server encrypts the content and sends it to Traffic Server, where it is decrypted (using the method determined during the handshake). A plain text version of the content is saved in the cache.

Step 3: If SSL termination is enabled for client /Traffic Server connections, then Traffic Server re-encrypts the content and sends it to the client via HTTPS, where it is decrypted and displayed. If SSL termination is not enabled for client/Traffic Server connections, then Traffic Server sends the plain text version of the content to the client via HTTP.

To configure Traffic Server to use the SSL termination option for Traffic Server and origin server connections, you must do the following:

  • Obtain and install an SSL client certificate from a recognized certificate authority. The SSL client certificate contains information that allows the origin server to authenticate Traffic Server (the client certificate is optional).
  • Configure SSL termination options:
  • Enable the SSL termination option.
    • Set the port number used for SSL communication.
    • Specify the filename and location of the SSL client certificate (if you choose to use a client certificate).
    • Specify the filename and location of the Traffic Server private key (if the private key is not located in the client certificate file). Traffic Server uses its private key during the SSL handshake to decrypt the session encryption keys. The private key must be stored and protected against theft.
    • Configure the use of CAs. CAs allow the Traffic Server that’s acting as a client to verify the identity of the server with which it is communicating, thereby enabling exchange of encryption keys.

In order to accomplish this, we:

  1. Edit the following variables in the SSL Termination section of records.config:
  2. Run the command traffic_line -L to restart Traffic Server on the local node or traffic_line -M to restart Traffic Server on all the nodes in a cluster.

Working with Log Files

Traffic Server generates log files that contain information about every request it receives and every error it detects. This chapter will examine the various log features, the configuration formats and also examine the various pre-defined log formats that are available.

Understanding Traffic Server Log Files

Traffic Server records information about every transaction (or request) it processes and every error it detects in log files. Traffic Server keeps three types of log files:

  • Error log files record information about why a particular transaction was in error.

  • Event log files (also called access log files) record information about the state of each transaction Traffic Server processes.

  • System log files record system information, including messages about the state of Traffic Server and errors/warnings it produces. This kind of information might include a note that event log files were rolled, a warning that cluster communication timed out, or an error indicating that Traffic Server was restarted.

    All system information messages are logged with the system-wide logging facility syslog under the daemon facility. The syslog.conf(5) configuration file (stored in the /etc directory) specifies where these messages are logged. A typical location is /var/log/messages (Linux).

    The syslog(8) process works on a system-wide basis, so it serves as the single repository for messages from all Traffic Server processes (including traffic_server, traffic_manager, and traffic_cop).

    System information logs observe a static format. Each log entry in the log contains information about the date and time the error was logged, the hostname of the Traffic Server that reported the error, and a description of the error or warning.

    Refer to Error Messages for a list of the messages logged by Traffic Server.

By default, Traffic Server creates both error and event log files and records system information in system log files. You can disable event logging and/or error logging by setting the configuration variable proxy.config.log.logging_enabled (in the records.config file) to one of the following values:

  • 0 to disable both event and error logging
  • 1 to enable error logging only
  • 2 to enable transaction logging only
  • 3 to enable both transaction and error logging
Understanding Event Log Files

Event log files record information about every request that Traffic Server processes. By analyzing the log files, you can determine how many people use the Traffic Server cache, how much information each person requested, what pages are most popular, and so on. Traffic Server supports several standard log file formats, such as Squid and Netscape, as well as user-defined custom formats. You can analyze the standard format log files with off-the-shelf analysis packages. To help with log file analysis, you can separate log files so they contain information specific to protocol or hosts. You can also configure Traffic Server to roll log files automatically at specific intervals during the day or when they reach a certain size.

The following sections describe the Traffic Server logging system features and discuss how to:

  • Manage your event log files

    You can choose a central location for storing log files, set how much disk space to use for log files, and set how and when to roll log files. Refer to Managing Event Log Files.

  • Choose different event log file formats

    You can choose which standard log file formats you want to use for traffic analysis, such as Squid or Netscape. Alternatively, you can use the Traffic Server custom format, which is XML-based and enables you to institute more control over the type of information recorded in log files. Refer to Choosing Event Log File Formats.

  • Roll event log files automatically

    Configure Traffic Server to roll event log files at specific intervals during the day or when they reach a certain size; this enables you to identify and manipulate log files that are no longer active. Refer to Rolling Event Log Files.

  • Separate log files according to protocols and hosts

    Configure Traffic Server to create separate log files for different protocols. You can also configure Traffic Server to generate separate log files for requests served by different hosts. Refer to Splitting Event Log Files.

  • Collate log files from different Traffic Server nodes

    Designate one or more nodes on the network to serve as log collation servers. These servers, which might be standalone or part of Traffic Server, enable you to keep all logged information in well-defined locations. Refer to Collating Event Log Files.

  • View statistics about the logging system

    Traffic Server provides statistics about the logging system; you can access these statistics via Traffic Line. Refer to Viewing Logging Statistics.

  • Interpret log file entries for the log file formats

    Refer to Example Event Log File Entries.

Managing Event Log Files

Traffic Server enables you to control where event log files are located and how much space they can consume. Additionally you can specify how to handle low disk space in the logging directory.

Choosing the Logging Directory

By default, Traffic Server writes all event log files in the logs directory located in the directory where you installed Traffic Server. To use a different directory, refer to Setting Log File Management Options.

Controlling Logging Space

Traffic Server enables you to control the amount of disk space that the logging directory can consume. This allows the system to operate smoothly within a specified space window for a long period of time. After you establish a space limit, Traffic Server continues to monitor the space in the logging directory. When the free space dwindles to the headroom limit (see Setting Log File Management Options), it enters a low space state and takes the following actions:

  • If the autodelete option (discussed in Rolling Event Log Files) is enabled, then Traffic Server identifies previously-rolled log files (i.e., log files with the .old extension). It starts deleting files one by one, beginning with the oldest file, until it emerges from the low state. Traffic Server logs a record of all deleted files in the system error log.
  • If the autodelete option is disabled or there are not enough old log files to delete for the system to emerge from its low space state, then Traffic Server issues a warning and continues logging until space is exhausted. When available space is consumed, event logging stops. Traffic Server resumes event logging when enough space becomes available for it to exit the low space state. To make space available, either explicitly increase the logging space limit or remove files from the logging directory manually.

You can run a cron(8) script in conjunction with Traffic Server to automatically remove old log files from the logging directory before Traffic Server enters the low space state. Relocate the old log files to a temporary partition, where you can run a variety of log analysis scripts. Following analysis, either compress the logs and move to an archive location, or simply delete them.

Setting Log File Management Options

To set log management options, follow the steps below:

  1. In the records.config file, edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.
Choosing Event Log File Formats

Traffic Server supports the following log file formats:

In addition to the standard and custom log file format, you can choose whether to save log files in binary or ASCII; refer to Choosing Binary or ASCII.

Event log files consume substantial disk space. Creating log entries in multiple formats at the same time can consume disk resources very quickly and adversely impact Traffic Server performance.

Using Standard Formats

The standard log formats include Squid, Netscape Common, Netscape extended, and Netscape Extended-2. The standard log file formats can be analyzed with a wide variety of off-the-shelf log-analysis packages. You should use one of the standard event log formats unless you need information that these formats do not provide. Refer to Using the Custom Format.

Set standard log file format options by following the steps below:

  1. In the records.config file, edit the following variables
  2. Edit the following variables to use the Squid format:
  3. To use the Netscape Common format, edit the following variables:
  4. To use the Netscape Extended format, edit the following variables:
  5. To use the Netscape Extended-2 format, edit the following variables:
  6. Run the command traffic_line -x to apply the configuration changes.
Using the Custom Format

The XML-based custom log format is more flexible then the standard log file formats and gives you more control over the type of information recorded in log files. You should create a custom log format if you need data for analysis that’s not available in the standard formats. You can decide what information to record for each Traffic Server transaction and create filters that specify which transactions to log.

The heart of the XML-based custom logging feature is the XML-based logging configuration file (logs_xml.config) that enables you to create very modular descriptions of logging objects. The logs_xml.config file uses three types of objects to create custom log files, as detailed below. To generate a custom log format, you must specify at least one LogObject definition (one log file is produced for each LogObject definition).

  • The LogFormat object defines the content of the log file using printf-style format strings.
  • The LogFilter object defines a filter so that you include or exclude certain information from the log file.
  • The LogObject object specifies all the information needed to produce a log file.
    • The name of the log file. (required)
    • The format to be used (required). This can be a standard format (Squid or Netscape) or
    • a previously-defined custom format (i.e., a previously-defined LogFormat object).
    • The file mode: ASCII, Binary, or ASCII_PIPE. The default is ASCII. The ASCII_PIPE mode writes log entries to a UNIX-named pipe (a buffer in memory); other processes can then read the data using standard I/O functions. The advantage of this option is that Traffic Server does not have to write to disk, which frees disk space and bandwidth for other tasks. When the buffer is full, Traffic Server drops log entries and issues an error message indicating how many entries were dropped. Because Traffic Server only writes complete log entries to the pipe, only full records are dropped.
    • Any filters you want to use (i.e., previously-defined LogFilter objects).
    • The collation servers that are to receive the log files.
    • The protocols you want to log. If the protocols tag is used, then Traffic Server will only log transactions from the protocols listed; otherwise, all transactions for all protocols are logged.
    • The origin servers you want to log. If the servers tag is used, then Traffic Server will only log transactions for the origin servers listed; otherwise, transactions for all origin servers are logged.
    • The header text you want the log files to contain. The header text appears at the beginning of the log file, just before the first record.
    • The log file rolling options.

In order to accomplish this, we

  1. edit the following variables in the records.config file:
  2. proxy.config.log.custom_logs_enabled
  3. In the logs_xml.config file
  4. Add LogFormat, LogFilters, and LogObject specifications to the configuration file.
  5. Save and close the logs_xml.config file.
  6. Run the command traffic_line -x to apply your configuration changes.
Creating Summary Log Files

Traffic Server performs several hundred operations per second; therefore, event log files can quickly grow to large sizes. Using SQL-like aggregate operators, you can configure Traffic Server to create summary log files that summarize a set of log entries over a specified period of time. This can significantly reduce the size of the log files generated.

To generate a summary log file, create a LogFormat object in the XML-based logging configuration file (logs_xml.config) using the SQL-like aggregate operators below. You can apply each of these operators to specific fields, over a specified interval.

  • COUNT
  • SUM
  • AVERAGE
  • FIRST
  • LAST

To create a summary log file format, we

  1. Define the format of the log file in logs_xml.config as follows:

    :::xml
    <LogFormat>
      <Name = "summary"/>
      <Format = "%<operator(field)> : %<operator(field)>"/>
      <Interval = "n"/>
    </LogFormat>

    where operator is one of the five aggregate operators (COUNT, SUM, AVERAGE, FIRST, LAST), field is the logging field you want to aggregate, and n is the interval (in seconds) between summary log entries. You can specify more than one operator in the format line. For more information, refer to :file`logs_xml.config`.

  2. Run the command traffic_line -x to apply configuration changes .

The following example format generates one entry every 10 seconds. Each entry contains the timestamp of the last entry of the interval, a count of the number of entries seen within that 10-second interval, and the sum of all bytes sent to the client:

<LogFormat>
  <Name = "summary"/>
  <Format = "%<LAST(cqts)> : %<COUNT(*)> : %<SUM(psql)>"/>
  <Interval = "10"/>
</LogFormat>

重要

You cannot create a format specification that contains both aggregate operators and regular fields. For example, the following specification would be invalid:

<Format = "%<LAST(cqts)> : %<COUNT(*)> : %<SUM(psql)> : %<cqu>"/>
Choosing Binary or ASCII

You can configure Traffic Server to create event log files in either of the following:

  • ASCII

    These files are human-readable and can be processed using standard, off-the-shelf log analysis tools. However, Traffic Server must perform additional processing to create the files in ASCII, which mildly impacts system overhead. ASCII files also tend to be larger than the equivalent binary files. By default, ASCII log files have a .log filename extension.

  • Binary

    These files generate lower system overhead and generally occupy less space on the disk than ASCII files (depending on the type of information being logged). However, you must use a converter application before you can read or analyze binary files via standard tools. By default, binary log files use a .blog filename extension.

While binary log files typically require less disk space, there are exceptions.

For example: the value 0 (zero) requires only one byte to store in ASCII, but requires four bytes when stored as a binary integer. Conversely: if you define a custom format that logs IP addresses, then a binary log file would only require four bytes of storage per 32-bit address. However, the same IP address stored in dot notation would require around 15 characters (bytes) in an ASCII log file. Therefore, it’s wise to consider the type of data that will be logged before you select ASCII or binary for your log files. For example, you might try logging for one day using ASCII and then another day using binary. If the number of requests is roughly the same for both days, then you can calculate a rough metric that compares the two formats.

For standard log formats, select Binary or ASCII (refer to Setting Standard Log File Format Options). For the custom log format, specify ASCII or Binary mode in the LogObject (refer to Using the Custom Format). In addition to the ASCII and binary options, you can also write custom log entries to a UNIX-named pipe (i.e., a buffer in memory). Other processes can then read the data using standard I/O functions. The advantage of using this option is that Traffic Server does not have to write to disk, which frees disk space and bandwidth for other tasks. In addition, writing to a pipe does not stop when logging space is exhausted because the pipe does not use disk space. Refer to logs_xml.config for more information about the ASCII_PIPE option.

Rolling Event Log Files

Traffic Server provides automatic log file rolling. This means that at specific intervals during the day or when log files reach a certain size, Traffic Server closes its current set of log files and opens new log files. Depending on the amount of traffic your servers are exposed to, you should roll log files several times a day. Rolling every six hours is a good guideline to start with.

Log file rolling offers the following benefits:

  • It defines an interval over which log analysis can be performed.
  • It keeps any single log file from becoming too large and helps to keep the logging system within the specified space limits.
  • It provides an easy way to identify files that are no longer being used so that an automated script can clean the logging directory and run log analysis programs.
Rolled Log Filename Format

Traffic Server provides a consistent naming scheme for rolled log files that enables you to easily identify log files. When Traffic Server rolls a log file, it saves and closes the old file before it starts a new file. Traffic Server renames the old file to include the following information:

  • The format of the file (such as squid.log).
  • The hostname of the Traffic Server that generated the log file.
  • Two timestamps separated by a hyphen (-). The first timestamp is a lower bound for the timestamp of the first record in the log file. The lower bound is the time when the new buffer for log records is created. Under low load, the first timestamp in the filename can be different from the timestamp of the first entry. Under normal load, the first timestamp in the filename and the timestamp of the first entry are similar. The second timestamp is an upper bound for the timestamp of the last record in the log file (this is normally the rolling time).
  • The suffix .old, which makes it easy for automated scripts to find rolled log files.

Timestamps have the following format:

%Y%M%D.%Hh%Mm%Ss-%Y%M%D.%Hh%Mm%Ss

The following table describes the format:

%Y
The year in four-digit format. For example: 2000.
%M
The month in two-digit format, from 01-12. For example: 07.
%D
The day in two-digit format, from 01-31. For example: 19.
%H
The hour in two-digit format, from 00-23. For example: 21.
%M
The minute in two-digit format, from 00-59. For example: 52.
%S
The second in two-digit format, from 00-59. For example: 36.

The following is an example of a rolled log filename:

squid.log.mymachine.20110912.12h00m00s-20000913.12h00m00s.old

The logging system buffers log records before writing them to disk. When a log file is rolled, the log buffer might be partially full. If it is, then the first entry in the new log file will have a timestamp earlier than the time of rolling. When the new log file is rolled, its first timestamp will be a lower bound for the timestamp of the first entry.

For example, suppose logs are rolled every three hours, and the first rolled log file is:

squid.log.mymachine.20110912.12h00m00s-19980912.03h00m00s.old

If the lower bound for the first entry in the log buffer at 3:00:00 is 2:59:47, then the next log file will have the following timestamp when rolled:

squid.log.mymachine.20110912.02h59m47s-19980912.06h00m00s.old

The contents of a log file are always between the two timestamps. Log files do not contain overlapping entries, even if successive timestamps appear to overlap.

Rolling Intervals

Log files are rolled at specific intervals relative to a given hour of the day. Two options control when log files are rolled:

  • The offset hour, which is an hour between 0 (midnight) and 23
  • The rolling interval

Both the offset hour and the rolling interval determine when log file rolling starts. Rolling occurs every rolling interval and at the offset hour. For example, if the rolling interval is six hours and the offset hour is 0 (midnight), then the logs will roll at midnight (00:00), 06:00, 12:00, and 18:00 each day. If the rolling interval is 12 hours and the offset hour is 3, then logs will roll at 03:00 and 15:00 each day.

Setting Log File Rolling Options

To set log file rolling options and/or configure Traffic Server to roll log files when they reach a certain size, follow the steps below:

  1. In the records.config file, edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.

You can fine-tune log file rolling settings for a custom log file in the LogObject specification in the logs_xml.config file. The custom log file uses the rolling settings in its LogObject, which override the default settings you specify in Traffic Manager or the records.config file described above.

Splitting Event Log Files

By default, Traffic Server uses standard log formats and generates log files that contain HTTP & ICP transactions in the same file. However, you can enable log splitting if you prefer to log transactions for different protocols in separate log files.

ICP Log Splitting

When ICP log splitting is enabled, Traffic Server records ICP transactions in a separate log file with a name that contains icp. For example: if you enable the Squid format, then all ICP transactions are recorded in the squid-icp.log file. When you disable ICP log splitting, Traffic Server records all ICP transactions in the same log file as HTTP transactions.

HTTP Host Log Splitting

HTTP host log splitting enables you to record HTTP transactions for different origin servers in separate log files. When HTTP host log splitting is enabled, Traffic Server creates a separate log file for each origin server that’s listed in the log_hosts.config file. When both ICP and HTTP host log splitting are enabled, Traffic Server generates separate log files for HTTP transactions (based on the origin server) and places all ICP transactions in their own respective log files. For example, if the log_hosts.config file contains the two origin servers uni.edu and company.com and Squid format is enabled, then Traffic Server generates the following log files:

squid-uni.edu.log
All HTTP transactions for uni.edu
squid-company.com.log
All HTTP transactions for company.com
squid-icp.log
All ICP transactions for all hosts
squid.log
All HTTP transactions for other hosts

If you disable ICP log splitting, then ICP transactions are placed in the same log file as HTTP transactions. Using the hosts and log format from the previous example, Traffic Server generates the log files below:

squid-uni.edu.log
All entries for uni.edu
squid-company.com.log
All entries for company.com
squid.log
All other entries

Traffic Server also enables you to create XML-based Custom Log Formats that offer even greater control over log file generation.

Setting Log Splitting Options

To set log splitting options, follow the steps below:

  1. In the records.config file, edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.
Editing the log_hosts.config File

The default log_hosts.config file is located in the Traffic Server config directory. To record HTTP transactions for different origin servers in separate log files, you must specify the hostname of each origin server on a separate line in the log_hosts.config file. For example, if you specify the keyword sports, then Traffic Server records all HTTP transactions from sports.yahoo.com and www.foxsports.com in a log file called squid-sports.log (if the Squid format is enabled).

注解

If Traffic Server is clustered and you enable log file collation, then you should use the same log_hosts.config file on every Traffic Server node in the cluster.

To edit the log_hosts.config file follow the steps below:

  1. In the log_hosts.config file, enter the hostname of each origin server on a separate line in the file, e.g.:

    webserver1
    webserver2
    webserver3
    
  2. Run the command traffic_line -x to apply the configuration changes.

Collating Event Log Files

You can use the Traffic Server log file collation feature to collect all logged information in one place. Log collation enables you to analyze a set of Traffic Server clustered nodes as a whole (rather than as individual nodes) and to use a large disk that might only be located on one of the nodes in the cluster. Traffic Server collates log files by using one or more nodes as log collation servers and all remaining nodes as log collation clients. When a Traffic Server node generates a buffer of event log entries, it first determines if it is the collation server or a collation client. The collation server node writes all log buffers to its local disk, just as it would if log collation was not enabled. Log collation servers can be standalone or they can be part of a node running Traffic Server.

The collation client nodes prepare their log buffers for transfer across the network and send the buffers to the log collation server. When the log collation server receives a log buffer from a client, it writes it to its own log file as if it was generated locally. For a visual representation of this, see the figure below.

Log collation

Log collation

If log clients cannot contact their log collation server, then they write their log buffers to their local disks, into orphan log files. Orphan log files require manual collation.

注解

Log collation can have an impact on network performance. Because all nodes are forwarding their log data buffers to the single collation server, a bottleneck can occur. In addition, collated log files contain timestamp information for each entry, but entries in the files do not appear in strict chronological order. You may want to sort collated log files before doing analysis.

To configure Traffic Server to collate event log files, you must perform the following tasks:

Configuring Traffic Server to Be a Collation Server

To configure a Traffic Server node to be a collation server, simply edit a configuration file via the steps below.

  1. In the records.config file, edit the following variables
  2. Run the command traffic_line -x to apply the configuration changes.

注解

If you modify the collation_port or secret after connections between the collation server and collation clients have been established, then you must restart Traffic Server.

Using a Standalone Collator

If you do not want the log collation server to be a Traffic Server node, then you can install and configure a standalone collator (SAC) that will dedicate more of its power to collecting, processing, and writing log files.

To install and configure a standalone collator:

  1. Configure your Traffic Server nodes as log collation clients; refer to Configuring Traffic Server to Be a Collation Client.

  2. Copy the traffic_sac binary from the Traffic Server bin directory and

  3. Copy the libtsutil.so libraries from the Traffic Server lib directory to the machine serving as the standalone collator.

  4. Create a directory called config in the directory that contains the traffic_sac binary.

  5. Create a directory called internal in the config directory you created in Step 4 (above). This directory is used internally by the standalone collator to store lock files.

  6. Copy the records.config file from a Traffic Server node configured to be a log collation client to the config directory you created in Step 4 on the standalone collator. The records.config file contains the log collation secret and the port you specified when configuring Traffic Server nodes to be collation clients. The collation port and secret must be the same for all collation clients and servers.

  7. In the records.config file, edit the following variable

  8. Enter the following command:

    traffic_sac -c config
Configuring Traffic Server to Be a Collation Client

To configure a Traffic Server node to be a collation client, follow the steps below. If you modify the collation_port or secret after connections between the collation clients and the collation server have been established, then you must restart Traffic Server.

  1. In the records.config file, edit the following variables:
  2. Run the command traffic_line -x to apply the configuration changes.
Collating Custom Event Log Files

If you use custom event log files, then you must edit the logs_xml.config file (in addition to configuring a collation server and collation clients).

To collate custom event log files

  1. On each collation client, edit the :file:`logs_xml.config

  2. Add the CollationHost attribute to the LogObject specification:

    <LogObject>
      <Format = "squid"/>
      <Filename = "squid"/>
      <CollationHosts="ipaddress:port"/>
    </LogObject>

    where ipaddress is the hostname or IP address of the collation server to which all log entries (for this object) are forwarded, and port is the port number for communication between the collation server and collation clients.

  3. Run the command traffic_line -L to restart Traffic Server on the local node or traffic_line -M to restart Traffic Server on all the nodes in a cluster.

Viewing Logging Statistics

Traffic Server generates logging statistics that enable you to see the following information:

  • How many log files (formats) are currently being written.
  • The current amount of space used by the logging directory, which contains all event and error logs.
  • The number of access events written to log files since Traffic Server installation. This counter represents one entry in one file; if multiple formats are being written, then a single event creates multiple event log entries.
  • The number of access events skipped (because they were filtered) since Traffic Server installation.
  • The number of access events written to the event error log since Traffic Server installation.

You can retrieve the statistics via the Traffic Line command-line interface; refer to Monitoring Traffic.

Viewing Log Files

You can view the system, event, and error log files Traffic Server creates. You can also delete a log file or copy it to your local system if you have the correct user permissions. Traffic Server displays only one MB of information in the log file. If the log file you select to view is bigger than 1MB, then Traffic Server truncates the file and displays a warning message indicating that the file is too big.

Online Event Log XML Builder

If you need any assistance building your event log, you can try out our online log builder. This is a work in progress, so any comments, critique or suggestions are most welcome.

Example Event Log File Entries

This section shows an example log file entry in each of the standard log formats supported by Traffic Server: Squid, Netscape Common, Netscape Extended, and Netscape Extended-2.

Squid Format

The following figure shows a sample log entry in a squid.log file.

Sample log entry in squid.log

Sample log entry in squid.log

Field Symbol Description
1 cqtq The client request timestamp in Squid format; the time of the client request in seconds since January 1, 1970 UTC (with millisecond resolution).
2 ttms The time Traffic Server spent processing the client request; the number of milliseconds between the time the client established the connection with Traffic Server and the time Traffic Server sent the last byte of the response back to the client.
3 chi The IP address of the client’s host machine.
4 crc/pssc The cache result code; how the cache responded to the request: HIT, MISS, and so on. Cache result codes are described here. The proxy response status code (the HTTP response status code from Traffic Server to client).
5 psql The length of the Traffic Server response to the client in bytes, including headers and content.
6 cqhm The client request method: GET, POST, and so on.
7 cauc The client request canonical URL; blanks and other characters that might not be parsed by log analysis tools are replaced by escape sequences. The escape sequence is a percentage sign followed by the ASCII code number of the replaced character in hex.
8 caun The username of the authenticated client. A hyphen (-) means that no authentication was required.
9 phr/pqsn The proxy hierarchy route; the route Traffic Server used to retrieve the object.
10 psct The proxy response content type; the object content type taken from the Traffic Server response header.
Squid log in XML

This is the equivalent XML configuration for the log above:

<LogFormat>
  <Name = "squid"/>
  <Format = "%<cqtq> %<ttms> %<chi> %<crc>/%<pssc> %<psql> %<cqhm> %<cquc>
             %<caun> %<phr>/%<pqsn> %<psct>"/>
</LogFormat>
Netscape Common
Sample log entry in common.log

Sample log entry in common.log

Field Symbol Description
1 chi The IP address of the client’s host machine.
2 This hyphen (-) is always present in Netscape log entries.
3 caun The authenticated client username. A hyphen (-) means no authentication was required.
4 cqtd The date and time of the client request, enclosed in brackets.
5 cqtx The request line, enclosed in quotes.
6 pssc The proxy response status code (HTTP reply code).
7 pscl The length of the Traffic Server response to the client in bytes.
Netscape Common in XML

This is the equivalent XML configuration for the log above:

<LogFormat>
  <Name = "common"/>
  <Format = "%<chi> - %<caun> [%<cqtn>] \"%<cqtx>\" %<pssc> %<pscl>"/>
</LogFormat>
Netscape Extended
Sample log entry in extended.log

Sample log entry in extended.log

In addition to field 1-7 from the Netscape Common log format above, the Extended format also adds the following fields:

Field Symbol Description
8 sssc The origin server response status code.
9 sshl The server response transfer length; the body length in the origin server response to Traffic Server, in bytes.
10 cqbl The client request transfer length; the body length in the client request to Traffic Server, in bytes.
11 pqbl The proxy request transfer length; the body length in the Traffic Server request to the origin server.
12 cqhl The client request header length; the header length in the client request to Traffic Server.
13 pshl The proxy response header length; the header length in the Traffic Server response to the client.
14 pqhl The proxy request header length; the header length in Traffic Server request to the origin server.
15 sshl The server response header length; the header length in the origin server response to Traffic Server.
16 tts The time Traffic Server spent processing the client request; the number of seconds between the time that the client established the connection with Traffic Server and the time that Traffic Server sent the last byte of the response back to the client.
Netscape Extended in XML

This is the equivalent XML configuration for the log above:

<LogFormat>
  <Name = "extended"/>
  <Format = "%<chi> - %<caun> [%<cqtn>] \"%<cqtx>\" %<pssc> %<pscl>
     %<sssc> %<sscl> %<cqbl> %<pqbl> %<cqhl> %<pshl> %<pqhl> %<sshl> %<tts>"/>
</LogFormat>
Netscape Extended2
Sample log entry in extended2.log

Sample log entry in extended2.log

In addition to field 1-16 from the log formats above, the Extended2 format also adds the following fields:

Field Symbol Description
17 phr The proxy hierarchy route; the route Traffic Server used to retrieve the object.
18 cfsc The client finish status code: FIN if the client request completed successfully or INTR if the client request was interrupted.
19 pfsc The proxy finish status code: FIN if the Traffic Server request to the origin server completed successfully or INTR if the request was interrupted.
20 crc The cache result code; how the Traffic Server cache responded to the request: HIT, MISS, and so on. Cache result codes are described here.
Netscape Extended2 in XML

This is the equivalent XML configuration for the log above:

<LogFormat>
  <Name = "extended2"/>
  <Format = "%<chi> - %<caun> [%<cqtn>] \"%<cqtx>\" %<pssc> %<pscl>
             %<sssc> %<sscl> %<cqbl> %<pqbl> %<cqhl> %<pshl> %<pqhl> %<sshl> %<tts> %<phr> %<cfsc> %<pfsc> %<crc>"/>
</LogFormat>
Squid- and Netscape-format: Cache Result Codes

The following table describes the cache result codes in Squid and Netscape log files.

TCP_HIT
A valid copy of the requested object was in the cache and Traffic Server sent the object to the client.
TCP_MISS
The requested object was not in cache, so Traffic Server retrieved the object from the origin server (or a parent proxy) and sent it to the client.
TCP_REFRESH_HIT
The object was in the cache, but it was stale. Traffic Server made an if-modified-since request to the origin server and the origin server sent a 304 not-modified response. Traffic Server sent the cached object to the client.
TCP_REF_FAIL_HIT
The object was in the cache but was stale. Traffic Server made an if-modified-since request to the origin server but the server did not respond. Traffic Server sent the cached object to the client.
TCP_REFRESH_MISS
The object was in the cache but was stale. Traffic Server made an if-modified-since request to the origin server and the server returned a new object. Traffic Server served the new object to the client.
TCP_CLIENT_REFRESH
The client issued a request with a no-cache header. Traffic Server obtained the requested object from the origin server and sent a copy to the client. Traffic Server deleted the previous copy of the object from cache.
TCP_IMS_HIT
The client issued an if-modified-since request and the object was in cache & fresher than the IMS date, or an if-modified-since request to the origin server revealed the cached object was fresh. Traffic Server served the cached object to the client.
TCP_IMS_MISS
The client issued an if-modified-since request, and the object was either not in cache or was stale in cache. Traffic Server sent an if-modified-since request to the origin server and received the new object. Traffic Server sent the updated object to the client.
TCP_SWAPFAIL
The object was in the cache but could not be accessed. The client did not receive the object.
ERR_CLIENT_ABORT
The client disconnected before the complete object was sent.
ERR_CONNECT_FAIL
Traffic Server could not reach the origin server.
ERR_DNS_FAIL
The Domain Name Server (DNS) could not resolve the origin server name, or no DNS could be reached.
ERR_INVALID_REQ
The client HTTP request was invalid. (Traffic Server forwards requests with unknown methods to the origin server.)
ERR_READ_TIMEOUT
The origin server did not respond to Traffic Server’s request within the timeout interval.
ERR_PROXY_DENIED
Client service was denied.
ERR_UNKNOWN
The client connected, but subsequently disconnected without sending a request.

Event Logging Formats

This document provides a reference for all the different logging formats Traffic Server supports. Rather than just reading about those formats, you may also want to try our online event log builder for an interactive way of building and understanding log formats.

Custom Logging Fields

The following list describes Traffic Server custom logging fields.

{HTTP header field name}cqh
Logs the information in the requested field of the client request HTTP header. For example, %<{Accept-Language}cqh> logs the Accept-Language: field in client request headers.
{HTTP header field name}pqh
Logs the information in the requested field of the proxy request HTTP header. For example, %<{Authorization}pqh> logs the Authorization: field in proxy request headers.
{HTTP header field name}psh
Logs the information in the requested field of the proxy response HTTP header. For example, %<{Retry-After}psh> logs the Retry-After: field in proxy response headers.
{HTTP header field name}ssh
Logs the information in the requested field of the server response HTTP header. For example, %<{Age}ssh> logs the Age: field in server response headers.
caun
The client authenticated username; result of the RFC931/ident lookup of the client username.
cfsc
The client finish status code; specifies whether the client request to Traffic Server was successfully completed (FIN) or interrupted (INTR).
chi
The IP address of the client’s host machine.
chih
The IP address of the client’s host machine in hexadecimal.
chp
The port number of the client’s host machine.
cps
Client Protocol Stack, the output would be the conjunction of protocol names in the stack spliced with ‘+’, such as “TLS+SPDY”.
cqbl
The client request transfer length; the body length in the client request to Traffic Server (in bytes).
cqhl
The client request header length; the header length in the client request to Traffic Server.
cqhm
The HTTP method in the client request to Traffic Server: GET, POST, and so on (subset of cqtx).
cqhv
The client request HTTP version.
cqtd
The client request timestamp. Specifies the date of the client request in the format yyyy-mm-dd, where yyyy is the 4-digit year, mm is the 2-digit month, and dd is the 2-digit day.
cqtn
The client request timestamp; date and time of the client’s request (in the Netscape timestamp format).
cqtq
The client request timestamp, with millisecond resolution.
cqts
The client-request timestamp in Squid format; the time of the client request since January 1, 1970 UTC. Time is expressed in seconds, with millisecond resolution.
cqtt
The client request timestamp. The time of the client request in the format hh:mm:ss, where hh is the two-digit hour in 24-hour format, mm is the two-digit minutes value, and ss is the 2-digit seconds value (for example, 16:01:19).
cqtx

The full HTTP client request text, minus headers; for example,

GET http://www.company.com HTTP/1.0

In reverse proxy mode, Traffic Server logs the rewritten/mapped URL (according to the rules in the remap.config file), _not_ the pristine/unmapped URL.

cqu

The universal resource identifier (URI) of the request from client to Traffic Server (subset of cqtx ).

In reverse proxy mode, Traffic Server logs the rewritten/mapped URL (according to the rules in the remap.config file), _not_ the pristine/unmapped URL.

cquc

The client request canonical URL. This differs from cqu in that blanks (and other characters that might not be parsed by log analysis tools) are replaced by escape sequences. The escape sequence is a percentage sign followed by the ASCII code number in hex.

See cquuc.

cqup

The client request URL path; specifies the argument portion of the URL (everything after the host). For example, if the URL is http://www.company.com/images/x.gif, then this field displays /images/x.gif

See cquup.

cqus
The client request URL scheme.
cquuc
The client request unmapped URL canonical. This field records a URL before it is remapped (reverse proxy mode).
cquup
The client request unmapped URL path. This field records a URL path before it is remapped (reverse proxy mode).
cquuh
The client request unmapped URL host. This field records a URL’s host before it is remapped (reverse proxy mode).
crat
The Retry-After time in seconds, if specified by the origin server.
crc
The cache result code; specifies how the cache responded to the request (HIT, MISS, and so on).
csscl
The cached response length (in bytes) from origin server to Traffic Server.
csshl
The cached header length in the origin server response to Traffic Server (in bytes).
csshv
The cached server response HTTP version (1.0, 1.1, etc.).
csssc
The cached HTTP response status code from origin server to Traffic Server.
cwr
The cache write result (-, WL_MISS, INTR`, ERR or FIN)
cwtr
The cache write transform result
fsiz
The size of the file (n bytes) as seen by the origin server.
pfsc
The proxy finish status code; specifies whether the Traffic Server request to the origin server was successfully completed (FIN), interrupted (INTR) or timed out (TIMEOUT).
phn
The hostname of the Traffic Server that generated the log entry in collated log files.
phi
The IP of the Traffic Server that generated the log entry in collated log files.
phr
The proxy hierarchy route; the route Traffic Server used to retrieve the object.
pqbl
The proxy request transfer length; the body length in Traffic Server’s request to the origin server.
pqhl
The proxy request header length; the header length in Traffic Server’s request to the origin server.
pqsi
The proxy request server IP address (0 on cache hits and parent-ip for requests to parent proxies).
pqsn
The proxy request server name; the name of the server that fulfilled the request.
pscl
The length of the Traffic Server response to the client (in bytes).
psct
The content type of the document from server response header: (for example, img/gif ).
pshl
The header length in Traffic Server’s response to the client.
psql
The proxy response transfer length in Squid format (includes header and content length).
pssc
The HTTP response status code from Traffic Server to the client.
shi

The IP address resolved from the DNS name lookup of the host in the request. For hosts with multiple IP addresses, this field records the IP address resolved from that particular DNS lookup.

This can be misleading for cached documents. For example: if the first request was a cache miss and came from ``IP1`` for server ``S`` and the second request for server ``S`` resolved to ``IP2`` but came from the cache, then the log entry for the second request will show ``IP2``.

shn
The hostname of the origin server.
sscl
The response length (in bytes) from origin server to Traffic Server.
sshl
The header length in the origin server response to Traffic Server (in bytes).
sshv
The server response HTTP version (1.0, 1.1, etc.).
sssc
The HTTP response status code from origin server to Traffic Server.
ttms
The time Traffic Server spends processing the client request; the number of milliseconds between the time the client establishes the connection with Traffic Server and the time Traffic Server sends the last byte of the response back to the client.
ttmsh
Same as ttms but in hexadecimal.
ttmsf

The time Traffic Server spends processing the client request as a fractional number of seconds. Time is specified in millisecond resolution; however, instead of formatting the output as an integer (as with ttms), the display is formatted as a floating-point number representing a fractional number of seconds.

For example: if the time is 1500 milliseconds, then this field displays 1.5 while the ttms field displays 1500 and the tts field displays 1.

tts
The time Traffic Server spends processing the client request; the number of seconds between the time at which the client establishes the connection with Traffic Server and the time at which Traffic Server sends the last byte of the response back to the client.
Logging Format Cross-Reference

The following sections illustrate the correspondence between Traffic Server logging fields and standard logging fields for the Squid and Netscape formats.

Squid Logging Formats

The following is a list of the Squid logging fields and the corresponding logging field symbols.

Squid Field Symbols
time cqts
elapsed ttms
client chi
action/code crc/pssc
size psql
method cqhm
url cquc
ident caun
hierarchy/from phr/pqsn
content psct
Netscape Common Logging Formats

The following is a list of the Netscape Common logging fields and the corresponding Traffic Server logging field symbols.

Netscape Common Field Symbols
host chi
usr caun
[time] [cqtn]
"req" "cqtx"
s1 pssc
c1 pscl
Netscape Extended Logging Formats

The following table lists the Netscape Extended logging fields and the corresponding Traffic Server logging field symbols.

Netscape Extended Field Symbols
host chi
usr caun
[time] [cqtn]
"req" "cqtx"
s1 pssc
c1 pscl
s2 sssc
c2 sscl
b1 cqbl
b2 pqbl
h1 cqhl
h2 pshl
h3 pqhl
h4 sshl
xt tts
Netscape Extended-2 Logging Formats

The following is a list of the Netscape Extended-2 logging fields and the corresponding Traffic Server logging field symbols.

Netscape Extended-2 Field Symbols
host chi
usr caun
[time] [cqtn]
"req" "cqtx"
s1 pssc
c1 pscl
s2 sssc
c2 sscl
b1 cqbl
b2 pqbl
h1 cqhl
h2 pshl
h3 pqhl
h4 sshl
xt tts
route phr
pfs cfsc
ss pfsc
crc crc

Error Messages

Traffic Server Error Messages

The following table lists messages that can appear in system log files. This list is not exhaustive; it simply describes common warning messages that can occur and which might require your attention.

Traffic Server Process Fatal
Accept port is not between 1 and 65535. Please check configuration
The port specified in the records.config file that accepts incoming HTTP requests is not valid.
Self loop is detected in parent proxy configuration
The name and port of the parent proxy match that of Traffic Server. This creates a loop when Traffic Server attempts to send the request to the parent proxy.
Traffic Server Warnings
<Logfile> error: error_number
Generic logging error.
Bad cluster major version range <version1-version2> for node <IP address> connect failed
Incompatible software versions causing a problem.
Connect by disallowed client <IP address>, closing
The specified client is not allowed to connect to Traffic Server; the client IP address is not listed in the ip_allow.config file.
Could not rename log <filename> to <rolled filename>
System error when renaming log file during roll.
Did <this amount> of backup; still to do <remaining amount>
Congestion is approaching.
Different clustering minor versions <version1, version2> for node <IP address> continuing
Incompatible software versions are causing a problem.
Log format symbol <symbol name> not found
Custom log format references a field symbol that does not exist. Refer to Event Logging Formats.
Missing field for field marker
Error reading a log buffer.
Unable to open log file <filename>, errno=<error number>
Cannot open the log file.
Error accessing disk <disk name>
Traffic Server might have a cache read problem. You might need to replace the disk.
Too many errors accessing disk <disk name>: declaring disk bad
Traffic Server is not using the cache disk because it encountered too many errors. The disk might be corrupt and might have to be replaced.
No cache disks specified in storage.config file: cache disabled
The Traffic Server storage.config file does not list any cache disks; Traffic Server is running in proxy-only mode. You must add the disks you want to use for the cache to storage.config.
Traffic Server Alarm Messages
[Rollback::Rollback] Config file is read-only: <filename>
Go to the Traffic Server config directory and check the indicated file permissions; change if necessary.
[Rollback::Rollback] Unable to read or write config file <filename>
Go to the Traffic Server config directory and make sure the indicated file exists. Check permissions and modify if necessary.
[Traffic Manager] Configuration File Update Failed: <error number>
Go to the Traffic Server config directory and check the indicated file permissions; change if necessary.
[Traffic Manager] Mgmt <==>Proxy conn. closed
An informational message to inform you that the traffic_server process is down.
Access logging suspended - configured space allocation exhausted.
The space allocated to the event log files is full; you must either increase the space or delete some log files so that access logging to continue. To prevent this error, consider rolling log files more frequently and enabling the autodelete feature.
Access logging suspended - no more space on the logging partition.
The entire partition containing the event logs is full; you must delete or move some log files to enable access logging to continue. To prevent this error, consider rolling log files more frequently and enabling the autodelete feature.
Created zero length place holder for config file <filename>
Go to the Traffic Server config directory and check the indicated file. If it is indeed zero in length, then use a backup copy of the configuration file.
Traffic Server could not open logfile <filename>
Check permissions for the indicated file and the logging directory.
Traffic Server failed to parse line <line number> of the logging config file <filename>
Check your custom log configuration file; there could be syntax errors. Refer to Custom Logging Fields for correct custom log format fields.
vip_config binary is not setuid root, manager will be unable to enable virtual ip addresses
The traffic_manager process is not able to set virtual IP addresses. You must setuid root for the vip_config file in the Traffic Server bin directory.
HTML Messages Sent to Clients

Traffic Server returns detailed error messages to browser clients when there are problems with the HTTP transactions requested by the browser. These Traffic Server response messages correspond to standard HTTP response codes, but provide more information. A list of the more frequently-encountered HTTP response codes is provided in Standard HTTP Response Messages. You can customize the Traffic Server response messages (typically in proxy/config/body_factory/default/, but set by proxy.config.body_factory.template_sets_dir).

The following table lists the hard-coded Traffic Server HTTP messages, with corresponding HTTP response codes and customizable files.

Access Denied
403 You are not allowed to access the document at location URL. access#denied
Cache Read Error
500 Error reading from cache; please retry request. cache#read_error
Connection Timed Out
504 Too much time has elapsed since the server has sent data. timeout#inactivity
Content Length Required
400 Could not process this request because Content-Length was not specified. request#no_content_length
Cycle Detected
400 Your request is prohibited because it would cause an HTTP proxy cycle. request#cycle_detected
Forbidden
403 <port number> is not an allowed port for SSL connections (you have made a request for a secure SSL connection to a forbidden port number). access#ssl_forbidden
Host Header Required
400 An attempt was made to transparently proxy your request, but this attempt failed because your browser did not send an HTTP Host header. Manually configure your browser to use http://<proxy name>:<proxy port> as the HTTP proxy. Alternatively, end users can upgrade to a browser that supports the HTTP Host header field. interception#no_host
Host Header Required
400 Because your browser did not send a Host HTTP header field, the virtual host being requested could not be determined. To access the website correctly, you must upgrade to a browser that supports the HTTP Host header field. request#no_host
HTTP Version Not Supported
505 The origin server <server name> is using an unsupported version of the HTTP protocol. response#bad_version
Invalid Content Length
400 Could not process this request because the specified Content-Length was invalid (less than 0).. request#invalid_content_length
Invalid HTTP Request
400 Could not process this <client request> HTTP method request for URL. request#syntax_error
Invalid HTTP Response
502 The host <server name> did not return the document URL correctly. response#bad_response
Malformed Server Response
502 The host <server name> did not return the document URL correctly. response#bad_response
Malformed Server Response Status
502 The host <server name> did not return the document URL correctly. response#bad_response
Maximum Transaction Time exceeded
504 Too much time has elapsed while transmitting document URL. timeout#activity
No Response Header From Server
502 The host <server name> did not return the document URL correctly. response#bad_response
Not Cached
504 This document was not available in the cache, and you (the client) only accept cached copies. cache#not_in_cache
Not Found on Accelerator
404 The request for URL on host <server name> was not found. Check the location and try again. urlrouting#no_mapping
NULL
502 The host <hostname> did not return the document URL correctly. response#bad_response
Proxy Authentication Required
407 Please log in with username and password. access#proxy_auth_required
Server Hangup
502 The server <hostname> closed the connection before the transaction was completed. connect#hangup
Temporarily Moved
302 The document you requested, URL, has moved to a new location. The new location is <new URL>. redirect#moved_temporarily
Transcoding Not Available
406 Unable to provide the document URL in the format requested by your browser. transcoding#unsupported
Tunnel Connection Failed
502 Could not connect to the server <hostname>. connect#failed_connect
Unknown Error
502 The host <hostname> did not return the document URL correctly. response#bad_response
Unknown Host
500 Unable to locate the server named <hostname>; the server does not have a DNS entry. Perhaps there is a misspelling in the server name or the server no longer exists; double-check the name and try again. connect#dns_failed
Unsupported URL Scheme
400 Cannot perform your request for the document URL because the protocol scheme is unknown. request#scheme_unsupported
Standard HTTP Response Messages

The following standard HTTP response messages are provided for your information.

200
OK
202
Accepted
204
No Content
206
Partial Content
300
Multiple Choices
301
Moved Permanently
302
Found
303
See Other
304
Not Modified
400
Bad Request
401
Unauthorized; retry
403
Forbidden
404
Not Found
405
Method Not Allowed
406
Not acceptable
408
Request Timeout
500
Internal server error
501
Not Implemented
502
Bad Gateway
504
Gateway Timeout

Performance Tuning

Before you start

There is no single option to that will guarantee maximum performance of Apache Traffic Server in every use-case. There are however numerous options that help tune its performance under different loads and in its - often vastly different - use-cases.

Building Traffic Server

A lot of speed can be gained or lost depending on the way ATS is built.

Tuning the Machine
Operating Systems Options
Optimal Use of Memory
Tuning different Thread types
Tuning Plugin Execution

FAQ and Troubleshooting Tips

FAQs
How do you create a raw disk for the cache if all your disks have mounted file systems?

Create a large file on filesystem (with dd(1)) and mount it as loopback device. This is accomplished with losetup(8) on Linux, lofiadm(1m) on Solaris and Illumos, and mdconfig(8) on FreeBSD.

How do disk I/O errors affect the cache and what does Traffic Server do when a cache disk fails?

If a disk drive fails five successive I/O operations, then Traffic Server considers the drive inaccessible and removes the entire disk from the cache. Normal cache operations continue for all other Traffic Server disk drives.

If a client disconnects during the time that Traffic Server is downloading a large object, is any of the object saved in the cache?

When a client disconnects during an HTTP operation, Traffic Server continues to download the object from the origin server for up to 10 seconds. If the transfer from the origin server completes successfully within 10 seconds after the client disconnect, then Traffic Server stores the object in cache. If the origin server download does not complete successfully within 10 seconds, then Traffic Server disconnects from the origin server and deletes the object from cache. Traffic Server does not store partial documents in the cache.

Can Traffic Server cache Java applets, JavaScript programs, or other application files like VBScript?

Yes, Traffic Server can store and serve Java applets, JavaScript programs, VBScripts, and other executable objects from its cache according to the freshness and cacheability rules for HTTP objects. Traffic Server does not execute the applets, scripts, or programs, however - these objects run only when the client system (ie, the one that sent the request) loads them.

In Squid- and Netscape-format log files, what do the cache result codes mean?

This is described in detail in the Squid Format documentation.

What is recorded by the cqtx field in a custom log file?
  • In forward proxy mode, the cqtx field records the complete client request in the log file (for example, GET http://www.company.com HTTP/1.0).
  • In reverse proxy mode, the cqtx field records the hostname or IP address of the origin server because Traffic Server first remaps the request as per map rules in the remap.config file.
Does Traffic Server refresh entries in its host database after a certain period of time if they have not been used?

By default, the Traffic Server host database observes the time-to-live (ttl) values set by name servers. You can reconfigure Traffic Server to ignore the ttl set by name servers and use a specific Traffic Server setting instead. Alternatively, you can configure Traffic Server to compare the ttl value set by the name server with the ttl value set by Traffic Server, and then use either the lower or the higher value.

see proxy.config.hostdb.ttl_mode for more info

Can you improve the look of your custom response pages by using images, animated .gifs, and Java applets?

No, because Traffic Server can only respond to clients with a single text or HTML document. As a workaround, however, you can provide references on your custom response pages to images, animated .gifs, Java applets, or objects other than text which are located on a web server. Add links in the body_factory template files in the same way you would for any image in an HTML document (i.e., with the full URL in the SRC attribute).

Can Traffic Server run in forward proxy and reverse proxy modes at the same time?

Yes. When you enable reverse proxy mode, Traffic Server remaps incoming requests according to the map rules in the remap.config file. All other requests that do not match a map rule are simply served in forward proxy mode.

If you want to run in reverse proxy only mode (wherein Traffic Server does not serve requests that fail to match a map rule), then you must set the configuration variable proxy.config.url_remap.remap_required to 1 in the records.config file.

How do I enable forward proxy mode

Please refer to the Forward Proxy documentation.

How do I interpret the Via: header code?

The Via header string can be decoded with the Via Decoder Ring.

Support for HTTP Expect: Header

Traffic Server currently does not handle request Expect: headers according to the HTTP/1.1 spec.

Note that clients such as cURL automatically send Expect: for POST requests with large POST bodies, with a 1 second timeout if a 100 Continue response is not received. To avoid the timeout when using cURL as a client to Traffic Server, you can turn off the Expect: header as follows:

curl -H"Expect:" http://www.example.com/

C (libcurl):

struct curl_slist *header_list=NULL;
header_list = curl_slist_append(header_list, "Expect:");
curl_easy_setopt(my_curlp, CURLOPT_HTTPHEADER, header_list);

php:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
Troubleshooting Tips
The throughput statistic is inaccurate

Traffic Server updates the throughput statistic after it has transferred an entire object. For larger files, the byte count increases sharply at the end of a transfer. The complete number of bytes transferred is attributed to the last 10-second interval, although it can take several minutes to transfer the object. This inaccuracy is more noticeable with a light load. A heavier load yields a more accurate statistic.

You are unable to execute Traffic Line commands

Traffic Line commands do not execute under the following conditions:

  • When the traffic_manager process is not running Check to see if the traffic_manager process is running by entering the following command: pgrep -l traffic_manager

    If the traffic_manager process is not running, then enter the following command from the Traffic Server bin directory to start it: ./traffic_manager

    You should always start and stop Traffic Server with the trafficserver start` and trafficserver stop commands to ensure that all the processes start and stop correctly. For more information, refer to Getting Started.

  • When you are not executing the command from $TSHome/bin If the Traffic Server bin directory is not in your path, then prepend the Traffic Line commands with ./ (for example, ./traffic_line -h).

  • When multiple Traffic Server installations are present and you are not executing the Traffic Line command from the active Traffic Server path specified in ``/etc/trafficserver``

You observe inconsistent behavior when one node obtains an object from another node in the cluster

As part of the initial system preparation, you must synchronize the clocks on all nodes in your cluster. Minor time differences do not cause problems, but differences of more than a few minutes can affect Traffic Server operation.

You should run a clock synchronization daemon such as xntpd. To obtain the latest version of xntpd, go to http://www.eecis.udel.edu/~ntp/

Web browsers display an error document with a ‘data missing’ message

A message similar to the following might display in web browsers:

Data Missing

This document resulted from a POST operation and has expired from the cache. You can repost the form data to recreate the document by pressing the Reload button.

This is a Web browser issue and not a problem specific to (or caused by) Traffic Server. Because Web browsers maintain a separate local cache in memory and/or disk on the client system, messages about documents that have expired from cache refer to the browser’s local cache and not to the Traffic Server cache. There is no Traffic Server message or condition that can cause such messages to appear in a web browser.

Traffic Server does not resolve any websites

The browser indicates that it is contacting the host and then times out with the following message:

The document contains no data; Try again later, or contact the server's Administrator...

Make sure the system is configured correctly and that Traffic Server can read the name resolution file:

  • Check if the server can resolve DNS lookups by issuing the nslookup command (for example, nslookup www.myhost.com).
  • Check if the resolv.conf(5) file contains valid IP addresses for your DNS servers.
  • On some systems, if the resolv.conf(5) file is unreadable or has no name server entry, then the operating system uses localhost as a name server. Traffic Server, however, does not use this convention. If you want to use localhost as a name server, then you must add a name server entry for 127.0.0.1 or 0.0.0.0 in the resolv.conf(5) file.
  • Check that the Traffic Server user account has permission to read the /etc/resolv.conf file. If it does not, then change the file permissions to rw-r--r-- (644)
‘Maximum document size exceeded’ message in the system log file

The following message appears in the system log file:

WARNING: Maximum document size exceeded

A requested object was larger than the maximum size allowed in the Traffic Server cache, so Traffic Server provided proxy service for the oversized object but did not cache it. To set the object size limit for the cache, modify the proxy.config.cache.max_doc_size variable in the records.config file. If you do not want to limit the size of objects in the cache, then set the document size to 0 (zero).

‘DrainIncomingChannel’ message in the system log file

The following messages may appear in the system log file:

Feb 20 23:53:40 louis traffic_manager[4414]: ERROR ==> [drainIncomingChannel] Unknown message: 'GET http://www.telechamada.pt/ HTTP/1.0'
Feb 20 23:53:46 louis last message repeated 1 time
Feb 20 23:53:58 louis traffic_manager[4414]: ERROR ==> [drainIncomingChannel] Unknown message: 'GET http://www.ip.pt/ HTTP/1.0'

These error messages indicate that a browser is sending HTTP requests to one of the Traffic Server cluster ports - either rsport (default port 8088) or mcport (default port 8089). Traffic Server discards the request; this error does not cause any Traffic Server problems. The misconfigured browser must be reconfigured to use the correct proxy port. Traffic Server clusters work best when configured to use a separate network interface and cluster on a private subnet, so that client machines have no access to the cluster ports.

‘No cop file’ message in the system log file

The following message appears repeatedly in the system log file:

traffic_cop[16056]: encountered "var/trafficserver/no_cop" file...exiting

The file var/trafficserver/no_cop acts as an administrative control that instructs the traffic_cop process to exit immediately without starting traffic_manager or performing any health checks. The no_cop file prevents Traffic Server from starting automatically when it has been stopped with the option:trafficserver stop command. Without this static control, Traffic Server would restart automatically upon system reboot. The no_cop control keeps Traffic Server off until it is explicitly restarted with the

trafficserver start

command.

Warning in the system log file when manually editing vaddrs.config

If you manually edit the vaddrs.config file as a non-root user, then Traffic Server issues a warning message in the system log file similar to the following:

WARNING: interface is ignored: Operation not permitted

You can safely ignore this message; Traffic Server does apply your configuration edits.

Traffic Server is running but no log files are created

Traffic Server only writes event log files when there is information to record. If Traffic Server is idle, then it’s possible/probable that no log files exist. In addition:

Make sure you’re looking in the correct directory. By default, Traffic Server creates log files in the logs directory. Check the location of log files by checking the value of the variable proxy.config.log.logfile_dir in the records.config file. Check that the log directory has read/write permissions for the Traffic Server user account. If the log directory does not have the correct permissions, then the traffic_server process is unable to open or create log files. Check that logging is enabled by checking the value of the proxy.config.log.logging_enabled variable in the records.config file. Check that a log format is enabled. In the records.config file, select the standard or custom format by editing variables in the Logging Config section.

Traffic Server shows an error indicating too many network connections

By default, Traffic Server supports 8000 network connections: half of this number is allocated for client connections and the remaining half is for origin server connections. A connection throttle event occurs when client or origin server connections reach 90% of half the configured limit (3600 by default). When a connection throttle event occurs, Traffic Server continues processing all existing connections but will not accept new client connection requests until the connection count falls below the limit.

Connection throttle events can occur under the following conditions:

  • If there is a connection spike (e.g., if thousands of client requests all reach Traffic Server at the same time). Such events are typically transient and require no corrective action.
  • If there is a service overload (e.g., if client requests continuously arrive faster than Traffic Server can service them). Service overloads often indicate network problems between Traffic Server and origin servers. Conversely, it may indicate that Traffic Server needs more memory, CPU, cache disks, or other resources to handle the client load.

If necessary, you can reset the maximum number of connections supported by Traffic Server by editing the value of the proxy.config.net.connections_throttle configuration variable in the records.config file. Do not increase the connection throttle limit unless the system has adequate memory to handle the client connections required. A system with limited RAM might need a throttle limit lower than the default value. Do not set this variable below the minimum value of 100.

Low memory symptoms

Under heavy load, the Linux kernel can run out of RAM. This low memory condition can cause slow performance and a variety of other system problems. In fact, RAM exhaustion can occur even if the system has plenty of free swap space.

Symptoms of extreme memory exhaustion include the following messages in the system log files (/var/log/messages):

WARNING: errno 105 is ENOBUFS (low on kernel memory), consider a memory upgrade

kernel: eth0: can't fill rx buffer (force 0)!

kernel: recvmsg bug: copied E01BA916 seq E01BAB22

To avoid memory exhaustion, add more RAM to the system or reduce the load on Traffic Server.

Connection timeouts with the origin server

Certain origin servers take longer than 30 seconds to post HTTP requests, which results in connection timeouts with Traffic Server. To prevent such connection timeouts, you must change the value of the configuration variable proxy.config.http.connect_attempts_timeout in the records.config file to 60 seconds or more.

What Is Apache Traffic Server?

Global data networking has become part of everyday life: Internet users request billions of documents and terabytes of data, on a daily basis, to and from all parts of the world. Information is free, abundant, and accessible. Unfortunately, global data networking can also be a nightmare for IT professionals as they struggle with overloaded servers and congested networks. It can be challenging to consistently and reliably accommodate society’s growing data demands.

Traffic Server is a high-performance web proxy cache that improves network efficiency and performance by caching frequently-accessed information at the edge of the network. This brings content physically closer to end users, while enabling faster delivery and reduced bandwidth use. Traffic Server is designed to improve content delivery for enterprises, Internet service providers (ISPs), backbone providers, and large intranets by maximizing existing and available bandwidth.

Traffic Server Deployment Options

To best suit your needs, Traffic Server can be deployed in several ways:

  • As a web proxy cache
  • As a reverse proxy
  • In a cache hierarchy

The following sections provide a summary of these Traffic Server deployment options. Please keep in mind that with every of these options Traffic Server can be run as a single instance, or as a multi-node cluster.

Traffic Server as a Web Proxy Cache

As a web proxy cache, Traffic Server receives user requests for web content as those requests travel to the destined web server (origin server). If Traffic Server contains the requested content, then it serves the content directly. If the requested content is not available from cache, then Traffic Server acts as a proxy: it obtains the content from the origin server on the user’s behalf and also keeps a copy to satisfy future requests.

Traffic Server provides explicit proxy caching, in which the user’s client software must be configured to send requests directly to Traffic Server. Explicit proxy caching is described in the Explicit Proxy Caching chapter.

Traffic Server as a Reverse Proxy

As a reverse proxy, Traffic Server is configured to be the origin server to which the user is trying to connect (typically, the origin server’s advertised hostname resolves to Traffic Server, which acts as the real origin server). The reverse proxy feature is also called server acceleration. Reverse proxy is described in more detail in Reverse Proxy and HTTP Redirects.

Traffic Server in a Cache Hierarchy

Traffic Server can participate in flexible cache hierarchies, in which Internet requests not fulfilled from one cache are routed to other regional caches, thereby leveraging the contents and proximity of nearby caches. In a hierarchy of proxy servers, Traffic Server can act either as a parent or a child cache to other Traffic Server systems or to similar caching products.

Traffic Server supports ICP (Internet Cache Protocol) peering. Hierarchical caching is described in more detail in Hierarchical Caching.

Deployment Limitations

There’s a number of deployment options that Traffic Server does not support right out of the box. Such funcionality may be implemented in a plugin, but in some cases Traffic Server’s internal APIs or architectural restrictions won’t make it easy:

  • Load Balancing - note that there is an experimental plugin for this: Balancer Plugin.

Traffic Server Components

Traffic Server consists of several components that work together to form a web proxy cache you can easily monitor and configure. These main components are described below.

The Traffic Server Cache

The Traffic Server cache consists of a high-speed object database called the object store. The object store indexes objects according to URLs and associated headers. Using sophisticated object management, the object store can cache alternate versions of the same object (perhaps in a different language or encoding type). It can also efficiently store very small and very large objects, thereby minimizing wasted space. When the cache is full, Traffic Server removes stale data to ensure that the most requested objects are readily available and fresh.

Traffic Server is designed to tolerate total disk failures on any of the cache disks. If the disk fails completely, then Traffic Server marks the entire disk as corrupt and continues to use remaining disks. If all of the cache disks fail, then Traffic Server switches to proxy-only mode. You can partition the cache to reserve a certain amount of disk space for storing data for specific protocols and origin servers. For more information about the cache, see Configuring the Cache.

The RAM Cache

Traffic Server maintains a small RAM cache that contains extremely popular objects. This RAM cache serves the most popular objects as fast as possible and reduces load on disks, especially during temporary traffic peaks. You can configure the RAM cache size to suit your needs; for detailed information, refer to Changing the Size of the RAM Cache.

The Host Database

The Traffic Server host database stores the domain name server (DNS) entries of origin servers to which Traffic Server connects to fulfill user requests. This information is used to adapt future protocol interactions and optimize performance. Along with other information, the host database tracks:

  • DNS information (for fast conversion of hostnames to IP addresses)
  • The HTTP version of each host (so advanced protocol features can be used with hosts running modern servers)
  • Host reliability and availability information (so users will not wait for servers that are not running)
The DNS Resolver

Traffic Server includes a fast, asynchronous DNS resolver to streamline conversion of hostnames to IP addresses. Traffic Server implements the DNS resolver natively by directly issuing DNS command packets rather than relying on slower, conventional resolver libraries. Since many DNS queries can be issued in parallel and a fast DNS cache maintains popular bindings in memory, DNS traffic is reduced.

Traffic Server Processes

Traffic Server contains three processes that work together to serve requests and manage/control/monitor the health of the system. The three processes are described below:

  • The traffic_server process is the transaction processing engine of Traffic Server. It is responsible for accepting connections, processing protocol requests, and serving documents from the cache or origin server.

  • The traffic_manager process is the command and control facility of the Traffic Server, responsible for launching, monitoring, and reconfiguring the traffic_server process. The traffic_manager process is also responsible for the proxy autoconfiguration port, the statistics interface, cluster administration, and virtual IP failover.

    If the traffic_manager process detects a traffic_server process failure, it instantly restarts the process but also maintains a connection queue of all incoming requests. All incoming connections that arrive in the several seconds before full server restart are saved in the connection queue and processed in first-come, first-served order. This connection queueing shields users from any server restart downtime.

  • The traffic_cop process monitors the health of both the traffic_server and traffic_manager processes. The traffic_cop process periodically (several times each minute) queries the traffic_server and traffic_manager process by issuing heartbeat requests to fetch synthetic web pages. In the event of failure (if no response is received within a timeout interval or if an incorrect response is received), traffic_cop restarts the traffic_manager and traffic_server processes.

The figure below illustrates the three Traffic Server processes.

Illustration of the three Traffic Server Processes

Illustration of the three Traffic Server Processes

Administration Tools

Traffic Server offers the following administration options:

  • The Traffic Line command-line interface is a text-based interface from which you can monitor Traffic Server performance and network traffic, as well as configure the Traffic Server system. From Traffic Line, you can execute individual commands or script a series of commands in a shell.
  • The Traffic Shell command-line interface is an additional command-line tool that enables you to execute individual commands that monitor and configure the Traffic Server system.
  • Various configuration files enable you to configure Traffic Server through a simple file-editing and signal-handling interface. Any changes you make through Traffic Line or Traffic Shell are automatically made to the configuration files as well.
  • Finally there is a clean C API which can be put to good use from a multitude of languages. The Traffic Server Admin Client demonstrates this for Perl.

Traffic Analysis Options

Traffic Server provides several options for network traffic analysis and monitoring:

  • Traffic Line and Traffic Shell enable you to collect and process statistics obtained from network traffic information.

  • Transaction logging enables you to record information (in a log file) about every request Traffic Server receives and every error it detects. By analyzing the log files, you can determine how many clients used the Traffic Server cache, how much information each of them requested, and what pages were most popular. You can also see why a particular transaction was in error and what state the Traffic Server was in at a particular time; for example, you can see that Traffic Server was restarted or that cluster communication timed out.

    Traffic Server supports several standard log file formats, such as Squid and Netscape, and its own custom format. You can analyze the standard format log files with off-the-shelf analysis packages. To help with log file analysis, you can separate log files so that they contain information specific to protocol or hosts.

Traffic analysis options are described in more detail in Monitoring Traffic.

Traffic Server logging options are described in Working with Log Files.

Traffic Server Security Options

Traffic Server provides numerous options that enable you to establish secure communication between the Traffic Server system and other computers on the network. Using the security options, you can do the following:

  • Control client access to the Traffic Server proxy cache.
  • Configure Traffic Server to use multiple DNS servers to match your site’s security configuration. For example, Traffic Server can use different DNS servers, depending on whether it needs to resolve hostnames located inside or outside a firewall. This enables you to keep your internal network configuration secure while continuing to provide transparent access to external sites on the Internet.
  • Configure Traffic Server to verify that clients are authenticated before they can access content from the Traffic Server cache.
  • Secure connections in reverse proxy mode between a client and Traffic Server, and Traffic Server and the origin server, using the SSL termination option.
  • Control access via SSL (Secure Sockets Layer).

Traffic Server security options are described in more detail in Security Options.

Tuning Traffic Server

Finally this last chapter on Performance Tuning discusses the vast number of options that allow to optimally tune Apache Traffic Server for maximum performance.

Programmers’ Guide

In progress

Abstract

The Traffic Server Software Developers Kit shows you how to create plugins using the Traffic Server SDK.

Introduction

This documentation is a work in progress. It was originally written for a previous, commercially-available version of Traffic Server that supported different operating systems and more functions than the current version. As a result, some of the sections may refer to functionality that no longer exists.

If you find any such issues, you may want to submit a bug or a patch. We also have a Wiki page explaining how to create useful bug reports. We encourage everyone to file tickets, early and often. Looking for existing, duplicate bugs is encouraged, but not required.

Contents:

Preface
How to Use This Book

This book has the following basic components:

  • Introduction and overview
  • Tutorials about writing specific kinds of plugins: HTTP header-based plugins, content transformation plugins, and protocol plugins
  • Guides about specific interfaces
  • Reference material

If you’re new to writing Traffic Server plugins, then read Getting Started and How to Create Traffic Server Plugins, and use the remaining chapters as needed. Header-Based Plugin Examples provides details about plugins that work on HTTP headers, while HTTP Transformation Plugins explains how to write a plugin that transforms or scans the body of an HTTP response. New Protocol Plugins provides essential information if you want to support your own protocol on Traffic Server.

You can look up information in the following reference sections:

Below is a section-by-section breakdown of this guide:

  • Getting Started How to compile and load plugins. Walks through a simple “hello world” example; explains how to initialize and register plugins.
  • How to Create Traffic Server Plugins Basic structures that all plugins use: events, continuations, and how to hook on to Traffic Server processes. Detailed explication of a sample blacklisting plugin.
  • Remap Plugin This chapter demonstrates on a practical example how you can exploit the Traffic Server remap API for your plugins.
  • Header-Based Plugin Examples Detailed explanation about writing plugins that work on HTTP headers; discusses sample blacklisting and basic authorization plugins.
  • HTTP Transformation Plugins Detailed explanation of the null-transform example; also discusses VConnections, VIOs, and IO buffers.
  • New Protocol Plugins Detailed explanation of a sample protocol plugin that supports a synthetic protocol. Discusses VConnections and mutexes, as well as the new NetConnection, DNS lookup, logging, and cache APIs.

The remaining sections comprise the API function reference and are organized by function type:

  • Miscellaneous Interface Guide Details error-writing and tracing functions, thread functions, and Traffic Server API versions of the malloc and fopen families. The Traffic Server API versions overcome various C library limitations.
  • HTTP Hooks and Transactions Functions in this chapter hook your plugin to Traffic Server HTTP processes.
  • HTTP Headers Contains instructions for implementing performance enhancements for all plugins that manipulate HTTP headers. These functions examine and modify HTTP headers, MIME headers, URLs, and the marshal buffers that contain header information. If you are working with headers, then be sure to read this chapter.
  • Mutex Guide
  • Continuations Continuations provide the basic callback mechanism and data abstractions used in Traffic Server.
  • Plugin Configurations
  • Actions Guide Describes how to use TSActions and the TSDNSLookup API.
  • IO Guide Describes how to use the Traffic Server IO interfaces: TSVConnection, TSVIO, TSIOBuffer, TSNetVConnection, the Cache API.
  • Plugin Management These functions enable you to set up a configuration interface for plugins, access installed plugin files, and set up plugin licensing.
  • Adding Statistics These functions add statistics to your plugin.
  • Function Index Doxygen generated Traffic Server API Documentation
Typographical Conventions

This document uses the following typographic conventions:

_italics _ or * bold*
Used to introduce terms.
monospaced face
Represents C language statements, commands, file content, and computer output.
``monospaced italic``
Represents variables for which you should substitute a value.
... (ellipsis)
Indicates the omission of irrelevant or unimportant information.

The Traffic Server Software Developer’s Kit is a reference for creating plugins. Plugins are programs that add services (such as filtering or content transformation) or entire features (such as new protocol support) to Traffic Server. If you are new to writing Traffic Server plugins, then read the first two chapters, Getting Started and How to Create Traffic Server Plugins, and use the remaining chapters as needed. Header-Based Plugin Examples provides details about plugins that work on HTTP headers, while HTTP Transformation Plugins explains how to write a plugin that transforms or scans the body of an HTTP response. If you want to support your own protocol on Traffic Server, then reference New Protocol Plugins.

Audience

This manual is intended for programmers who want to write plugin programs that add services or features to Traffic Server. It assumes a cursory knowledge of the C programming language, Hyper-Text Transfer Protocol (HTTP), and Multipurpose Internet Mail Extensions (MIME).

Getting Started
A Simple Plugin

This section describes how to write, compile, configure, and run a simple Traffic Server plugin. You’ll follow the steps below:

  1. Make sure that your plugin source code contains an TSPluginInit initialization function.
  2. Compile your plugin source code, creating a shared library.
  3. Add an entry to your plugin’s plugin.config file.
  4. Add the path to your plugin shared library into the records.config file.
  5. Restart Traffic Server.
Compile Your Plugin

The process for compiling a shared library varies with the platform used, so the Traffic Server API provides the tsxs tool which you can use to create shared libraries on all the supported Traffic Server platforms.

Example

Assuming the sample program is stored in the file hello-world.c, you could use the following commands to build a shared library

tsxs -o hello-world.so -c hello-world.c

This shared library will be your plugin. In order to install it, run

sudo tsxs -o hello-world.so -i

or the equivalent to sudo on your platform.

Update the plugin.config File

Your next step is to tell Traffic Server about the plugin by adding the following line to the plugin.config file. Since our simple plugin does not require any arguments, the following plugin.config will work:

# a simple plugin.config for hello-world
hello-world.so

Traffic Server can accommodate multiple plugins. If several plugin functions are triggered by the same event, then Traffic Server invokes each plugin’s function in the order each was defined in the plugin.config file.

Specify the Plugin’s Location

All plugins must be located in the directory specified by the configuration variable proxy.config.plugin.plugin_dir, which is located in the records.config file. The directory can be specified as an absolute or relative path.

If a relative path is used, then the starting directory will be the Traffic Server installation directory as specified in /etc/traffic_server. The default value is libexec/trafficserver, but this can vary based on how the software was configured and built. It is common to use the default directory. Be sure to place the shared library hello-world.so inside the directory you’ve configured.

Restart Traffic Server

The last step is to start/restart Traffic Server. Shown below is the output displayed after you’ve created and loaded your hello-world plugin.

# ls libexec/trafficserver
hello-world.so*
# bin/traffic_server
[Mar 27 19:06:31.669] NOTE: updated diags config
[Mar 27 19:06:31.680] NOTE: loading plugin 'libexec/trafficserver/hello-world.so'
hello world
[Mar 27 19:06:32.046] NOTE: cache disabled (initializing)
[Mar 27 19:06:32.053] NOTE: cache enabled
[Mar 27 19:06:32.526] NOTE: Traffic Server running

Note: in the example above, Traffic Server notes are directed to the console by specifying E for proxy.config.diags.output.note in records.config. The second note shows Traffic Server attempting to load the hello-world plugin. The third line of Traffic Server output is from your plugin.

Plugin Registration and Version Checking

Make sure that the functions in your plugin are supported in your version of Traffic Server.

Use the following interfaces:

The following version of hello-world registers the plugin and ensures it’s running with a compatible version of Traffic Server.

    :::c
#include <stdio.h>
#include <ts/ts.h>
int
check_ts_version()
{

 const char *ts_version = TSTrafficServerVersionGet();
 int result = 0;

   if (ts_version) {
    int major_ts_version = 0;
    int minor_ts_version = 0;
    int patch_ts_version = 0;

   if (sscanf(ts_version, "%d.%d.%d", &major_ts_version,
      &minor_ts_version, &patch_ts_version) != 3) {
      return 0;
  }

  /* We need at least Traffic Server 2.0 */

   if (major_ts_version >= 2) {
      result = 1;
   }

  }

  return result;
}

void
TSPluginInit (int argc, const char *argv[])
{

      TSPluginRegistrationInfo info;

      info.plugin_name = "hello-world";
      info.vendor_name = "MyCompany";
      info.support_email = "ts-api-support@MyCompany.com";

      if (!TSPluginRegister (TS_SDK_VERSION_2_0 , &info)) {
         TSError ("Plugin registration failed. \n");
      }

      if (!check_ts_version()) {
         TSError ("Plugin requires Traffic Server 2.0 or later\n");
         return;
      }

      TSDebug ("debug-hello", "Hello World!\n");
}
Naming Conventions

The Traffic Server API adheres to the following naming conventions:

  • The TS prefix is used for all function and variable names defined in the Traffic Server API. Examples: TS_EVENT_NONE,TSMutex, and TSContCreate
  • Enumerated values are always written in all uppercase letters. Examples: ``TS_EVENT_NONE`` and ``TS_VC_CLOSE_ABORT``
  • Constant values are all uppercase; enumerated values can be seen as a subset of constants. Examples: TS_URL_SCHEME_FILE and TS_MIME_FIELD_ACCEPT
  • The names of defined types are mixed-case. Examples: ``TSHttpSsn`` and ``TSHttpTxn``
  • Function names are mixed-case. Examples: TSUrlCreate and TSContDestroy
  • Function names use the following subject-verb naming style: TS-<subject>-<verb>, where <subject> goes from general to specific. This makes it easier to determine what a function does by reading its name. For example: the function to retrieve the password field (the specific subject) from a URL (the general subject) is TSUrlPasswordGet.
  • Common verbs like Create, Destroy, Get, Set, Copy, Find, Retrieve, Insert, Remove, and Delete are used only when appropriate.

The Traffic Server API enables you to create plugins, using the C programming language, that customize the behavior of your Traffic Server installation. This chapter contains the following sections:

Understanding Traffic Server Plugins

Traffic Server enables sophisticated caching and processing of web-related traffic, such as DNS and HTTP requests and responses.

Traffic Server itself consists of an event-driven loop that can be simplified as follows:

for (;;) {
   event = get_next_event();
   handle_event (event);
}
The Role of Plugins

You compile your plugin source code to create a shared library that Traffic Server loads when it is started. Your plugin contains callback functions that are registered for specific Traffic Server events. When Traffic Server needs to process an event, it invokes any and all call-back functions you’ve registered for that event type.

警告

Since plugins add object code to Traffic Server, programming errors in a plugin can have serious implications. Bugs in your plugin, such as an out-of-range pointer, can cause Traffic Server processes to crash and may ultimately result in unpredictable behavior.

Plugin Process

Plugin Process

Plugin Process

Possible Uses for Plugins

Possible uses for plugins include the following:

  • HTTP processing: plugins can filter, blacklist, authorize users, transform content
  • Protocol support: plugins can enable Traffic Server to proxy-cache new protocol content

Some examples of plugins include:

  • Blacklisting plugin: denies attempts to access web sites that are off-limits.
  • Append transform plugin: adds text to HTTP response content.
  • Image conversion plugin: transforms JPEG images to GIF images.
  • Compression plugin: sends response content to a compression server that compresses the data (alternatively, a compression library local to the Traffic Server host machine could do the compression).
  • Authorization plugin: checks a user’s permissions to access particular web sites. The plugin could consult a local authorization program or send queries to an authorization server.
  • A plugin that gathers client information from request headers and enters this information in a database.
  • Protocol plugin: listens for specific protocol requests on a designated port and then uses Traffic Server’s proxy server & cache to serve client requests.

The figure below, Possible Traffic Server Plugins, illustrates several types of plugins.

Possible Traffic Server Plugins

Possible Traffic Server Plugins

Possible Traffic Server Plugins

You can find basic examples for many plugins in the SDK sample code:

  • append-transform.c adds text from a specified file to HTTP/text responses. This plugin is explained in The Append-Transform Plugin
  • The compression plugin in the figure communicates with the server that actually does the compression. The server-transform.c plugin shows how to open a connection to a transformation server, have the server do the transformation, and send transformed data back to the client. Although the transformation is null in server-transform.c, a compression or image translation plugin could be implemented in a similar way.
  • basic-auth.c performs basic HTTP proxy authorization.
  • blacklist-1.c reads blacklisted servers from a configuration file and denies client access to these servers. This plugin is explained in The Blacklist Plugin.
Plugin Loading

When Traffic Server is first started, it consults the plugin.config file to determine the names of all shared plugin libraries that need to be loaded. The plugin.config file also defines arguments that are to be passed to each plugin’s initialization function, TSPluginInit. The records.config file defines the path to each plugin shared library, as described in Specify the Plugin’s Location.

注解

The path for each of these files is <root_dir>/config/, where <root_dir> is where you installed Traffic Server.

Plugin Configuration

The sample plugin.config file below contains a comment line, a blank line, and two plugin configurations:

# This is a comment line.

my-plugin.so junk.example.com trash.example.org garbage.example.edu
some-plugin.so arg1 arg2 $proxy.config.http.cache.on

Each plugin configuration in the plugin.config file resembles a UNIX or DOS shell command; each line in plugin.config cannot exceed 1023 characters.

The first plugin configuration is for a plugin named my-plugin.so. It contains three arguments that are to be passed to that plugin’s initialization routine. The second configuration is for a plugin named some-plugin.so; it contains three arguments. The last argument, ``$proxy.config.http.cache.on``, is actually a configuration variable. Traffic Server will look up the specified configuration variable and substitute its value.

Plugins with global variables should not appear more than once in plugin.config. For example, if you enter:

add-header.so header1
add-header.so header2

then the second global variable, header2, will be used for both instances. A simple workaround is to give different names to different instances of the same plugin. For example:

cp add-header.so add-header1.so
cp add-header.so add-header2.so

These entries will produce the desired result below:

add-header1.so header1
add-header2.so header2
Configuration File Rules
  • Comment lines begin with # and continue to the end of the line.
  • Blank lines are ignored.
  • Plugins are loaded and initialized by Traffic Server in the order they appear in the plugin.config file.
Plugin Initialization

Each plugin must define an initialization function named TSPluginInit that Traffic Server invokes when the plugin is loaded. The TSPluginInit function is commonly used to read configuration information and register hooks for event notification.

The TSPluginInit function has two arguments:

  • The argc argument represents the number of arguments defined in the plugin.config file for that particular plugin
  • The argv argument is an array of pointers to the actual arguments defined in the plugin.config file for that plugin

See TSPluginInit() for details about TSPluginInit.

How to Create Traffic Server Plugins
Roadmap for Creating Plugins

This chapter has provided an overview of Traffic Server’s HTTP processing, API hooks, and the asynchronous event model. Next, you must understand the capabilities of Traffic Server API functions. These are quite broad:

  • HTTP header manipulation functions

    Obtain information about and manipulate HTTP headers, URLs, & MIME headers.

  • HTTP transaction functions

    Get information about and modify HTTP transactions (for example: get the client IP associated to the transaction; get the server IP; get parent proxy information)

  • IO functions

    Manipulate vconnections (virtual connections, used for network and disk I/O)

  • Network connection functions

    Open connections to remote servers.

  • Statistics functions

    Define and compute statistics for your plugin’s activity.

  • Traffic Server management functions

    Obtain values for Traffic Server configuration and statistics variables.

Below are some guidelines for creating a plugin:

  1. Decide what you want your plugin to do, based on the capabilities of the API and Traffic Server. Two main kinds of example plugins provided with this SDK are HTTP-based (includes header-based and response transform plugins), and non-HTTP-based (a protocol plugin). These examples are discussed in the next three chapters.
  2. Determine where your plugin needs to hook on to Traffic Server’s HTTP processing (view the HTTP Transaction State Diagram
  3. Read Header-Based Plugin Examples to learn the basics of writing plugins: creating continuations and setting up hooks. If you want to write a plugin that transforms data, then read HTTP Transformation Plugins
  4. Figure out what parts of the Traffic Server API you need to use and then read about the details of those APIs in this manual’s reference chapters.
  5. Compile and load your plugin (see Getting Started
  6. Depending on your plugin’s functionality, you might start testing it by issuing requests by hand and checking for the desired behavior in Traffic Server log files. See the *Traffic Server Administrator’s Guide* for information about Traffic Server logs.
  7. You can test the performance of Traffic Server running with your plugin using SDKTest. You can also customize SDKTest to perform functional testing on your plugin; for more information see the *Traffic Server SDKTest User’s Guide*.

This chapter provides a foundation for designing and writing plugins. Reading this chapter will help you to understand:

  • The asynchronous event mode. This is the design paradigm used throughout Traffic Server; plugins must also follow this design. It includes the callback mechanism for Traffic Server to “wake up” your plugin and put it to work.
  • Traffic Server’s HTTP processing, with an overview of the HTTP state machine.
  • How plugins can hook onto and modify/extend Traffic Server’s HTTP processing.
  • A roadmap for writing plugins, with an overview of the functionality provided by the Traffic Server API.
The Asynchronous Event Model

Traffic Server is a multi-threaded process. There are two main reasons why a server might use multiple threads:

  • To take advantage of the concurrency available with multiple CPUs and multiple I/O devices.
  • To manage concurrency from having many simultaneous client connections. For example, a server could create one thread for each connection, allowing the operating system (OS) to control switching between threads.

Traffic Server uses multiple threads for the first reason. However, Traffic Server does not use a separate OS thread per transaction because it would not be efficient when handling thousands of simultaneous connections.

Instead, Traffic Server provides special event-driven mechanisms for efficiently scheduling work: the event system and continuations. The event system is used to schedule work to be done on threads. A continuation is a passive, event-driven state machine that can do some work until it reaches a waiting point; it then sleeps until it receives notification that conditions are right for doing more work. For example, HTTP state machines (which handle HTTP transactions) are implemented as continuations.

Continuation objects are used throughout Traffic Server. Some might live for the duration of the Traffic Server process, while others are created (perhaps by other continuations) for specific needs and then destroyed. Traffic Server Internals (below) shows how the major components of Traffic Server interact. Traffic Server has several processors, such as cache processor and net processor, that consolidate cache or network I/O tasks. Processors talk to the event system and schedule work on threads. An executing thread calls back a continuation by sending it an event. When a continuation receives an event, it wakes up, does some work, and either destroys itself or goes back to sleep & waits for the next event.

Traffic Server Internals

Traffic Server Internals

Traffic Server Internals

Plugins are typically implemented as continuations. All of the sample code plugins (except hello-world) are continuations that are created when Traffic Server starts up; they then wait for events that trigger them into activity.

Traffic Server with Plugins

Traffic Server with Plugins

Traffic Server with Plugins

A plugin may consist of just one static continuation that is called whenever certain events happen. Examples of such plugins include blacklist-1.c, basic-auth.c, and redirect-1.c. Alternatively, a plugin might dynamically create other continuations as needed. Transform plugins are built in this manner: a static parent continuation checks all transactions to see if any are transformable; when a transaction is transformable, the static continuation creates a type of continuation called a vconnection. The vconnection lives as long as it takes to complete the transform and then destroys itself. This design can be seen in all of the sample transform plugins. Plugins that support new protocols also have this architecture: a static continuation listens for incoming client connections and then creates transaction state machines to handle each protocol transaction.

When you write plugins, there are several ways to send events to continuations. For HTTP plugins, there is a “hook” mechanism that enables the Traffic Server HTTP state machine to send your plugin wakeup calls when needed. Additionally, several Traffic Server API functions trigger Traffic Server sub-processes to send events to plugins: TSContCall, TSVConnRead, TSCacheWrite, and TSMgmtUpdateRegister, to name a few.

Traffic Server HTTP State Machine

Traffic Server performs sophisticated HTTP caching and proxying. Important features include checking for alternates and document freshness, filtering, supporting cache hierarchies, and hosting. Traffic Server handles thousands of client requests at a time and each request is handled by an HTTP state machine. These machines follow a complex state diagram that includes all of the states required to support Traffic Server’s features. The Traffic Server API provides hooks to a subset of these states, chosen for their relevance to plugins. You can view the API hooks and corresponding HTTP states in the HTTP Transaction State Diagram.

The example in this section (below) explains how a plugin typically intervenes and extends Traffic Server’s processing of an HTTP transaction. Complete details about hooking on to Traffic Server processes are provided in HTTP Hooks and Transactions.

HTTP Transaction

An HTTP transaction consists of a client request for a web document and Traffic Server’s response. The response could be the requested web server content or it could be an error message. The content could come from the Traffic Server cache or Traffic Server might fetch it from the origin server. The following diagram shows some states in a typical transaction - specifically, the scenario wherein content is served from cache.

Simplified HTTP Transaction

Simplified HTTP Transaction

Simplified HTTP Transaction

In the diagram above, Traffic Server accepts the client connection, reads the request headers, looks up the origin server’s IP address, and looks for the requested content in the cache. If the content is not in the cache (a “miss”), then Traffic Server opens a connection to the origin server and issues a request for the content. If the content is in the cache (a “hit”), then Traffic Server checks it for freshness.

If the content is fresh, then Traffic Server sends a reply header to the client. If the content is stale, then Traffic Server opens a connection to the origin server and requests the content. The figure above, Simplified HTTP Transaction, does not show behavior in the event of an error. If there is an error at a any stage, then the HTTP state machine jumps to the “send reply header” state and sends a reply. If the reply is an error, then the transaction closes. If the reply is not an error, then Traffic Server first sends the response content before it closes the transaction.

API Hooks Corresponding to States

API Hooks Corresponding to States Listed in

API Hooks Corresponding to States Listed in

You use hooks as triggers to start your plugin. The name of a hook reflects the Traffic Server state that was just completed. For example, the “OS DNS lookup” hook wakes up a plugin right after the origin server DNS lookup. For a plugin that requires the IP address of the requested origin server, this hook is the right one to use. The Blacklist plugin works in this manner, as shown in the Blacklist Plugin diagram below.

Blacklist Plugin

Blacklist Plugin

Blacklist Plugin

Traffic Server calls the Blacklist plugin right after the origin server DNS lookup. The plugin checks the requested host against a list of blacklisted servers; if the request is allowed, then the transaction proceeds. If the host is forbidden, then the Blacklist plugin sends the transaction into an error state. When the HTTP state machine gets to the “send reply header” state, it then calls the Blacklist plugin to provide the error message that’s sent to the client.

Types of Hooks

The Blacklist plugin’s hook to the “origin server DNS lookup” state is a **global hook**, meaning that the plugin is called every time there’s an HTTP transaction with a DNS lookup event. The plugin’s hook to the “send reply header” state is a tr*ansaction hook*, meaning that this hook is only invoked for specified transactions (in the Blacklist example, it’s only used for requests to blacklisted servers). Several examples of setting up hooks are provided in the code example chapters: Header-Based Plugin Examples and HTTP Transformation Plugins

Header manipulation plugins, such as filtering, basic authorization, or redirects, usually have a global hook to the DNS lookup or the read request header states. If specific actions need to be done to the transaction further on, then the plugin adds itself to a transaction hook. Transformation plugins require a **global hook **to check all transactions for transformability followed by a transform hook, which is a type of transaction hook used specifically for transforms.

Remap Plugin
Example: Query Remap Plugin

The sample remap plugin, query_remap.c, maps client requests to a number of servers based on a hash of the request’s URL query parameter. This can be useful for spreading load for a given type of request among backend servers, while still maintaining “stickiness” to a single server for similar requests. For example, a search engine may want to send repeated queries for the same keywords to a server that has likely cached the result from a prior query.

Configuration of query_remap

The query remap plugin will allow the query parameter name to be specified, along with the hostnames of the servers to hash across. Sample remap.config rules using query_remap will look like:

map http://www.example.com/search http://srch1.example.com/search @plugin=query_remap.so @pparam=q @pparam=srch1.example.com @pparam=srch2.example.com @pparam=srch3.example.com
map http://www.example.com/profiles http://prof1.example.com/profiles @plugin=query_remap.so @pparam=user_id @pparam=prof1.example.com @pparam=prof2.example.com

The first @pparam specifies the query param key for which the value will be hashed. The remaining parameters list the hostnames of the servers. A request for http://www.example.com/search?q=apache will match the first rule. The plugin will look for the ``q`` parameter and hash the value ‘apache‘ to pick from among srch_[1-3]_.example.com to send the request.

If the request does not include a ``q`` query parameter and the plugin decides not to modify the request, the default toURL ‘http://srch1.example.com/search‘ will be used by TS.

The parameters are passed to the plugin’s tsremap_new_instance function. In query_remap, tsremap_new_instance creates a plugin-defined query_remap_info struct to store its configuration parameters. The ihandle, an opaque pointer that can be used to pass per-instance data, is set to this struct pointer and will be passed to the tsremap_remap function when it is triggered for a request.

:::c
typedef struct _query_remap_info {
  char *param_name;
  size_t param_len;
  char **hosts;
  int num_hosts;
} query_remap_info;


int tsremap_new_instance(int argc,char *argv[],ihandle *ih,char *errbuf,int errbuf_size)
{
  int i;

  if (argc param_name = strdup(argv[2]);
  qri->param_len = strlen(qri->param_name);
  qri->num_hosts = argc - 3;
  qri->hosts = (char**) TSmalloc(qri->num_hosts*sizeof(char*));

  for (i=0; i num_hosts; ++i) {
    qri->hosts[i] = strdup(argv[i+3]);
  }

  *ih = (ihandle)qri;
  return 0;
}

Another way remap plugins may want handle more complex configuration is to specify a configuration filename as a pparam and parse the specified file during instance initialization.

Performing the Remap

The plugin implements the tsremap_remap function, which is called when TS has read the client HTTP request headers and matched the request to a remap rule configured for the plugin. The TSRemapRequestInfo struct contains input and output members for the remap operation.

tsremap_remap uses the configuration information passed via the ihandle and checks the request_query for the configured query parameter. If the parameter is found, the plugin sets a new_host to modify the request host:

:::c
int tsremap_remap(ihandle ih, rhandle rh, TSRemapRequestInfo *rri)
{
  int hostidx = -1;
  query_remap_info *qri = (query_remap_info*)ih;

  if (!qri) {
    TSError("NULL ihandle");
    return 0;
  }

  if (rri && rri->request_query && rri->request_query_size > 0) {
    char *q, *s, *key;

    //make a copy of the query, as it is read only
    q = (char*) TSmalloc(rri->request_query_size+1);
    strncpy(q, rri->request_query, rri->request_query_size);
    q[rri->request_query_size] = '\0';

    s = q;
    //parse query parameters
    for (key = strsep(&s, "&"); key != NULL; key = strsep(&s, "&")) {
      char *val = strchr(key, '=');
      if (val && (size_t)(val-key) == qri->param_len &&
          !strncmp(key, qri->param_name, qri->param_len)) {
        ++val;
        //the param key matched the configured param_name
        //hash the param value to pick a host
        hostidx = hash_fnv32(val, strlen(val)) % (u_int32_t)qri->num_hosts;
        break;
      }
    }

    TSfree(q);

    if (hostidx >= 0) {
      rri->new_host_size = strlen(qri->hosts[hostidx]);
      if (rri->new_host_size new_host, qri->hosts[hostidx], rri->new_host_size);
        return 1; //host has been modified
      }
    }
  }

  //the request was not modified, TS will use the toURL from the remap rule
  return 0;
}

The Remap plugin provides a more flexible, dynamic way of specifying remap rules. It is not built on top of the Traffic Server APIs and exists solely for the purpose of URL remapping. The remap plugin is not global –it is configured on a per-remap rule basis, which enables you to customize how URLs are redirected based on individual rules in the remap.config file.

The Traffic Server Remap API enables a plugin to dynamically map a client request to a target URL. Each plugin is associated with one or more remap rules in remap.config (an “instance”). If a request URL matches a remap rule’s “fromURL”, then Traffic Server calls the plugin-defined remap function for that request.

((Editor’s note: additional text TBD; text in this chapter is still under development))

Getting Started
Remap Header File

The remap.h header file contains the Traffic Server remap API. By default, the header file location is: /usr/local/include/ts/remap.h

Required Functions

A remap plugin is required to implement the following functions:

  • TSRemapInit: the remap initialization function, called once when the plugin is loaded
  • TSRemapNewInstance: a new instance is created for each rule associated with the plugin. Called each time the plugin used in a remap rule (this function is what processes the pparam values)
  • TSRemapDoRemap: the entry point used by Traffic Server to find the new URL to which it remaps; called every time a request comes in
Configuration

To associate a remap plugin with a remap rule, use the @plugin parameter. See the Admin Guide section (?TBD?) for details on configuring remap plugins

Header-Based Plugin Examples
The Blacklist Plugin

The sample blacklisting plugin included in the Traffic Server SDK is blacklist-1.c. This plugin checks every incoming HTTP client request against a list of blacklisted web sites. If the client requests a blacklisted site, then the plugin returns an Access forbidden message to the client.

The flow of HTTP processing with the blacklist plugin is illustrated in the figure titled Blacklist Plugin. This example also contains a simple configuration management interface. It can read a list of blacklisted sites from a file (blacklist.txt) that can be updated by a Traffic Server administrator. When the configuration file is updated, Traffic Server sends an event to the plugin that wakes it up to do some work.

Creating the Parent Continuation

You create the static parent continuation in the mandatory TSPluginInit function. This parent continuation effectively is the plugin: the plugin executes only when this continuation receives an event from Traffic Server. Traffic Server passes the event as an argument to the continuation’s handler function. When you create continuations, you must create and specify their handler functions.

You can specify an optional mutex lock when you create continuations. The mutex lock protects data shared by asynchronous processes. Because Traffic Server has a multi-threaded design, race conditions can occur if several threads try to access the same continuation’s data.

Here is how the static parent continuation is created in blacklist-1.c:

void
TSPluginInit (int argc, const char *argv[])
{
   // ...
   TSCont contp;

   contp = TSContCreate (blacklist_plugin, NULL);
   // ...
}

The handler function for the plugin is blacklist_plugin, and the mutex is null. The continuation handler function’s job is to handle the events that are sent to it; accordingly, the blacklist_plugin routine consists of a switch statement that covers each of the events that might be sent to it:

static int
blacklist_plugin (TSCont contp, TSEvent event, void *edata)
{
   TSHttpTxn txnp = (TSHttpTxn) edata;
   switch (event) {
      case TS_EVENT_HTTP_OS_DNS:
         handle_dns (txnp, contp);
         return 0;
      case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
         handle_response (txnp);
         return 0;
      default:
         TSDebug ("blacklist_plugin", "This event was unexpected: %d\n", );
         break;
   }
   return 0;
}

When you write handler functions, you have to anticipate any events that might be sent to the handler by hooks or by other functions. In the Blacklist plugin, TS_EVENT_OS_DNS is sent because of the global hook established in TSPluginInit, TS_EVENT_HTTP_SEND_RESPONSE_HDR is sent because the plugin contains a transaction hook (see Setting Up a Transaction Hook). It is good practice to have a default case in your switch statements.

Setting a Global Hook

Global hooks are always added in TSPluginInit using TSHttpHookAdd. The two arguments of TSHttpHookAdd are the hook ID and the continuation to call when processing the event corresponding to the hook. In blacklist-1.c, the global hook is added as follows:

TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, contp);

Above, TS_HTTP_OS_DNS_HOOK is the ID for the origin server DNS lookup hook and contp is the parent continuation created earlier.

This means that the Blacklist plugin is called at every origin server DNS lookup. When it is called, the handler functio blacklist_plugin receives TS_EVENT_HTTP_OS_DNS and calls handle_dns to see if the request is forbidden.

Accessing the Transaction Being Processed

A continuation’s handler function is of type TSEventFunc; the prototype is as follows:

static int function_name (TSCont contp, TSEvent event, void *edata)

In general, the return value of the handler function is not used. The continuation argument is the continuation being called back, the event is the event being sent to the continuation, and the data pointed to by void *edata depends on the type of event. The data types for each event type are listed in Writing Handler Functions

The key here is that if the event is an HTTP transaction event, then the data passed to the continuation’s handler is of type TSHttpTxn (a data type that represents HTTP transactions). Your plugin can then do things with the transaction. Here’s how it looks in the code for the Blacklist plugin’s handler:

static int
blacklist_plugin (TSCont contp, TSEvent event, void *edata)
{
   TSHttpTxn txnp = (TSHttpTxn) edata;
   switch (event) {
      case TS_EVENT_HTTP_OS_DNS:
         handle_dns (txnp, contp);
         return 0;
      case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
         handle_response (txnp);
         return 0;
      default:
         break;
   }
   return 0;
}

For example: when the origin server DNS lookup event is sent, blacklist_plugin can call handle_dnsand pass txnp as an argument.

Setting Up a Transaction Hook

The Blacklist plugin sends “access forbidden” messages to clients if their requests are directed to blacklisted hosts. Therefore, the plugin needs a transaction hook so it will be called back when Traffic Server’s HTTP state machine reaches the “send response header” event. In the Blacklist plugin’s handle_dns routine, the transaction hook is added as follows:

TSMutexLock (sites_mutex);
for (i = 0; i < nsites; i++) {
   if (strncmp (host, sites[i], host_length) == 0) {
      printf ("blacklisting site: %s\n", sites[i]);
      TSHttpTxnHookAdd (txnp,
         TS_HTTP_SEND_RESPONSE_HDR_HOOK,
         contp);
      TSHandleMLocRelease (bufp, hdr_loc, url_loc);
      TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
      TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
      TSMutexUnlock (sites_mutex);
      return;
   }
}
TSMutexUnlock (sites_mutex);
done:
TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);

This code fragment shows some interesting features. The plugin is comparing the requested site to the list of blacklisted sites. While the plugin is using the blacklist, it must acquire the mutex lock for the blacklist to prevent configuration changes in the middle of a blacklisting operation. If the requested site is blacklisted, then the following things happen:

  1. A transaction hook is added with TSHttpTxnHookAdd; the plugin is called back at the “send response header” event (i.e., the plugin sends an Access forbidden message to the client). You can see that in order to add a transaction hook, you need a handle to the transaction being processed.
  2. The transaction is reenabled using TSHttpTxnReenable with TS_EVENT_HTTP_ERROR as its event argument. Reenabling with an error event tells the HTTP state machine to stop the transaction and jump to the “send response header” state. Notice that if the requested site is not blacklisted, then the transaction is reenabled with the TS_EVENT_HTTP_CONTINUE event.
  3. The string and TSMLoc data stored in the marshal buffer bufp is released by TSHandleMLocRelease (see Release Marshal Buffer Handles). Release these handles before reenabling the transaction.

In general, whenever the plugin is doing something to a transaction, it must reenable the transaction when it is finished. In other words: every time your handler function handles a transaction event, it must call TSHttpTxnReenable when it is finished. Similarly, after your plugin handles session events (TS_EVENT_HTTP_SSN_START and TS_EVENT_HTTP_SSN_CLOSE), it must reenable the session with TSHttpSsnReenable. Reenabling the transaction twice in the same plugin routine is a bad error.

Working with HTTP Header Functions

The Blacklist plugin examines the host header in every client transaction. This is done in the handle_dns routine, using TSHttpTxnClientReqGet, TSHttpHdrUrlGet, and TSUrlHostGet.

static void
handle_dns (TSHttpTxn txnp, TSCont contp)
{
TSMBuffer bufp;
TSMLoc hdr_loc;
TSMLoc url_loc;
const char *host;
int i;
int host_length;

if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
   TSError("couldn't retrieve client request header\n");
   goto done;
}

if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) {
   TSError("couldn't retrieve request url\n");
   TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
   goto done;
}

host = TSUrlHostGet(bufp, url_loc, &host_length);
if (!host) {
   TSError("couldn't retrieve request hostname\n");
   TSHandleMLocRelease(bufp, hdr_loc, url_loc);
   TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
   goto done;
}

To access the host header, the plugin must first get the client request, retrieve the URL portion, and then obtain the host header. See HTTP Headers for more information about these calls. See Release Marshal Buffer Handles for guidelines on using TSHandleMLocRelease.

The Basic Authorization Plugin

The sample basic authorization plugin, basic-auth.c, checks for basic HTTP proxy authorization. In HTTP basic proxy authorization, client user names and passwords are contained in the Proxy-Authorization header. The password is encoded using base64 encoding. The plugin checks all incoming requests for the authorization header, user name, and password. If the plugin does not find all of the these, then it reenables with an error (effectively stopping the transaction) and adds a transaction hook to the send response header event.

Creating the Plugin’s Parent Continuation and Global Hook

The parent continuation and global hook are created as follows:

TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, TSContCreate (auth_plugin, NULL));

Implementing the Handler and Getting a Handle to the Transaction

The handler function for the plugin’s parent continuation is implemented as follows:

:::c
static int
auth_plugin (TSCont contp, TSEvent event, void *edata)
{

     TSHttpTxn txnp = (TSHttpTxn) edata;
     switch (event) {
     case TS_EVENT_HTTP_OS_DNS:
          handle_dns (txnp, contp);
          return 0;
     case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
          handle_response (txnp);
          return 0;
     default:
          break;
     }

     return 0;
}
Working With HTTP Headers

The plugin checks all client request headers for the Proxy-Authorization MIME field, which should contain the user name and password. The plugin’s continuation handler, auth-plugin, calls handle_dns to check the Proxy-Authorization field. The handle_dns routine uses TSHttpTxnClientReqGet and TSMimeHdrFieldFind to obtain the Proxy-Authorization field:

:::c
{
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
    const char *val;
    char *user, *password;

    if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
        TSError ("couldn't retrieve client request header\n");
        goto done;
    }

    field_loc = TSMimeHdrFieldFind (bufp, hdr_loc,
            TS_MIME_FIELD_PROXY_AUTHORIZATION);

If the Proxy-Authorization field is present, then the plugin checks that the authentication type is “Basic”, and the user name and password are present and valid:

:::c
val = TSMimeHdrFieldValueStringGet (bufp, hdr_loc, field_loc, -1, &authval_length);
if (!val) {
    TSError ("no value in Proxy-Authorization field\n");
    TSHandleMLocRelease (bufp, hdr_loc, field_loc);
    TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
}

if (strncmp (val, "Basic", 5) != 0) {
    TSError ("no Basic auth type in Proxy-Authorization\n");
    TSHandleMLocRelease (bufp, hdr_loc, field_loc);
    TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
}

val += 5;
while ((*val == ' ') || (*val == '\t')) {
    val += 1;
}

user = base64_decode (val);
password = strchr (user, ':');
if (!password) {
    TSError ("no password in authorization information\n");
    TSfree (user);
    TSHandleMLocRelease (bufp, hdr_loc, field_loc);
    TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
}
*password = '\0';
password += 1;

if (!authorized (user, password)) {
    TSError ("%s:%s not authorized\n", user, password);
    TSfree (user);
    TSHandleMLocRelease (bufp, hdr_loc, field_loc);
    TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
}

TSfree (user);
TSHandleMLocRelease (bufp, hdr_loc, field_loc);
TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
return;
Setting a Transaction Hook

If the request does not have the Proxy-Authorization field set to Basic authorization or a valid username/password, then the plugin sends the 407 Proxy authorization required status code back to the client. The client will then prompt the user for a username and password, and then resend the request.

In the handle_dns routine, the following lines handle the authorization error case:

:::c
done:
     TSHttpTxnHookAdd (txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
     TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);

If handle_dns does not find the Proxy-Authorization field set to Basic authorization or a valid username/password, then it adds a SEND_RESPONSE_HDR_HOOK to the transaction being processed. This means that Traffic Server will call the plugin back when sending the client response. handle_dns reenables the transaction with TS_EVENT_HTTP_ERROR, which means that the plugin wants Traffic Server to terminate the transaction.

When Traffic Server terminates the transaction, it sends the client an error message. Because of the SEND_RESPONSE_HDR_HOOK, Traffic Server calls the plugin back. The auth-plugin routine calls handle_response to send the client a 407 status code. When the client resends the request with the Proxy-Authorization field, a new transaction begins.

handle_dns calls base64_decode to decode the username and password; handle_dns also calls authorized to validate the username and password. In this plugin, sample NT code is provided for password validation. UNIX programmers can supply their own validation mechanism.

Header-based plugins read or modify the headers of HTTP messages that Traffic Server sends and receives. Reading this chapter will help you to understand the following topics:

  • Creating continuations for your plugins
  • Adding global hooks
  • Adding transaction hooks
  • Working with HTTP header functions

The two sample plugins discussed in this chapter are blacklist-1.c and basic-auth.c.

Overview

Header-based plugins take actions based on the contents of HTTP request or response headers. Examples include filtering (on the basis of requested URL, source IP address, or other request header), user authentication, or user redirection. Header-based plugins have the following common elements:

  • The plugin has a static parent continuation that scans all Traffic Server headers (either request headers, response headers, or both).
  • The plugin has a global hook. This enables the plugin to check all transactions to determine if the plugin needs to do something.
  • The plugin gets a handle to the transaction being processed through the global hook.
  • If the plugin needs to do something to transactions in specific cases, then it sets up a transaction hook for a particular event.
  • The plugin obtains client header information and does something based on that information.

This chapter demonstrates how these components are implemented in SDK sample code.

HTTP Transformation Plugins

Transform plugins examine or transform HTTP message body content. For example, transform plugins can:

  • Append text to HTML documents
  • Compress images
  • Do virus checking (on client POST data or server response data)
  • Do content-based filtering (filter out HTML documents that contain certain terms or expressions)

This chapter explains how to write transform plugins. The following examples are discussed in detail:

The Sample Null Transform Plugin

This section provides a step-by-step description of what the null transform plugin does, along with sections of code that apply. For context, you can find each code snippet in the complete source code. Some of the error checking details are left out - to give the description a step-by-step flow, only the highlights of the transform are included.

Below is an overview of the null transform plugin:

  1. Gets a handle to HTTP transactions.

    :::c
    void
    TSPluginInit (int argc, const char *argv[]) {
        TSHttpHookAdd (TS_HTTP_READ_RESPONSE_HDR_HOOK,
                TSContCreate (transform_plugin, NULL));

    With this TSPluginInit routine, the plugin is called back every time Traffic Server reads a response header.

  2. Checks to see if the transaction response is transformable.

    :::c
    static int transform_plugin (TSCont contp, TSEvent event, void *edata) {
        TSHttpTxn txnp = (TSHttpTxn) edata;
        switch (event) {
            case TS_EVENT_HTTP_READ_RESPONSE_HDR:
                if (transformable (txnp)) {
                    transform_add (txnp);
                }

    The default behavior for transformations is to cache the transformed content (you can also tell Traffic Server to cache untransformed content, if you want). Therefore, only responses received directly from an origin server need to be transformed. Objects served from cache are already transformed. To determine whether the response is from the origin server, the routine transformable checks the response header for the “200 OK” server response.

    :::c
    static int transformable (TSHttpTxn txnp)
    {
        TSMBuffer bufp;
        TSMLoc hdr_loc;
        TSHttpStatus resp_status;
        TSHttpTxnServerRespGet (txnp, &bufp, &hdr_loc);
    
        if (TS_HTTP_STATUS_OK == (resp_status =
                    TSHttpHdrStatusGet (bufp, hdr_loc)) ) {
            return 1;
        } else {
            return 0;
        }
    }
  3. If the response is transformable, then the plugin creates a transformation vconnection that gets called back when the response data is ready to be transformed (as it is streaming from the origin server).

    :::c
    static void transform_add (TSHttpTxn txnp)
    {
        TSVConn connp;
        connp = TSTransformCreate (null_transform, txnp);
        TSHttpTxnHookAdd (txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
    }

    The previous code fragment shows that the handler function for the transformation vconnection is null_transform.

  4. Get a handle to the output vconnection (that receives data from the tranformation).

    :::c
    output_conn = TSTransformOutputVConnGet (con
  5. Get a handle to the input VIO. (See the handle_transform function.)

    :::c
    input_vio = TSVConnWriteVIOGet (contp);

    This is so that the transformation can get information about the upstream vconnection’s write operation to the input buffer.

  6. Initiate a write to the output vconnection of the specified number of bytes. When the write is initiated, the transformation expects to receive WRITE_READY, WRITE_COMPLETE, or ERROR events from the output vconnection. See the handle_transform function for the following code fragment:

    :::c
    data->output_vio = TSVConnWrite (output_conn, contp,
        data->output_reader, TSVIONBytesGet (input_vio));
  7. Copy data from the input buffer to the output buffer. See the handle_transform function for the following code fragment:

    ::::c
    TSIOBufferCopy (TSVIOBufferGet (data->output_vio),
            TSVIOReaderGet (input_vio), towrite, 0);
  8. Tell the input buffer that the transformation has read the data. See the handle_transform function for the following code fragment:

    TSIOBufferReaderConsume (TSVIOReaderGet (input_vio), towrite);
    
  9. Modify the input VIO to tell it how much data has been read (increase the value of ndone). See the handle_transform function for the following code fragment:

    ::::c
    TSVIONDoneSet (input_vio, TSVIONDoneGet (input_vio) + towrite);
  10. If there is more data left to read ( if ndone < nbytes), then the handle_transform function wakes up the downstream vconnection with a reenable and wakes up the upstream vconnection by sending it WRITE_READY:

    :::c
    if (TSVIONTodoGet (input_vio) > 0) {
        if (towrite > 0) {
            TSVIOReenable (data->output_vio);
    
            TSContCall (TSVIOContGet (input_vio),
                    TS_EVENT_VCONN_WRITE_READY, input_vio);
        }
        } else {

    The process of passing data through the transformation is illustrated in the following diagram. The downstream vconnections send WRITE_READY events when they need more data; when data is available, the upstream vconnections reenable the downstream vconnections. In this instance, the TSVIOReenable function sends TS_EVENT_IMMEDIATE.

    Passing Data Through a Transformation {#PassingDataThroughaTransformation}

Passing Data Through a Transformation

Passing Data Through a Transformation

  1. If the handle_transform function finds there is no more data to read, then it sets nbytes to ndone on the output (downstream) VIO and wakes up the output vconnection with a reenable. It then triggers the end of the write operation from the upstream vconnection by sending the upstream vconnection a WRITE_COMPLETE event.

    TSVIONBytesSet (data->output_vio, TSVIONDoneGet (input_vio));
       TSVIOReenable (data->output_vio);
       TSContCall (TSVIOContGet (input_vio),
          TS_EVENT_VCONN_WRITE_COMPLETE, input_vio);
    }
    

    When the upstream vconnection receives the WRITE_COMPLETE event, it will probably shut down the write operation.

  2. Similarly, when the downstream vconnection has consumed all of the data, it sends the transformation a WRITE_COMPLETE event. The transformation handles this event with a shut down (the transformation shuts down the write operation to the downstream vconnection). See the null_plugin function for the following code fragment:

    :::c
    case TS_EVENT_VCONN_WRITE_COMPLETE:
        TSVConnShutdown (TSTransformOutputVConnGet (contp), 0, 1
        break;

    The following diagram illustrates the flow of events:

    Ending the Transformation {#EndingTransformation}

    Ending the Transformation

    Ending the Transformation

The Append-Transform Plugin

The append-transform plugin appends text to the body of an HTTP response. It obtains this text from a file; the name of the file containing the append text is a parameter you specify in plugin.config, as follows:

append-transform.so path/to/file

The append-transform plugin is based on null-transform.c. The only difference is that after the plugin feeds the document through the transformation, it adds text to the response.

Below is a list of the functions in append-transform.c, in the order they appear in the source code. Below each entry is a description of what the function does:

  • ``my_data_alloc``

    Allocates and initializes a MyData structure. The plugin defines a struct, MyData, as follows:

    :::c
    typedef struct {
        TSVIO output_vio;
        TSIOBuffer output_buffer;
        TSIOBufferReader output_reader;
        int append_needed;
    } MyData;

    The MyData structure is used to represent data that the transformation (vconnection) needs. The transformation’s data pointer is set to a MyData pointer using TSContDataSet in the handle_transform routine.

  • ``my_data_destroy``

    Destroys objects of type MyData. To deallocate the transform’s data, the append_transform routine (see below) calls my_data_destroy when the transformation is complete.

  • ``handle_transform``

    This function does the actual data transformation. The transformation is created in transform_add (see below). handle_transform is called by append_transform.

  • ``append_transform``

    This is the handler function for the transformation vconnection created in transform_add. It is the implementation of the vconnection.

    • If the transformation vconnection has been closed, then append_transform calls my_data_destroy to destroy the vonnection.
    • If append_transform receives an error event, then it calls back the continuation to let it know it has completed the write operation.
    • If it receives a WRITE_COMPLETE event, then it shuts down the write portion of its vconnection.
    • If it receives a WRITE_READY or any other event (such as TS_HTTP_RESPONSE_TRANSFORM_HOOK), then it calls handle_transform to attempt to transform more data.
  • ``transformable``

    The plugin transforms only documents that have a content type of text/html. This function examines the Content-Type MIME header field in the response header. If the value of the MIME field is text/html, then the function returns 1; otherwise, it returns zero.

  • ``transform_add``

    Creates the transformation for the current transaction and sets up a transformation hook. The handler function for the transformation is append_transform.

  • ``transform_plugin``

    This is the handler function for the main continuation for the plugin. Traffic Server calls this function whenever it reads an HTTP response header. transform_plugin does the following:

    • Gets a handle to the HTTP transaction being processed
    • Calls transformable to determine whether the response document content is of type text/html
    • If the content is transformable, then it calls transform_add to create the transformation.
    • Calls TSHttpTxnReenable to continue the transaction
  • ``load``

    Opens the file containing the text to be appended and loads the contents of the file into an TSIOBuffer called append_buffer.

  • ``TSPluginInit``

    Does the following:

    • Checks to make sure that the required configuration information (the append text filename) is entered in plugin.config correctly.
    • If there is a filename, then TSPluginInit calls load to load the text.
    • Creates a continuation for the plugin. The handler for this continuation is transform_plugin.
    • Adds the plugin’s continuation to TS_HTTP_READ_RESPONSE_HDR_HOOK. In other words, it sets up a callback of the plugin’s continuation when Traffic Server reads HTTP response headers.
The Sample Buffered Null Transform Plugin

The buffered null transform, bnull-transform.c, reads the response content into a buffer and then writes the full buffer out to the client. Many examples of transformations, such as compression, require you to gather the full response content in order to perform the transformation.

The buffered null transform uses a state variable to keep track of when it is (a) reading data into the buffer and (b) writing the data from the buffer to the downstream vconnection.

The following is a step-by-step walk through the buffered null transform:

  1. Gets a handle to HTTP transactions.
void
   TSPluginInit (int argc, const char *argv[]) {
      TSHttpHookAdd (TS_HTTP_READ_RESPONSE_HDR_HOOK,
         TSContCreate (transform_plugin, NULL)); }

With this TSPluginInit routine, the plugin is called back every time Traffic Server reads a response header.

  1. Checks to see if the transaction response is transformable.
static int transform_plugin (TSCont contp, TSEvent event, void *edata) {
   TSHttpTxn txnp = (TSHttpTxn) edata;
   switch (event) {
      case TS_EVENT_HTTP_READ_RESPONSE_HDR:
         if (transformable (txnp)) {
            transform_add (txnp);
         }

The default behavior for transformations is to cache the transformed content (if desired, you also can tell Traffic Server to cache untransformed content). Therefore, only responses received directly from an origin server need to be transformed. Objects served from the cache are already transformed. To determine whether the response is from the origin server, the routine transformable checks the response header for the “200 OK” server response.

{
   TSMBuffer bufp;
   TSMLoc hdr_loc;
   TSHttpStatus resp_status;

   TSHttpTxnServerRespGet (txnp, &bufp, &hdr_loc);

   if(TS_HTTP_STATUS_OK==
      (resp_status=TSHttpHdrStatusGet(bufp,hdr_loc)))
   {
      return 1;
   }
   else {
      return 0;
   }
}
  1. If the response is transformable, then the plugin creates a transformation vconnection that gets called back when the response data is ready to be transformed (as it is streaming from the origin server).

    static void transform_add (TSHttpTxn txnp)
    {
       TSVConn connp;
       connp = TSTransformCreate (bnull_transform, txnp);
       TSHttpTxnHookAdd (txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
    }
    

    The previous code fragment shows that the handler function for the transformation vconnection is bnull_transform.

  2. The bnull_transform function has to handle ERROR, WRITE_COMPLETE, WRITE_READY, and IMMEDIATE events. If the transform is just beginning, the event received is probably IMMEDIATE. The bnull_transform function calls handle_transform to handle WRITE_READY and IMMEDIATE.

  3. The handle_transform function examines the data parameter for the continuation passed to it (the continuation passed to handle_transform is the transformation vconnection). The data structure keeps track of two states: copying the data into the buffer (STATE_BUFFER_DATA) and writing the contents of the buffer to the output vconnection (STATE_OUTPUT_DATA).

  4. Get a handle to the input VIO (see the handle_buffering function). input_vio = TSVConnWriteVIOGet (contp); This is so that the transformation can get information about the upstream vconnection’s write operation to the input buffer.

  5. Copy data from the input buffer to the output buffer. See the handle_buffering function for the following code fragment:

    TSIOBufferCopy (data->output_buffer,
       TSVIOReaderGet (write_vio), towrite, 0);
    
  6. Tell the input buffer that the transformation has read the data. See the handle_buffering function for the following code fragment:

    TSIOBufferReaderConsume (TSVIOReaderGet (write_vio), towrite);
    
  7. Modify the input VIO to tell it how much data has been read (increase the value of ndone). See the handle_buffering function for the following code fragment:

    TSVIONDoneSet (write_vio, TSVIONDoneGet (write_vio) + towrite); }
    
  8. If there is more data left to read ( if ndone < nbytes), then the handle_buffering function wakes up the upstream vconnection by sending it WRITE_READY:

    if (TSVIONTodoGet (write_vio) > 0) {
       if (towrite > 0) {
          TSContCall (TSVIOContGet (write_vio),
             TS_EVENT_VCONN_WRITE_READY, write_vio);
       }
    } else {
    

    The process of passing data through the transformation is illustrated in the following diagram. The transformation sends WRITE_READY events when it needs more data; when data is available, the upstream vconnection reenables the transformation with an IMMEDIATE event.

    The following diagram illustrates the read from an input vconnection:

    Reading Data Into the Buffer (the ``STATE_BUFFER_DATA`` State) {#ReadingDataIntoBuffer}

    Reading Data Into the Buffer the STATE\_BUFFER\_DATA State

    Reading Data Into the Buffer the STATE_BUFFER_DATA State

  9. When the data is read into the output buffer, the handle_buffering function sets the state of the transformation’s data structure to STATE_OUTPUT_DATA and calls the upstream vconnection back with the WRITE_COMPLETE event.

    data->state = STATE_OUTPUT_DATA;
    TSContCall (TSVIOContGet (write_vio),
       TS_EVENT_VCONN_WRITE_COMPLETE, write_vio);
    
  10. The upstream vconnection will probably shut down the write operation when it receives the WRITE_COMPLETE event. The handler function of the transformation, bnull_transform, receives an IMMEDIATE event and calls the handle_transform function. This time, the state is STATE_OUTPUT_DATA, so handle_transform calls handle_output.

  11. The handle_output function gets a handle to the output vconnection: output_conn = TSTransformOutputVConnGet (contp);

  12. The handle_output function writes the buffer to the output vconnection:

    data->output_vio =
       TSVConnWrite (output_conn, contp, data->output_reader,
       TSIOBufferReaderAvail (data->output_reader) );
    

    The following diagram illustrates the write to the output vconnection:

    Writing the Buffered Data to the Output Vconnection {#WritingBufferedtDataIntoVConnection}

    Writing the Buffered Data to the Output Vconnection

    Writing the Buffered Data to the Output Vconnection

Writing Content Transform Plugins

Content transformation plugins transform HTTP response content (such as images or HTML documents) and HTTP request content (such as client POST data). Because the data stream to be transformed is of variable length, these plugins must use a mechanism that passes data from buffer to buffer and checks to see if the end of the data stream is reached. This mechanism is provided by virtual connections (VConnections) and virtual IO descriptors (VIOs).

A VConnection is an abstraction for a data pipe that allows its users to perform asynchronous reads and writes without knowing the underlying implementation. A transformation is a specific type of VConnection. A transformation connects an input data source and an output data sink; this feature enables it to view and modify all the data passing through it.

Transformations can be chained together, one after the other, so that multiple transformations can be performed on the same content. The VConnection type, TSVConn, is actually a subclass of TSCont, which means that VConnections (and transformations) are continuations. VConnections and transformations can thus exchange events, informing one another that data is available for reading or writing, or that the end of a data stream is reached.

A VIO is a description of an IO operation that is in progress. Every VConnection has an associated input VIO and an associated output VIO. When VConnections are transferring data to one another, one VConnection‘s input VIO is another VConnection‘s output VIO. A VConnection‘s input VIO is also called its write ``VIO`` because the input VIO refers to a write operation performed on the VConnection itself. Similarly, the outpt VIO is also called the read ``VIO``. For transformations, which are designed to pass data in one direction, you can picture the relationship between the transformation VConnection and its VIOs as follows:

Transformation and its ``VIO``s {#TransformationAndVIOs}

A Transformation and its VIOs

A Transformation and its VIOs

Because the Traffic Server API places transformations directly in the response or request data stream, the transformation VConnection is responsible only for reading the data from the input buffer, transforming it, and then writing it to the output buffer. The upstream VConnection writes the incoming data to the transformation’s input buffer. In the figure above, A Transformation and its ``VIO`s <#TransformationAndVIOs>`__, the input VIO describes the progress of the upstream VConnection‘s write operation on the transformation, while the output VIO describes the progress of the transformation’s write operation on the output (downstream) VConnection. The nbytes value in the VIO is the total number of bytes to be written. The ndone value is the current progress, or the number of bytes that have been written at a specific point in time.

When writing a transformation plugin, you must understand implementation as well as the use of VConnections. The implementor’s side refers to how to implement a VConnection that others can use. At minimum, a transform plugin creates a transformation that sits in the data stream and must be able to handle the events that the upstream and downstream VConnections send to it. The user’s side refers to how to use a VConnection to read or write data. At the very least, transformations output (write) data.

Transformations
VIOs

A VIO``*or virtual IO is a description of an in progress IO operation. The ``VIO data structure is used by VConnection users to determine how much progress has been made on a particular IO operation, and to reenable an IO operation when it stalls due to buffer space. VConnection implementors use VIOs to determine the buffer for an IO operation, how much work to do on the IO operation, and which continuation to call back when progress on the IO operation is made.

The TSVIO data structure itself is opaque, but it might have been defined as follows:

typedef struct {
   TSCont continuation;
   TSVConn vconnection;
   TSIOBufferReader reader;
   TSMutex mutex;
   int nbytes;
   int ndone;
} *TSVIO;
IO Buffers

The IO buffer data structure is the building block of the VConnection abstraction. An IO buffer is composed of a list of buffer blocks which, in turn, point to buffer data. Both the buffer block (TSIOBufferBlock) and buffer data (TSIOBufferData) data structures are reference counted so they can reside in multiple buffers at the same time. This makes it extremely efficient to copy data from one IO buffer to another using TSIOBufferCopy, since Traffic Server only needs to copy pointers and adjust reference counts appropriately (instead of actually copying any data).

The IO buffer abstraction provides for a single writer and multiple readers. In order for the readers to have no knowledge of each other, they manipulate IO buffers through theTSIOBufferReader data structure. Since only a single writer is allowed, there is no corresponding TSIOBufferWriter data structure. The writer simply modifies the IO buffer directly.

New Protocol Plugins

The new protocol APIs enable you to extend Traffic Server to be a web proxy for any protocol. This chapter describes new protocol APIs and the plugins that support new protocols. It also provides a detailed review of code for a sample Protocol plugin that supports a very simple artificial HTTP-like protocol.

About the Sample Protocol

The sample protocol enables a client to ask a server for a file. Clients send requests to a specific Traffic Server port (specified in plugin.config); each request has the following structure:

server_name file_name

Using the Protocol plugin, Traffic Server can accept these requests, parse them, and act as a proxy cache (i.e., request the file from the origin server on the client’s behalf and store copies of response messages in cache). The Protocol plugin is a state machine that flows through the states illustrated in the Sample Protocol State Diagram. This figure illustrates the steps that Traffic Server and the Protocol plugin go through in order to support the sample protocol.

In more specific terms, Traffic Server and the Protocol plugin must:

  • Listen for and accept client connections (on the accept port specified in plugin.config)
  • Read incoming client requests
  • Look up the requested content in the Traffic Server cache
  • Serve content from cache if the request is a cache hit (this simple example does not do freshness checking)
  • Open a connection to the origin server if the request is a cache miss (on the server port specified in plugin.config)
  • Forward the request to the origin server
  • Receive the origin server response
  • Cache the response and send it on to the client

Sample Protocol State Diagram {#SampleProtocolStDiag}

Sample Protocol State Diagram

Sample Protocol State Diagram

Protocol Plugin Structure

To see how the Protocol plugin works, you need to understand some broader concepts. This section assumes you’re familiar with the concepts of continuation, Traffic Server’s asynchronous event model, and basic Traffic Server plugin structure. If you are not familiar with these concepts, then reference Getting Started and How to Create Traffic Server Plugins

Continuations in the Protocol Plugin

The Protocol plugin creates a static continuation that is an “accept” state machine - that is, a state machine whose job is to accept client connections on the appropriate port. When Traffic Server accepts a net connection from a client on that port, the accept state machine is activated. It then creates a new continuation: a transaction state machine. The accept state machine creates one transaction state machine for each transaction (where a transaction consists of a client request and Traffic Server’s response). Each transaction state machine lives until the transaction completes; then it is destroyed. If the client’s request for content is a cache miss, then a transaction state machine might need to open a connection to the origin server. This is illustrated in the Protocol Plugin Overview diagram below.

Protocol Plugin Overview

Protocol Plugin Overview

Protocol Plugin Overview

The first steps for writing the Protocol plugin are now clear: in TSPluginInit, you must create a continuation that listens for net connections on the client port specified in plugin.config (this continuation is the accept state machine).

Below is a summary of the continuations implemented for the Protocol plugin:

  • An accept state machine that listens for client connections, and then creates transaction state machines whenever Traffic Server accepts a new client connection. The accept state machine lives as long as Traffic Server is running.
  • Transaction state machines that read client requests, process them, and are then destroyed when the transaction is finished.
Event Flow

Implementing the rest of the Protocol plugin requires that you understand the flow of events during the course of a transaction. Unlike HTTP transaction plugins, this plugin must read data from network connections and then read/write data to the Traffic Server cache. This means that its continuations do not receive HTTP state machine events; they receive events from Traffic Server’s processor subsystems. For example: the accept state machine is activated by an TS_EVENT_NET_ACCEPT event from Traffic Server’s Net Processor; the handler function for the accept state machine must therefore be able to handle that event.

The transaction state machines are activated when the client connection receives incoming request data. The Net Processor notifies the transaction state machine of incoming data. The transaction state machine reads the data; when finished, it initiates a cache lookup of the requested file. When the cache lookup completes, the transaction state machine is activated by the Traffic Server Cache Processor.

If the transaction state machine needs to open a connection to the origin server to fetch content (in the case of a cache miss), then the transaction state machine initiates a DNS lookup of the server name. The transaction state machine is activated by a DNS lookup event from the Traffic Server Host Database Processor. If the transaction must connect to the origin server, then the transaction state machine initiates a net connection and waits for an event from the Net Processor.

Protocol Plugin Flow of Events

Protocol Plugin Flow of Events

Protocol Plugin Flow of Events

The flow of events is illustrated in the Protocol Plugin Flow of Events diagram above. The thin straight lines show Net Processor event flow, the thin dashed lines represent Host Database event flow, and the thick dashed lines show Cache event flow.

Notice that this flow of events is independent of the Protocol plugin’s design (i.e., whether you build accept or transaction state machines). Any plugin that supports network connections uses the net vconnection interfaces (TSNetAccept, TSNetConnect) and thus receives events from the Net Processor. Any plugin that performs cache lookups or cache writes uses TSCacheRead, TSCacheWrite, TSVConnRead, and TSVConnWrite and thus receives events from the Cache Processor and Traffic Server event system. Similarly, any plugin that does DNS lookups receives events from the Host Database Processor.

One Way to Implement a Transaction State Machine

Transaction state machines (TSMs) in the Protocol plugin must do the following:

  • Keep track of the state of the transaction
  • Handle events received (based on the state of the transaction and the event received)
  • Update the state of the transaction as it changes

Below is one way you can implement TSMs. Details about how the Protocol plugin does this are provided in the next section.

  • Create a data structure for transactions that contains all of the state data you need to keep track of. In the Protocol plugin this is a struct, Txn_SM.
  • When you create the TSM’s continuation, initialize data of type Txn_SM. Initialize the data to the initial state of a transaction (in this case, a net connection has just been accepted). Associate this data to the TSM continuation using TSContDataSet.
  • Write state handler functions that handle the expected events for each state.
  • Write the handler for the TSM. Its job is to receive events, examine the current state, and execute the appropriate state handler function. In the Protocol plugin, the handler is main_handler. main_handler calls the state handler functions to handle each state.

The steps below describe the flow of execution illustrated in “How Transaction State Machines are Implemented in the Protocol Plugin”.

  1. The handler for the TSM, (called ``main_handler`` in the Protocol plugin) receives events from the TSM.
  2. ``main_handler`` examines the state of the transaction-in particular, it examines the current handler.
  3. ``main_handler`` calls the ``current_handler`` (which is one of the state handler functions), and then passes the current event to ``current_handler``. In the image below below, the current handler is called ``state2_handler``.
  4. The ``current_handler`` handles the event and updates the data. In the image below below, the state is changed from ``state2`` to ``state3`` (and the current handler is changed from ``state2_handler`` to ``state3_handler``). The next time ``main_handler`` receives an event, it will be processed by ``state3_handler``.
  5. ``state2_handler`` arranges the next callback of the TSM. Typically, it gives Traffic Server additional work to do (such as writing a file to cache) so that it can progress to the next state. The TSM (``main_handler``) then waits for the next event to arrive from Traffic Server.

How Transaction State Machines are Implemented in the Protocol Plugin {#ImplementTransStMachine}

How Transaction State Machines are Implemented in the Protocol Plugin

How Transaction State Machines are Implemented in the Protocol Plugin

Processing a Typical Transaction

The code is contained in the following files:

  • Protocol.c and Protocol.h
  • Accept.c and Accept.h
  • TxnSM.c and TxnSM.h

Below is a step-by-step walk-through of the code that processes a typical transaction.

  1. The TSPluginInit function is in the Protocol.c file. It checks the validity of the plugin.config entries (there must be two: a client accept port and a server port) and runs an initialization routine, init.
  2. The ``init`` function (in Protocol.c) creates the plugin’s log file using ``TSTextLogObjectCreate``.
  3. The ``init`` function creates the accept state machine using ``AcceptCreate``. The code for ``AcceptCreate`` is in the Accept.c file.
  4. The accept state machine, like the transaction state machine, keeps track of its state with a data structure. This data structure, ``Accept``, is defined in the Accept.h file. State data in ``AcceptCreate`` is associated with the new accept state machine via ``TSContDataSet``.
  5. The ``init`` function arranges the callback of the accept state machine when there is a network connection by using ``TSNetAccept``.
  6. The handler for the accept state machine is ``accept_event`` in the Accept.c file. When Traffic Server’s Net Processor sends ``TS_EVENT_NET_ACCEPT`` to the accept state machine, ``accept_event`` creates a transaction state machine (``txn_sm``) by calling ``TxnSMCreate``. Notice that ``accept_event`` creates a mutex for the transaction state machine, since each transaction state machine has its own mutex.
  7. The ``TxnSMCreate`` function is in the TxnSM.c file. The first thing it does is initialize the transaction’s data, which is of type TxnSM (as defined in TxnSM.h). Notice that the current handler (``q_current_handler``) is set to ``state_start``.
  8. ``TxnSMCreate`` then creates a transaction state machine using ``TSContCreate``. The handler for the transaction state machine is ``main_handler``, which is in the TxnSM.c file.
  9. When ``accept_event`` receives ``TS_EVENT_NET_ACCEPT``, it calls the transaction state machine ( ``TSContCall (txn_sm, 0, NULL);`` ). The event passed to ``main_handler`` is 0 (``TS_EVENT_NONE``).
  10. The first thing ``main_handler`` does is examine the current ``txn_sm`` state by calling ``TSContDataGet``. The state is ``state_start``.
  11. ``main_handler`` then invokes the handler for ``state_start`` by using the function pointer ``TxnSMHandler`` (as defined in TxnSM.h).
  12. The ``state_start`` handler function (in the TxnSM.c file) is handed an event (at this stage, the event is ``TS_EVENT_NET_ACCEPT``) and a client vconnection. ``state_start`` checks to see if this client vconnection is closed; if it is not, then ``state_start`` attempts to read data from the client vconnection into an ``TSIOBuffer`` (``state_start`` is handling the event it receives).
  13. ``state_start`` changes the current handler to ``state_interface_with_client`` (that is, it updates the state of the transaction to the next state).
  14. ``state_start`` initiates a read of the client vconnection (arranges for Traffic Server to send ``TS_EVENT_VCONN_READ_READY`` events to the TSM) by calling ``TSVConnRead``.
  15. ``state_interface_with_client`` is activated by the next event from Traffic Server. It checks for errors and examines the read VIO for the read operation initiated by ``TSVConnRead``.
  16. If the read VIO is the ``client_read_VIO`` (which we are expecting at this stage in the transaction), then ``state_interface_with_client`` updates the state to ``state_read_request_from_client`` .
  17. ``state_read_request_from_client`` handles actual ``TS_EVENT_READ_READY`` events and reads the client request.
  18. ``state_read_request_from_client`` parses the client request.
  19. ``state_read_request_from_client`` updates the current state to the next state, ``state_handle_cache_lookup`` .
  20. ``state_read_request_from_client`` arranges for Traffic Server to call back the TSM with the next set of events (initiating the cache lookup) by calling ``TSCacheRead``.
  21. When the ``TSCacheRead`` sends the TSM either ``TS_EVENT_OPEN_READ`` (a cache hit) or ``TS_EVENT_OPEN_READ_FAILED`` (a cache miss), ``main_handler`` calls ``state_handle_cache_lookup``.
HTTP Hooks and Transactions

Hooks are points in Traffic Server transaction processing where plugins can step in and do some work. Registering a plugin function for callback amounts to “adding” the function to a hook. You can register your plugin to be called back for every single transaction or only for specific transactions.

This chapter contains the following sections:

Adding Hooks

There are several ways to add hooks to your plugin.

  • Global HTTP hooks HTTP transaction hooks are set on a global basis using the function TSHttpHookAdd. This means that the continuation specified as the parameter to TSHttpHookAdd is called for every transaction. TSHttpHookAdd must be used in TSPluginInit.
  • Transaction hooks Transaction hooks can be used to call plugins back for a specific HTTP transaction. You cannot add transaction hooks in TSPluginInit; you first need a handle to a transaction. See Accessing the Transaction Being Processed
  • Transformation hooks Transformation hooks are a special case of transaction hooks. See `TSVConnCacheObjectSizeGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#af5ca2c5b00e4859d2fa5dec466dfd058>`__ for more information about transformation hooks. You add a transformation hook using TSHttpTxnHookAdd, as described in HTTP Transactions.
  • Session hooks An HTTP session starts when a client opens a connection to Traffic Server and ends when the connection closes. A session can consist of several transactions. Session hooks enable you to hook your plugin to a particular point in every transaction within a specified session (see HTTP Sessions). Session hooks are added in a manner similar to transaction hooks (ie, you first need a handle to an HTTP session).
  • HTTP select alternate hook Alternate selection hooks enable you to hook on to the alternate selection state. These hooks must be added globally, since Traffic Server does not have a handle to a transaction or session when alternate selection is taking place. See HTTP Alternate Selection for information on the alternate selection mechanism.

All of the hook addition functions (`TSHttpHookAdd <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a19a663edd3ec439f66256fbbb26cc1db>`__, `TSHttpSsnHookAdd <HTTPSessionFunctions.html#TSHttpSsnHookAdd>`__, `TSHttpSsnReenable <HTTPSessionFunctions.html#TSHttpSsnReenable>`__) take TSHttpHookID (identifies the hook to add on to) and TSCont (the basic callback mechanism in Traffic Server). A single TSCont can be added to any number of hooks at a time.

An HTTP hook is identified by the enumerated type TSHttpHookID. The values for TSHttpHookID are:

Values for TSHttpHookID

TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK
Called after the HTTP state machine has completed the cache lookup for the document requested in the ongoing transaction. Register this hook via TSHttpTxnHookAdd or TSHttpHookAdd. Corresponds to the event TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE.
TS_HTTP_OS_DNS_HOOK
Called immediately after the HTTP state machine has completed a DNS lookup of the origin server. The HTTP state machine will know the origin server’s IP address at this point, which is useful for performing both authentication and blacklisting. Corresponds to the event TS_EVENT_HTTP_OS_DNS.
TS_HTTP_POST_REMAP_HOOK
Called immediately after remapping occurs, before cache lookup. Corresponds to the event TS_EVENT_HTTP_POST_REMAP.
TS_HTTP_PRE_REMAP_HOOK
Called after the request header is read from the client, before any remapping of the headers occurs. Corresponds to the event TS_EVENT_HTTP_PRE_REMAP.
TS_HTTP_READ_CACHE_HDR_HOOK
Called immediately after the request and response header of a previously-cached object is read from cache. This hook is only called if the document is being served from cache. Corresponds to the event TS_EVENT_HTTP_READ_CACHE_HDR.
TS_HTTP_READ_RESPONSE_HDR_HOOK
Called immediately after the response header is read from the origin server or parent proxy. Corresponds to the event TS_EVENT_HTTP_READ_RESPONSE_HDR.
TS_HTTP_RESPONSE_TRANSFORM_HOOK
See “`”Transformations” <../http-transformation-plugin#Transformations>`__ for information about transformation hooks.
TS_HTTP_READ_REQUEST_HDR_HOOK
Called immediately after the request header is read from the client. Corresponds to the event TS_EVENT_HTTP_READ_REQUEST_HDR.
TS_HTTP_REQUEST_TRANSFORM_HOOK
See “`”Transformations” <../http-transformation-plugin#Transformations>`__ for information about transformation hooks.
TS_HTTP_SELECT_ALT_HOOK
See “HTTP Alternate Selection” for information about the alternate selection mechanism.
TS_HTTP_SEND_RESPONSE_HDR_HOOK
Called immediately before the proxy’s response header is written to the client; this hook is usually used for modifying the response header. Corresponds to the event TS_EVENT_HTTP_SEND_RESPONSE_HDR.
TS_HTTP_SEND_REQUEST_HDR_HOOK
Called immediately before the proxy’s request header is sent to the origin server or the parent proxy. This hook is not called if the document is being served from cache. This hook is usually used for modifying the proxy’s request header before it is sent to the origin server or parent proxy.
TS_HTTP_SSN_CLOSE_HOOK
Called when an HTTP session ends. A session ends when the client connection is closed. You can only add this hook as a global hook
TS_HTTP_SSN_START_HOOK
Called when an HTTP session is started. A session starts when a client connects to Traffic Server. You can only add this hook as a global hook.
TS_HTTP_TXN_CLOSE_HOOK
Called when an HTTP transaction ends.
TS_HTTP_TXN_START_HOOK
Called when an HTTP transaction is started. A transaction starts when either a client connects to Traffic Server and data is available on the connection, or a previous client connection that was left open for keep alive has new data available.

The function you use to add a global HTTP hook is `TSHttpHookAdd <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a19a663edd3ec439f66256fbbb26cc1db>`__.

HTTP Sessions

An HTTP session is an object that is defined for the lifetime of a client’s TCP session. The Traffic Server API enables you to add a global hook to the start or end of an HTTP session, as well as add session hooks that call back your plugin for every transaction within a given session. When a client connects to Traffic Server, it opens up a TCP connection and sends one or more HTTP requests. An individual request and its response comprise the HTTP transaction. The HTTP session begins when the client opens the connection and ends when the connection closes.

The HTTP session hooks are:

  • TS_HTTP_SSN_START_HOOK Called when an HTTP session is started (a session starts when a client connects to Traffic Server). This hook must be added as a global hook.
  • TS_HTTP_SSN_CLOSE_HOOK Called when an HTTP session ends (a session ends when the client connection is closed). This hook must be added as a global hook.

Use the session hooks to get a handle to a session (an TSHttpSsn object). If you want your plugin to be called back for each transaction within the session, then use TSHttpSsnHookAdd.

Note: you must reenable the session with TSHttpSsnReenable after processing a session hook.

The session hook functions are listed below:

HTTP Transactions

The HTTP transaction functions enable you to set up plugin callbacks to HTTP transactions and obtain/modify information about particular HTTP transactions.

As described in the section on HTTP sessions, an HTTP transaction is an object defined for the lifetime of a single request from a client and the corresponding response from Traffic Server. The ``TSHttpTxn`` structure is the main handle given to a plugin for manipulating a transaction’s internal state. Additionally, an HTTP transaction has a reference back to the HTTP session that created it.

The sample code below illustrates how to register locally to a transaction and associate data to the transaction.

:::c
/*
* Simple plugin that illustrates:
* - how to register locally to a transaction
* - how to deal with data that's associated with a tranaction
*
* Note: for readability, error checking is omitted
*/

#include <ts/ts.h>

#define DBG_TAG "txn"

/* Structure to be associated to txns */
typedef struct {
   int i;
   float f;
   char *s;
} TxnData;

/* Allocate memory and init a TxnData structure */
TxnData *
txn_data_alloc()
{
   TxnData *data;
   data = TSmalloc(sizeof(TxnData));

   data->i = 1;
   data->f = 0.5;
   data->s = "Constant String";
   return data;
}

/* Free up a TxnData structure */
void
txn_data_free(TxnData *data)
{
   TSfree(data);
}

/* Handler for event READ_REQUEST and TXN_CLOSE */
static int
local_hook_handler (TSCont contp, TSEvent event, void *edata)
{
   TSHttpTxn txnp = (TSHttpTxn) edata;
   TxnData *txn_data = TSContDataGet(contp);
   switch (event) {
   case TS_EVENT_HTTP_READ_REQUEST_HDR:
      /* Modify values of txn data */
      txn_data->i = 2;
      txn_data->f = 3.5;
      txn_data->s = "Constant String 2";
      break;

   case TS_EVENT_HTTP_TXN_CLOSE:
      /* Print txn data values */
      TSDebug(DBG_TAG, "Txn data i=%d f=%f s=%s", txn_data->i, txn_data->f, txn_data->s);

      /* Then destroy the txn cont and its data */
      txn_data_free(txn_data);
      TSContDestroy(contp);
      break;

   default:
       TSAssert(!"Unexpected event");
       break;
   }

   TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
   return 1;
}

/* Handler for event TXN_START */
static int
global_hook_handler (TSCont contp, TSEvent event, void *edata)
{
   TSHttpTxn txnp = (TSHttpTxn) edata;
   TSCont txn_contp;
   TxnData *txn_data;

   switch (event) {
   case TS_EVENT_HTTP_TXN_START:
      /* Create a new continuation for this txn and associate data to it */
      txn_contp = TSContCreate(local_hook_handler, TSMutexCreate());
      txn_data = txn_data_alloc();
      TSContDataSet(txn_contp, txn_data);

      /* Registers locally to hook READ_REQUEST and TXN_CLOSE */
      TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, txn_contp);
      TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp);
      break;

   default:
      TSAssert(!"Unexpected event");
      break;
   }

   TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
   return 1;
}


void
TSPluginInit (int argc, const char *argv[])
{
   TSCont contp;

   /* Note that we do not need a mutex for this txn since it registers globally
      and doesn't have any data associated with it */
   contp = TSContCreate(global_hook_handler, NULL);

   /* Register gloabally */
   TSHttpHookAdd(TS_HTTP_TXN_START_HOOK, contp);
}

See Adding Hooks for background about HTTP transactions and HTTP hooks, as well as HTTP Hooks and Transactions Also see the [HTTP Transaction State Diagram ](HTTPHooksAndTransactions.html(../http-hooks-and-transactions#HHTTPTxStateDiag) for an illustration of the steps involved in a typical HTTP transaction.

The HTTP transaction functions are:

Intercepting HTTP Transactions

The intercepting HTTP transaction functions enable plugins to intercept transactions either after the request is received or upon contact with the origin server. The plugin then acts as the origin server using the TSVConn interface. The intercepting HTTP transaction function allow for reading POST bodies in plugins as well as using alternative transports to the origin server.The intercepting HTTP transaction functions are:

Initiate HTTP Connection

This function enables plugins to initiate HTTP transactions. The initiate HTTP connection function is:

HTTP Alternate Selection

The HTTP alternate selection functions provide a mechanism for hooking into Traffic Server’s alternate selection mechanism and augmenting it with additional information. HTTP alternate selection refers to the process of choosing between several alternate versions of a document for a specific URL. Alternates arise because the HTTP 1.1 specification allows different documents to be sent back for the same URL (depending on the clients request). For example, a server might send back a GIF image to a client that only accepts GIF images, and might send back a JPEG image to a client that only accepts JPEG images.

The alternate selection mechanism is invoked when Traffic Server looks up a URL in its cache. For each URL, Traffic Server stores a vector of alternates. For each alternate in this vector, Traffic Server computes a quality value between 0 and 1 that represents how “good” the alternate is. A quality value of 0 means that the alternate is unacceptable; a value of 1 means that the alternate is a perfect match.

If a plugin hooks onto the TS_HTTP_SELECT_ALT_HOOK, then it will be called back when Traffic Server performs alternate selection. You cannot register locally to the hook TS_HTTP_SELECT_ALT_HOOK by using TSHttpTxnHookAdd - you can only do so by using only TSHttpHookAdd. Since Traffic Server does not actually have an HTTP transaction or an HTTP session on hand when alternate selection is performed, it is only valid to hook onto the global list of TS_HTTP_SELECT_ALT_HOOK. Traffic Server calls each of the select alternate hooks with the TS_EVENT_HTTP_SELECT_ALT event. The void *edata argument that is passed to the continuation is a pointer to an TSHttpAltInfo structure. It can be used later to call the HTTP alternate selection functions listed at the end of this section. Unlike other hooks, this alternate selection callout is non-blocking; the expectation is that the quality value for the alternate will be changed by a call to TSHttpAltInfoQualitySet.

注解

HTTP SM does not have to be reenabled using TSHttpTxnReenable or any other APIs; just return from the function.

The sample code below shows how to call the alternate APIs.

static void handle_select_alt(TSHttpAltInfo infop)
{
   TSMBuffer client_req_buf, cache_resp_buf;
   TSMLoc client_req_hdr, cache_resp_hdr;

   TSMLoc accept_transform_field;
   TSMLoc content_transform_field;

   int accept_transform_len = -1, content_transform_len = -1;
   const char* accept_transform_value = NULL;
   const char* content_transform_value = NULL;
   int content_plugin, accept_plugin;

   float quality;

   /* get client request, cached request and cached response */
   TSHttpAltInfoClientReqGet (infop, &client_req_buf, &client_req_hdr);
   TSHttpAltInfoCachedRespGet(infop, &cache_resp_buf, &cache_resp_hdr);

   /* get the Accept-Transform field value from the client request */
   accept_transform_field = TSMimeHdrFieldFind(client_req_buf,
      client_req_hdr, "Accept-Transform", -1);
   if (accept_transform_field) {
      TSMimeHdrFieldValueStringGet(client_req_buf, client_req_hdr,
         accept_transform_field, 0, &accept_transform_value, &accept_transform_len);
      TSDebug(DBG_TAG, "Accept-Transform = |%s|",
         accept_transform_value);
   }

   /* get the Content-Transform field value from cached server response */
   content_transform_field = TSMimeHdrFieldFind(cache_resp_buf,
      cache_resp_hdr, "Content-Transform", -1);
   if (content_transform_field) {
      TSMimeHdrFieldValueStringGet(cache_resp_buf, cache_resp_hdr,
         content_transform_field, 0, &content_transform_value, &content_transform_len);
      TSDebug(DBG_TAG, "Content-Transform = |%s|",
         content_transform_value);
   }

   /* compute quality */
   accept_plugin = (accept_transform_value && (accept_transform_len > 0) &&
      (strncmp(accept_transform_value, "plugin",
         accept_transform_len) == 0));

   content_plugin = (content_transform_value && (content_transform_len >0) &&
      (strncmp(content_transform_value, "plugin",
         content_transform_len) == 0));

   if (accept_plugin) {
      quality = content_plugin ? 1.0 : 0.0;
   } else {
      quality = content_plugin ? 0.0 : 0.5;
   }

   TSDebug(DBG_TAG, "Setting quality to %3.1f", quality);

   /* set quality for this alternate */
   TSHttpAltInfoQualitySet(infop, quality);

   /* cleanup */
   if (accept_transform_field)
      TSHandleMLocRelease(client_req_buf, client_req_hdr,
         accept_transform_field);
   TSHandleMLocRelease(client_req_buf, TS_NULL_MLOC, client_req_hdr);

   if (content_transform_field)
      TSHandleMLocRelease(cache_resp_buf, cache_resp_hdr,
         content_transform_field);
   TSHandleMLocRelease(cache_resp_buf, TS_NULL_MLOC, cache_resp_hdr);
}

static int alt_plugin(TSCont contp, TSEvent event, void *edata)
{
   TSHttpAltInfo infop;

   switch (event) {
      case TS_EVENT_HTTP_SELECT_ALT:
         infop = (TSHttpAltInfo)edata;
         handle_select_alt(infop);
         break;

      default:
         break;
   }

   return 0;
}

void TSPluginInit (int argc, const char *argv[])
{
   TSHttpHookAdd(TS_HTTP_SELECT_ALT_HOOK, TSContCreate (alt_plugin,
      NULL));
}

Traffic Server augments the alternate selection through these callouts using the following algorithm:

  1. Traffic Server computes its own quality value for the alternate, taking into account the quality of the accept match, the encoding match, and the language match.
  2. Traffic Server then calls out each of the continuations on the global TS_HTTP_SELECT_ALT_HOOK‘s list.
  3. It multiplies its quality value with the value returned by each callout. Since all of the values are clamped to be between 0 and 1, the final value will be between 0 and 1 as well.
  4. This algorithm also ensures that a single callout can block the usage of a given alternate by specifying a quality value of 0.

A common usage for the alternate selection mechanism is when a plugin transforms a document for some clients and not for others, but wants to store both the transformed and unchanged document. The client’s request will specify whether it accepted the transformed document. The plugin will then determine if the alternate matches this specification and then set the appropriate quality level for the alternate.

The HTTP alternate selection functions are:

The Set of Hooks

To understand hooks and transactions, you should be familiar with the following terminology:

HTTP Transaction

A transaction consists of a single HTTP request from a client and the response Traffic Server sends to that client. Thus, a transaction begins when Traffic Server receives a request and ends when Traffic Server sends the response.

Traffic Server uses HTTP state machines to process transactions. The state machines follow a complex set of states involved in sophisticated caching and document retrieval (taking into account, for example, alternate selection, freshness criteria, and hierarchical caching). The Traffic Server API provides hooks to a subset of these states, as illustrated in the HTTP Transaction State Diagram below.

Transform hooks

The two transform hooks, TS_HTTP_REQUEST_TRANSFORM_HOOK and TS_HTTP_RESPONSE_TRANSFORM_HOOK, are called in the course of an HTTP transform. To see where in the HTTP transaction they are called, look for the “set up transform” ovals in the HTTP Transaction State Diagram below.

HTTP session

A session consists of a single client connection to Traffic Server; it may consist of a single transaction or several transactions in succession. The session starts when the client connection opens and ends when the connection closes.

HTTP Transaction State Diagram

HTTP Transaction State Diagram

Miscellaneous Interface Guide

Most of the functions in the Traffic Server API provide an interface to specific code modules within Traffic Server. The miscellaneous functions described in this chapter provide some useful general capabilities. They are categorized as follows:

The TSfopen Family

The fopen family of functions in C is normally used for reading configuration files, since fgets is an easy way to parse files on a line-by-line basis. The TSfopen family of functions aims at solving the same problem of buffered IO and line at a time IO in a platform-independent manner. The fopen family of C library functions can only open a file if a file descriptor less than 256 is available. Since Traffic Server often has more than 2000 file descriptors open at once, however, the likelihood of an available file descriptor less than 256 very small. To solve this problem, the TSfopen family can open files with descriptors greater than 256.

The TSfopen family of routines is not intended for high speed IO or flexibility - they are blocking APIs (not asynchronous). For performance reasons, you should not directly use these APIs on a Traffic Server thread (when being called back on an HTTP hook); it is better to use a separate thread for doing the blocking IO. The TSfopen family is intended for reading and writing configuration information when corresponding usage of the fopen family of functions is inappropriate due to file descriptor and portability limitations. The TSfopen family of functions consists of the following:

Memory Allocation

Traffic Server provides five routines for allocating and freeing memory. These routines correspond to similar routines in the C library. For example, TSrealloc behaves like the C library routine realloc.

There are two main reasons for using the routines provided by Traffic Server. The first is portability: the Traffic Server API routines behave the same on all of Traffic Server’s supported platforms. For example, realloc does not accept an argument of NULL on some platforms. The second reason is that the Traffic Server routines actually track the memory allocations by file and line number. This tracking is very efficient, always turned on, and quite useful when tracking down memory leaks.

The memory allocation functions are:

Thread Functions

The Traffic Server API thread functions enable you to create, destroy, and identify threads within Traffic Server. Multithreading enables a single program to have more than one stream of execution and to process more than one transaction at a time. Threads serialize their access to shared resources and data using the TSMutex type, as described in Mutexes.

The thread functions are listed below:

The C library already provides functions such as printf, malloc, and fopen to perform these tasks. The Traffic Server API versions, however, overcome various C library limitations (such as portability to all Traffic Server-support platforms).

Debugging Functions
HTTP Headers

This chapter explains the functions used to manipulate HTTP headers.

Guide to Traffic Server HTTP Header System

No Null-Terminated Strings

It’s not safe to assume that string data contained in marshal buffers (such as URLs and MIME fields) is stored in null-terminated string copies. Therefore, your plugins should always use the length parameter when retrieving or manipulating these strings. You cannot pass in NULL for string-length return values; string values returned from marshall buffers are not null-terminated. If you need a null-terminated value, then use TSstrndup to automatically null-terminate a string. The strings that come back and are not null-terminated cannot be passed into the common str*() routines

注解

Values returned from a marshall buffer can be NULL, which means the field or object requested does not exist.

For example (from the blacklist-1 sample)

char *host_string;
int host_length;
host_string = TSUrlHostGet (bufp, url_loc, &host_length);
for (i = 0; i < nsites; i++) {
if (strncmp (host_string, sites[i], host_length) == 0) {
   // ...
}

See the sample plugins for additional examples.

Duplicate MIME Fields Are Not Coalesced

MIME headers can contain more than one MIME field with the same name. Earlier versions of Traffic Server joined multiple fields with the same name into one field with composite values. This behavior came at a performance cost and caused interoperability problems with older clients and servers. Therefore, this version of Traffic Server does not coalesce duplicate fields.

Properly-behaving plugins should check for the presence of duplicate fields and then iterate over the duplicate fields via :ref:TSMimeHdrFieldNextDup <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#af2d776615afe959ed7c3639830a7061f>.

MIME Fields Always Belong to an Associated MIME Header

When using Traffic Server, you cannot create a new MIME field without an associated MIME header or HTTP header; MIME fields are always seen as part of a MIME header or HTTP header.

To use a MIME field, you must specify the MIME header or HTTP header to which it belongs - this is called the field’s parent header. The TSMimeField* functions in older versions of the SDK have been deprecated, as they do not require the parent header as inputs. The current version of Traffic Server uses new functions, the ``TSMimeHdrField`` series, which require you to specify the location of the parent header along with the location of the MIME field. For every deprecated ``TSMimeField`` function, there is a new, preferred TSMimeHdrField* function. Therefore, you should use the ``TSMimeHdrField`` functions instead of the deprecated ``TSMimeField`` series. Examples are provided below.

Instead of:

    :::c
TSMLoc TSMimeFieldCreate (TSMBuffer bufp)

You should use:

    :::c
TSMLoc TSMimeHdrFieldCreate (TSMBuffer bufp, TSMLoc hdr)

Instead of:

    :::c
void TSMimeFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_offset,
   TSMBuffer src_bufp, TSMLoc src_offset)

You should use:

    :::c
void TSMimeHdrFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_hdr,
   TSMLoc dest_field, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc
   src_field)

In the TSMimeHdrField* function prototypes, the TSMLoc field corresponds to the TSMLoc offset used the deprecated TSMimeField* functions (see the discussion of parent TSMLoc in the following section).

Release Marshal Buffer Handles

When you fetch a component object or create a new object, you get back a handle to the object location. The handle is either an TSMLoc for an object location or char * for a string location. You can manipulate the object through these handles, but when you are finished you need to release the handle to free up system resources.

The general guideline is to release all TSMLoc and string handles you retrieve. The one exception is the string returned by TSUrlStringGet, which must be freed by a call to TSfree.

The handle release functions expect three arguments: the marshal buffer containing the data, the location of the parent object, and the location of the object to be released. The parent location is usually clear from the creation of the TSMLoc or string. For example, if your plugin had the following calls:

url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
host_string = TSUrlHostGet (bufp, url_loc, &host_length);

then your plugin would have to call:

TSHandleMLocRelease (bufp, hdr_loc, url_loc);

If an TSMLoc is obtained from a transaction, then it does not have a parent TSMLoc. Use the null TSMLoc constant TS_NULL_MLOC as its parent. For example, if your plugin calls:

TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc);

then you must release hdr_loc with:

TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);

You need to use TS_NULL_MLOC to release any TSMLoc handles retrieved by the TSHttpTxn*Get functions.

Here’s an example using a new TSMimeHdrField function:

TSHttpTxnServerRespGet( txnp, &resp_bufp, &resp_hdr_loc );
new_field_loc = TSMimeHdrFieldCreate (resp_bufp, resp_hdr_loc);
TSHandleMLocRelease ( resp_bufp, resp_hdr_loc, new_field_loc);
TSHandleMLocRelease ( resp_bufp, TS_NULL_MLOC, resp_hdr_loc);

See the sample plugins for many more examples.

小技巧

You should release handles before reenabling the HTTP transaction. In other words, call TSHandleMLocRelease before TSHttpTxnReenable.

Marshal Buffers

A marshal buffer, or TSMBuffer, is a heap data structure that stores parsed URLs, MIME headers, and HTTP headers. You can allocate new objects out of marshal buffers and change the values within a marshal buffer. Whenever you manipulate an object, you require the handle to the object (TSMLoc) and the marshal buffer containing the object (TSMBuffer).

Routines exist for manipulating the object based on these two pieces of information. For example, see one of the following:

The marshal buffer functions enable you to create and destroy Traffic Server’s marshal buffers, which are the data structures that hold parsed URLs, MIME headers, and HTTP headers.

警告

Any marshal buffer fetched by TSHttpTxn*Get will be used by other parts of the system. Be careful not to destroy these shared transaction marshal buffers in functions such as those below:

HTTP Headers
Marshal Buffers

A marshal buffer, or TSMBuffer, is a heap data structure that stores parsed URLs, MIME headers, and HTTP headers. You can allocate new objects out of marshal buffers and change the values within a marshal buffer. Whenever you manipulate an object, you require the handle to the object (TSMLoc) and the marshal buffer containing the object (TSMBuffer).

Routines exist for manipulating the object based on these two pieces of information. For example, see one of the following:

The marshal buffer functions enable you to create and destroy Traffic Server’s marshal buffers, which are the data structures that hold parsed URLs, MIME headers, and HTTP headers.

警告

Any marshal buffer fetched by TSHttpTxn*Get will be used by other parts of the system. Be careful not to destroy these shared transaction marshal buffers in functions such as those below:

MIME Headers

The Traffic Server **MIME header functions ** enable you to retrieve and modify information about HTTP MIME fields.

An HTTP request or response consists of a header, body, and trailer. The HTTP header contains a request (or response) line and a MIME header. A MIME header is composed of zero or more MIME fields. A MIME field is composed of a field name, a colon, and zero or more field values (values in a field are separated by commas).

In the example below: Foo is the MIME field name, bar is the first MIME field value, and car is the second MIME field value.

:::text
Foo: bar, car

The following example is an augmented Backus-Naur Form (BNF) for the form of a MIME header - it specifies exactly what was described above. A header consists of zero or more fields that contain a name, separating colon, and zero or more values. A name or value is simply a string of tokens that is potentially zero length; a token is any character except certain control characters and separators (such as colons). For the purpose of retrieving a field, field names are not case-sensitive; therefore, the field names Foo, foo and fOO are all equivalent.

    :::text
MIME-header = *MIME-field
MIME-field = field-name ":" #field-value
field-name = *token
field-value = *token

The MIME header data structure is a parsed version of a standard Internet MIME header. The MIME header data structure is similar to the URL data structure (see URLs). The actual data is stored in a marshal buffer; the MIME header functions operate on a marshal buffer and a location (TSMLoc) within the buffer.

After a call to TSMimeHdrFieldDestroy, TSMimeHdrFieldRemove, or TSUrlDestroy is made, you must deallocate the TSMLoc handle with a call to TSHandleMLocRelease. You do not need to deallocate a NULL handles. For example: if you call TSMimeHdrFieldValueStringGet to get the value of the content type field and the field does not exist, then it returns TS_NULL_MLOC. In such a case, you wouldn’t need to deallocate the handle with a call to TSHandleMLocRelease.

The location (TSMLoc) in the MIME header functions can be either an HTTP header location or a MIME header location. If an HTTP header location is passed to these functions, then the system locates the MIME header associated with that HTTP header and executes the corresponding MIME header operations specified by the functions (see the example in the description of `TSMimeHdrCopy <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a6e0a392b2e072db8e7f1d795151203b4>`__).

Note: MIME headers may contain more than one MIME field with the same name. Previous versions of Traffic Server joined multiple fields with the same name into one field with composite values, but this behavior came at a performance cost and caused compatability issues with older clients and servers. Hence, the current version of Traffic Server does not coalesce duplicate fields. Correctly-behaving plugins should check for the presence of duplicate fields and iterate over the duplicate fields by using TSMimeHdrFieldNextDup.

To facilitate fast comparisons and reduce storage size, Traffic Server defines several pre-allocated field names. These field names correspond to the field names in HTTP and NNTP headers.

TS_MIME_FIELD_ACCEPT
“Accept” TS_MIME_LEN_ACCEPT
TS_MIME_FIELD_ACCEPT_CHARSET
“Accept-Charset” TS_MIME_LEN_ACCEPT_CHARSET
TS_MIME_FIELD_ACCEPT_ENCODING
“Accept-Encoding” TS_MIME_LEN_ACCEPT_ENCODING
TS_MIME_FIELD_ACCEPT_LANGUAGE
“Accept-Language” TS_MIME_LEN_ACCEPT_LANGUAGE
TS_MIME_FIELD_ACCEPT_RANGES
“Accept-Ranges” TS_MIME_LEN_ACCEPT_RANGES
TS_MIME_FIELD_AGE
“Age” TS_MIME_LEN_AGE
TS_MIME_FIELD_ALLOW
“Allow” TS_MIME_LEN_ALLOW
TS_MIME_FIELD_APPROVED
“Approved” TS_MIME_LEN_APPROVED
TS_MIME_FIELD_AUTHORIZATION
“Authorization” TS_MIME_LEN_AUTHORIZATION
TS_MIME_FIELD_BYTES
“Bytes” TS_MIME_LEN_BYTES
TS_MIME_FIELD_CACHE_CONTROL
“Cache-Control” TS_MIME_LEN_CACHE_CONTROL
TS_MIME_FIELD_CLIENT_IP
“Client-ip” TS_MIME_LEN_CLIENT_IP
TS_MIME_FIELD_CONNECTION
“Connection” TS_MIME_LEN_CONNECTION
TS_MIME_FIELD_CONTENT_BASE
“Content-Base” TS_MIME_LEN_CONTENT_BASE
TS_MIME_FIELD_CONTENT_ENCODING
“Content-Encoding” TS_MIME_LEN_CONTENT_ENCODING
TS_MIME_FIELD_CONTENT_LANGUAGE
“Content-Language” TS_MIME_LEN_CONTENT_LANGUAGE
TS_MIME_FIELD_CONTENT_LENGTH
“Content-Length” TS_MIME_LEN_CONTENT_LENGTH
TS_MIME_FIELD_CONTENT_LOCATION
“Content-Location” TS_MIME_LEN_CONTENT_LOCATION
TS_MIME_FIELD_CONTENT_MD5
“Content-MD5” TS_MIME_LEN_CONTENT_MD5
TS_MIME_FIELD_CONTENT_RANGE
“Content-Range” TS_MIME_LEN_CONTENT_RANGE
TS_MIME_FIELD_CONTENT_TYPE
“Content-Type” TS_MIME_LEN_CONTENT_TYPE
TS_MIME_FIELD_CONTROL
“Control” TS_MIME_LEN_CONTROL
TS_MIME_FIELD_COOKIE
“Cookie” TS_MIME_LEN_COOKIE
TS_MIME_FIELD_DATE
“Date” TS_MIME_LEN_DATE
TS_MIME_FIELD_DISTRIBUTION
“Distribution” TS_MIME_LEN_DISTRIBUTION
TS_MIME_FIELD_ETAG
“Etag” TS_MIME_LEN_ETAG
TS_MIME_FIELD_EXPECT
“Expect” TS_MIME_LEN_EXPECT
TS_MIME_FIELD_EXPIRES
“Expires” TS_MIME_LEN_EXPIRES
TS_MIME_FIELD_FOLLOWUP_TO
“Followup-To” TS_MIME_LEN_FOLLOWUP_TO
TS_MIME_FIELD_FROM
“From” TS_MIME_LEN_FROM
TS_MIME_FIELD_HOST
“Host” TS_MIME_LEN_HOST
TS_MIME_FIELD_IF_MATCH
“If-Match” TS_MIME_LEN_IF_MATCH
TS_MIME_FIELD_IF_MODIFIED_SINCE
“If-Modified-Since” TS_MIME_LEN_IF_MODIFIED_SINCE
TS_MIME_FIELD_IF_NONE_MATCH
“If-None-Match” TS_MIME_LEN_IF_NONE_MATCH
TS_MIME_FIELD_IF_RANGE
“If-Range” TS_MIME_LEN_IF_RANGE
TS_MIME_FIELD_IF_UNMODIFIED_SINCE
“If-Unmodified-Since” TS_MIME_LEN_IF_UNMODIFIED_SINCE
TS_MIME_FIELD_KEEP_ALIVE
“Keep-Alive” TS_MIME_LEN_KEEP_ALIVE
TS_MIME_FIELD_KEYWORDS
“Keywords” TS_MIME_LEN_KEYWORDS
TS_MIME_FIELD_LAST_MODIFIED
“Last-Modified” TS_MIME_LEN_LAST_MODIFIED
TS_MIME_FIELD_LINES
“Lines” TS_MIME_LEN_LINES
TS_MIME_FIELD_LOCATION
“Location” TS_MIME_LEN_LOCATION
TS_MIME_FIELD_MAX_FORWARDS
“Max-Forwards” TS_MIME_LEN_MAX_FORWARDS
TS_MIME_FIELD_MESSAGE_ID
“Message-ID” TS_MIME_LEN_MESSAGE_ID
TS_MIME_FIELD_NEWSGROUPS
“Newsgroups” TS_MIME_LEN_NEWSGROUPS
TS_MIME_FIELD_ORGANIZATION
“Organization” TS_MIME_LEN_ORGANIZATION
TS_MIME_FIELD_PATH
“Path” TS_MIME_LEN_PATH
TS_MIME_FIELD_PRAGMA
“Pragma” TS_MIME_LEN_PRAGMA
TS_MIME_FIELD_PROXY_AUTHENTICATE
“Proxy-Authenticate” TS_MIME_LEN_PROXY_AUTHENTICATE
TS_MIME_FIELD_PROXY_AUTHORIZATION
“Proxy-Authorization” TS_MIME_LEN_PROXY_AUTHORIZATION
TS_MIME_FIELD_PROXY_CONNECTION
“Proxy-Connection” TS_MIME_LEN_PROXY_CONNECTION
TS_MIME_FIELD_PUBLIC
“Public” TS_MIME_LEN_PUBLIC
TS_MIME_FIELD_RANGE
“Range” TS_MIME_LEN_RANGE
TS_MIME_FIELD_REFERENCES
“References” TS_MIME_LEN_REFERENCES
TS_MIME_FIELD_REFERER
“Referer” TS_MIME_LEN_REFERER
TS_MIME_FIELD_REPLY_TO
“Reply-To” TS_MIME_LEN_REPLY_TO
TS_MIME_FIELD_RETRY_AFTER
“Retry-After” TS_MIME_LEN_RETRY_AFTER
TS_MIME_FIELD_SENDER
“Sender” TS_MIME_LEN_SENDER
TS_MIME_FIELD_SERVER
“Server” TS_MIME_LEN_SERVER
TS_MIME_FIELD_SET_COOKIE
“Set-Cookie” TS_MIME_LEN_SET_COOKIE
TS_MIME_FIELD_SUBJECT
“Subject” TS_MIME_LEN_SUBJECTTS_MIME_LEN_SUBJECT
TS_MIME_FIELD_SUMMARY
“Summary” TS_MIME_LEN_SUMMARY
TS_MIME_FIELD_TE
“TE” TS_MIME_LEN_TE
TS_MIME_FIELD_TRANSFER_ENCODING
“Transfer-Encoding” TS_MIME_LEN_TRANSFER_ENCODING
TS_MIME_FIELD_UPGRADE
“Upgrade” TS_MIME_LEN_UPGRADE
TS_MIME_FIELD_USER_AGENT
“User-Agent” TS_MIME_LEN_USER_AGENT
TS_MIME_FIELD_VARY
“Vary” TS_MIME_LEN_VARY
TS_MIME_FIELD_VIA
“Via” TS_MIME_LEN_VIA
TS_MIME_FIELD_WARNING
“Warning” TS_MIME_LEN_WARNING
TS_MIME_FIELD_WWW_AUTHENTICATE
“Www-Authenticate” TS_MIME_LEN_WWW_AUTHENTICATE
TS_MIME_FIELD_XREF
“Xref” TS_MIME_LEN_XREF

The header field names above are defined in ts.h as const char* strings. When Traffic Server sets the name portion of a header field (or any portion for that matter), it quickly checks to see if the new value is one of the known values. If it is, then Traffic Server stores a pointer into a global table instead of storing the known value in the marshal buffer. The header field names listed above are also pointers into this table, which enables simple pointer comparison of the value returned from TSMimeHdrFieldNameGet with one of the values listed above. It is recommended that you use the above values when referring to one of the known header field names to avoid the possibility of a spelling error.

Traffic Server adds one important feature to MIME fields that you may not know about: Traffic Server does not print a MIME field if the field name begins with the ‘@‘ symbol. For example: a plugin can add the field “@My-Field” to a header. Even though Traffic Server never sends that field out in a request to an origin server or in a response to a client, it can be printed to Traffic Server logs by defining a custom log configuration file that explicitly logs such fields. This provides a useful mechanism for plugins to store information about an object in one of the MIME headers associated with the object.

The MIME header functions are listed below:

URLs

API URL functions provide access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs; they can also retrieve or modify parts of URLs, such as port or scheme information.

The general form of an Internet URL is:

:::text
scheme://user:password@host:port/stuff

The URL data structure includes support for two specific types of internet URLs. HTTP URLs have the form:

:::text
http://user:password@host:port/path;params?query#fragment

The URL port is stored as integer. All remaining parts of the URL (scheme, user, etc.) are stored as strings. Traffic Server URL functions are named according to the portion of the URL on which they operate. For instance, the function that retrieves the host portion of a URL is named TSUrlHostGet.

To facilitate fast comparisons and reduce storage size, Traffic Server defines several preallocated scheme names.

TS_URL_SCHEME_FILE
“file” TS_URL_LEN_FILE
TS_URL_SCHEME_FTP
“ftp” TS_URL_LEN_FTP
TS_URL_SCHEME_GOPHER
“gopher” TS_URL_LEN_GOPHER
TS_URL_SCHEME_HTTP
“http” TS_URL_LEN_HTTP
TS_URL_SCHEME_HTTPS
“https” TS_URL_LEN_HTTPS
TS_URL_SCHEME_MAILTO
“mailto” TS_URL_LEN_MAILTO
TS_URL_SCHEME_NEWS
“news” TS_URL_LEN_NEWS
TS_URL_SCHEME_NNTP
“nntp” TS_URL_LEN_NNTP
TS_URL_SCHEME_PROSPERO
“prospero” TS_URL_LEN_PROSPERO
TS_URL_SCHEME_TELNET
“telnet” TS_URL_LEN_TELNET
TS_URL_SCHEME_WAIS
“wais” TS_URL_LEN_WAIS

The scheme names above are defined in ts.h as const char* strings. When Traffic Server sets the scheme portion of the URL (or any portion for that matter), it quickly checks to see if the new value is one of the known values. If it is, then it stores a pointer into a global table (instead of storing the known value in the marshal buffer). The scheme values listed above are also pointers into this table. This allows simple pointer comparison of the value returned from TSUrlSchemeGet with one of the values listed above. You should use the Traffic Server-defined values when referring to one of the known schemes, since doing so can prevent the possibility of spelling errors.

Traffic Server URL functions are listed below:

`TSUrlClone <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#acb775f48f1da5f6c5bf32c833a236574>`__ `TSUrlCopy <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#aa2b8d5f9289a23ab985210914a6301a7>`__ `TSUrlCreate <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#ad3518ea3bca6a6f2d899b859c6fbbede>`__ `TSUrlDestroy <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a87559aac42f4f9439399ba2bd32693fa>`__ `TSUrlPrint <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#adec26f5a4afe62b4308dd86f97ae08fd>`__ `TSUrlFtpTypeGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a5cd15d2c288a48b832f0fc096ed6fb80>`__ `TSUrlFtpTypeSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a66df700e23085cabf945e92eb1e22890>`__ `TSUrlHostGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a48e626d9497d4d81c0b9d2781f86066b>`__ `TSUrlHostSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a7e550dac573f5780f7ba39509aa881f3>`__ `TSUrlHttpFragmentGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a316696ad964cb6c6afb7e3028da3ef84>`__ `TSUrlHttpFragmentSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a45f7b216882c4517b92929145adf5424>`__ `TSUrlHttpParamsGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a9395d5d794078c8ec0f17f27dc8d8498>`__ `TSUrlHttpParamsSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a566f2996d36663e3eb8ed4a8fda738c3>`__ `TSUrlHttpQueryGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a74a6c51ea9f472cf29514facbf897785>`__ `TSUrlHttpQuerySet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a9846aaf11accd8c817fff48bfaa784e0>`__ `TSUrlLengthGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a96ded2567985b187c0a8274d76d12c17>`__ `TSUrlParse <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a17f785697773b62b1f5094c06896cac5>`__ `TSUrlPasswordGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a14614f77e0c15b206bab8fd6fdfa7bd1>`__ `TSUrlPasswordSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#abb4d983b9d47ba5a254c2b9dd9ad835e>`__ `TSUrlPathGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#aa064a2d5256d839819d1ec8f252c01a9>`__ `TSUrlPathSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#ad73274cb5b7e98a64d53f992681110b7>`__ `TSUrlPortGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#ad99bfb408a46f47c4aa9478fc1b95e0c>`__ `TSUrlPortSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#aab07c0482fc3c3aae1b545fb0104e3aa>`__ `TSUrlSchemeGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a24c660b5b46f17b24d7a1cc9aa9a4930>`__ `TSUrlSchemeSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a03b1a806ea8d79806dfff39bfe138934>`__ `TSUrlStringGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a1cda3103d8dd59372609aed6c9c47417>`__ `TSUrlUserGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a3c4d7ffcbbda447c3b665dc857a3226b>`__ `TSUrlUserSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a3175e9c89c2bbea5ed50e2a7f52d7f9f>`__

Guide to Traffic Server HTTP Header System

No Null-Terminated Strings

It’s not safe to assume that string data contained in marshal buffers (such as URLs and MIME fields) is stored in null-terminated string copies. Therefore, your plugins should always use the length parameter when retrieving or manipulating these strings. You cannot pass in NULL for string-length return values; string values returned from marshall buffers are not null-terminated. If you need a null-terminated value, then use TSstrndup to automatically null-terminate a string. The strings that come back and are not null-terminated cannot be passed into the common str*() routines

注解

Values returned from a marshall buffer can be NULL, which means the field or object requested does not exist.

For example (from the blacklist-1 sample)

char *host_string;
int host_length;
host_string = TSUrlHostGet (bufp, url_loc, &host_length);
for (i = 0; i < nsites; i++) {
if (strncmp (host_string, sites[i], host_length) == 0) {
   // ...
}

See the sample plugins for additional examples.

Duplicate MIME Fields Are Not Coalesced

MIME headers can contain more than one MIME field with the same name. Earlier versions of Traffic Server joined multiple fields with the same name into one field with composite values. This behavior came at a performance cost and caused interoperability problems with older clients and servers. Therefore, this version of Traffic Server does not coalesce duplicate fields.

Properly-behaving plugins should check for the presence of duplicate fields and then iterate over the duplicate fields via :ref:TSMimeHdrFieldNextDup <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#af2d776615afe959ed7c3639830a7061f>.

MIME Fields Always Belong to an Associated MIME Header

When using Traffic Server, you cannot create a new MIME field without an associated MIME header or HTTP header; MIME fields are always seen as part of a MIME header or HTTP header.

To use a MIME field, you must specify the MIME header or HTTP header to which it belongs - this is called the field’s parent header. The TSMimeField* functions in older versions of the SDK have been deprecated, as they do not require the parent header as inputs. The current version of Traffic Server uses new functions, the ``TSMimeHdrField`` series, which require you to specify the location of the parent header along with the location of the MIME field. For every deprecated ``TSMimeField`` function, there is a new, preferred TSMimeHdrField* function. Therefore, you should use the ``TSMimeHdrField`` functions instead of the deprecated ``TSMimeField`` series. Examples are provided below.

Instead of:

    :::c
TSMLoc TSMimeFieldCreate (TSMBuffer bufp)

You should use:

    :::c
TSMLoc TSMimeHdrFieldCreate (TSMBuffer bufp, TSMLoc hdr)

Instead of:

    :::c
void TSMimeFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_offset,
   TSMBuffer src_bufp, TSMLoc src_offset)

You should use:

    :::c
void TSMimeHdrFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_hdr,
   TSMLoc dest_field, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc
   src_field)

In the TSMimeHdrField* function prototypes, the TSMLoc field corresponds to the TSMLoc offset used the deprecated TSMimeField* functions (see the discussion of parent TSMLoc in the following section).

Release Marshal Buffer Handles

When you fetch a component object or create a new object, you get back a handle to the object location. The handle is either an TSMLoc for an object location or char * for a string location. You can manipulate the object through these handles, but when you are finished you need to release the handle to free up system resources.

The general guideline is to release all TSMLoc and string handles you retrieve. The one exception is the string returned by TSUrlStringGet, which must be freed by a call to TSfree.

The handle release functions expect three arguments: the marshal buffer containing the data, the location of the parent object, and the location of the object to be released. The parent location is usually clear from the creation of the TSMLoc or string. For example, if your plugin had the following calls:

url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
host_string = TSUrlHostGet (bufp, url_loc, &host_length);

then your plugin would have to call:

TSHandleMLocRelease (bufp, hdr_loc, url_loc);

If an TSMLoc is obtained from a transaction, then it does not have a parent TSMLoc. Use the null TSMLoc constant TS_NULL_MLOC as its parent. For example, if your plugin calls:

TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc);

then you must release hdr_loc with:

TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);

You need to use TS_NULL_MLOC to release any TSMLoc handles retrieved by the TSHttpTxn*Get functions.

Here’s an example using a new TSMimeHdrField function:

TSHttpTxnServerRespGet( txnp, &resp_bufp, &resp_hdr_loc );
new_field_loc = TSMimeHdrFieldCreate (resp_bufp, resp_hdr_loc);
TSHandleMLocRelease ( resp_bufp, resp_hdr_loc, new_field_loc);
TSHandleMLocRelease ( resp_bufp, TS_NULL_MLOC, resp_hdr_loc);

See the sample plugins for many more examples.

小技巧

You should release handles before reenabling the HTTP transaction. In other words, call TSHandleMLocRelease before TSHttpTxnReenable.

MIME Fields Always Belong to an Associated MIME Header

When using Traffic Server, you cannot create a new MIME field without an associated MIME header or HTTP header; MIME fields are always seen as part of a MIME header or HTTP header.

To use a MIME field, you must specify the MIME header or HTTP header to which it belongs - this is called the field’s parent header. The TSMimeField* functions in older versions of the SDK have been deprecated, as they do not require the parent header as inputs. The current version of Traffic Server uses new functions, the ``TSMimeHdrField`` series, which require you to specify the location of the parent header along with the location of the MIME field. For every deprecated ``TSMimeField`` function, there is a new, preferred TSMimeHdrField* function. Therefore, you should use the ``TSMimeHdrField`` functions instead of the deprecated ``TSMimeField`` series. Examples are provided below.

Instead of:

    :::c
TSMLoc TSMimeFieldCreate (TSMBuffer bufp)

You should use:

    :::c
TSMLoc TSMimeHdrFieldCreate (TSMBuffer bufp, TSMLoc hdr)

Instead of:

    :::c
void TSMimeFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_offset,
   TSMBuffer src_bufp, TSMLoc src_offset)

You should use:

    :::c
void TSMimeHdrFieldCopyValues (TSMBuffer dest_bufp, TSMLoc dest_hdr,
   TSMLoc dest_field, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc
   src_field)

In the TSMimeHdrField* function prototypes, the TSMLoc field corresponds to the TSMLoc offset used the deprecated TSMimeField* functions (see the discussion of parent TSMLoc in the following section).

Release Marshal Buffer Handles

When you fetch a component object or create a new object, you get back a handle to the object location. The handle is either an TSMLoc for an object location or char * for a string location. You can manipulate the object through these handles, but when you are finished you need to release the handle to free up system resources.

The general guideline is to release all TSMLoc and string handles you retrieve. The one exception is the string returned by TSUrlStringGet, which must be freed by a call to TSfree.

The handle release functions expect three arguments: the marshal buffer containing the data, the location of the parent object, and the location of the object to be released. The parent location is usually clear from the creation of the TSMLoc or string. For example, if your plugin had the following calls:

url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
host_string = TSUrlHostGet (bufp, url_loc, &host_length);

then your plugin would have to call:

TSHandleMLocRelease (bufp, hdr_loc, url_loc);

If an TSMLoc is obtained from a transaction, then it does not have a parent TSMLoc. Use the null TSMLoc constant TS_NULL_MLOC as its parent. For example, if your plugin calls:

TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc);

then you must release hdr_loc with:

TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);

You need to use TS_NULL_MLOC to release any TSMLoc handles retrieved by the TSHttpTxn*Get functions.

Here’s an example using a new TSMimeHdrField function:

TSHttpTxnServerRespGet( txnp, &resp_bufp, &resp_hdr_loc );
new_field_loc = TSMimeHdrFieldCreate (resp_bufp, resp_hdr_loc);
TSHandleMLocRelease ( resp_bufp, resp_hdr_loc, new_field_loc);
TSHandleMLocRelease ( resp_bufp, TS_NULL_MLOC, resp_hdr_loc);

See the sample plugins for many more examples.

小技巧

You should release handles before reenabling the HTTP transaction. In other words, call TSHandleMLocRelease before TSHttpTxnReenable.

Duplicate MIME Fields Are Not Coalesced

MIME headers can contain more than one MIME field with the same name. Earlier versions of Traffic Server joined multiple fields with the same name into one field with composite values. This behavior came at a performance cost and caused interoperability problems with older clients and servers. Therefore, this version of Traffic Server does not coalesce duplicate fields.

Properly-behaving plugins should check for the presence of duplicate fields and then iterate over the duplicate fields via :ref:TSMimeHdrFieldNextDup <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#af2d776615afe959ed7c3639830a7061f>.

The Traffic Server API HTTP header functions enable you to work with HTTP header data stored in marshal buffers.

The HTTP header data structure is a parsed version of the HTTP header defined in the HTTP protocol specification. An HTTP header is composed of a request or response line followed by zero or more MIME fields. In fact, an HTTP header is a subclass of a MIME header; all of the MIME header routines operate on HTTP headers.

An HTTP request line is composed of a method, a URL, and version. A response line is composed of a version, status code, and reason phrase. See About HTTP Headers for additional details and examples.

To facilitate fast comparisons and reduce storage size, Traffic Server defines several pre-allocated method names. These names correspond to the methods defined in the HTTP 1.1 specification

TS_HTTP_METHOD_CONNECT
“CONNECT”
TS_HTTP_METHOD_DELETE
“DELETE”
TS_HTTP_METHOD_GE
“GET”
TS_HTTP_METHOD_HEAD
“HEAD”
TS_HTTP_METHOD_ICP_QUERY
“ICP_QUERY”
TS_HTTP_METHOD_OPTIONS
“OPTIONS”
TS_HTTP_METHOD_POST
“POST”
TS_HTTP_METHOD_PURGE
“PURGE”
TS_HTTP_METHOD_PUT
“PUT”
TS_HTTP_METHOD_TRACE
“TRACE”
TS_HTTP_METHOD_PUSH
“PUSH”

Traffic Server also defines several common values that appear in HTTP headers.

TS_HTTP_VALUE_BYTES
“bytes”
TS_HTTP_VALUE_CHUNKED
“chunked”
TS_HTTP_VALUE_CLOSE
“close”
TS_HTTP_VALUE_COMPRESS
“compress”
TS_HTTP_VALUE_DEFLATE
“deflate”
TS_HTTP_VALUE_GZIP
“gzip”
TS_HTTP_VALUE_IDENTITY
“identity”
TS_HTTP_VALUE_KEEP_ALIVE
“keep-alive”
TS_HTTP_VALUE_MAX_AGE
“max-age”
TS_HTTP_VALUE_MAX_STALE
“max-stale”
TS_HTTP_VALUE_MIN_FRESH
“min-fresh”
TS_HTTP_VALUE_MUST_REVALIDATE
“must-revalidate”
TS_HTTP_VALUE_NONE
“none”
TS_HTTP_VALUE_NO_CACHE
“no-cache”
TS_HTTP_VALUE_NO_STORE
“no-store”
TS_HTTP_VALUE_NO_TRANSFORM
“no-transform”
TS_HTTP_VALUE_ONLY_IF_CACHED
“only-if-cached”
TS_HTTP_VALUE_PRIVATE
“private”
TS_HTTP_VALUE_PROXY_REVALIDATE
“proxy-revalidate”
TS_HTTP_VALUE_PUBLIC
“public”
TS_HTTP_VALUE_S_MAX_AGE
“s-maxage”

The method names and header values above are defined in ts.h as const char* strings. When Traffic Server sets a method or a header value, it checks to make sure that the new value is one of the known values. If it is, then it stores a pointer into a global table (instead of storing the known value in the marshal buffer). The method names and header values listed above are also pointers into this table. This allows simple pointer comparison of the value returned from TSHttpMethodGet with one of the values listed above. It is also recommended that you use the above values when referring to one of the known schemes, since this removes the possibility of a spelling error.

The HTTP Header Functions are listed below:

URLs

API URL functions provide access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs; they can also retrieve or modify parts of URLs, such as port or scheme information.

The general form of an Internet URL is:

:::text
scheme://user:password@host:port/stuff

The URL data structure includes support for two specific types of internet URLs. HTTP URLs have the form:

:::text
http://user:password@host:port/path;params?query#fragment

The URL port is stored as integer. All remaining parts of the URL (scheme, user, etc.) are stored as strings. Traffic Server URL functions are named according to the portion of the URL on which they operate. For instance, the function that retrieves the host portion of a URL is named TSUrlHostGet.

To facilitate fast comparisons and reduce storage size, Traffic Server defines several preallocated scheme names.

TS_URL_SCHEME_FILE
“file” TS_URL_LEN_FILE
TS_URL_SCHEME_FTP
“ftp” TS_URL_LEN_FTP
TS_URL_SCHEME_GOPHER
“gopher” TS_URL_LEN_GOPHER
TS_URL_SCHEME_HTTP
“http” TS_URL_LEN_HTTP
TS_URL_SCHEME_HTTPS
“https” TS_URL_LEN_HTTPS
TS_URL_SCHEME_MAILTO
“mailto” TS_URL_LEN_MAILTO
TS_URL_SCHEME_NEWS
“news” TS_URL_LEN_NEWS
TS_URL_SCHEME_NNTP
“nntp” TS_URL_LEN_NNTP
TS_URL_SCHEME_PROSPERO
“prospero” TS_URL_LEN_PROSPERO
TS_URL_SCHEME_TELNET
“telnet” TS_URL_LEN_TELNET
TS_URL_SCHEME_WAIS
“wais” TS_URL_LEN_WAIS

The scheme names above are defined in ts.h as const char* strings. When Traffic Server sets the scheme portion of the URL (or any portion for that matter), it quickly checks to see if the new value is one of the known values. If it is, then it stores a pointer into a global table (instead of storing the known value in the marshal buffer). The scheme values listed above are also pointers into this table. This allows simple pointer comparison of the value returned from TSUrlSchemeGet with one of the values listed above. You should use the Traffic Server-defined values when referring to one of the known schemes, since doing so can prevent the possibility of spelling errors.

Traffic Server URL functions are listed below:

`TSUrlClone <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#acb775f48f1da5f6c5bf32c833a236574>`__ `TSUrlCopy <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#aa2b8d5f9289a23ab985210914a6301a7>`__ `TSUrlCreate <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#ad3518ea3bca6a6f2d899b859c6fbbede>`__ `TSUrlDestroy <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a87559aac42f4f9439399ba2bd32693fa>`__ `TSUrlPrint <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#adec26f5a4afe62b4308dd86f97ae08fd>`__ `TSUrlFtpTypeGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a5cd15d2c288a48b832f0fc096ed6fb80>`__ `TSUrlFtpTypeSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a66df700e23085cabf945e92eb1e22890>`__ `TSUrlHostGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a48e626d9497d4d81c0b9d2781f86066b>`__ `TSUrlHostSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a7e550dac573f5780f7ba39509aa881f3>`__ `TSUrlHttpFragmentGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a316696ad964cb6c6afb7e3028da3ef84>`__ `TSUrlHttpFragmentSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a45f7b216882c4517b92929145adf5424>`__ `TSUrlHttpParamsGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a9395d5d794078c8ec0f17f27dc8d8498>`__ `TSUrlHttpParamsSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a566f2996d36663e3eb8ed4a8fda738c3>`__ `TSUrlHttpQueryGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a74a6c51ea9f472cf29514facbf897785>`__ `TSUrlHttpQuerySet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a9846aaf11accd8c817fff48bfaa784e0>`__ `TSUrlLengthGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a96ded2567985b187c0a8274d76d12c17>`__ `TSUrlParse <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a17f785697773b62b1f5094c06896cac5>`__ `TSUrlPasswordGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a14614f77e0c15b206bab8fd6fdfa7bd1>`__ `TSUrlPasswordSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#abb4d983b9d47ba5a254c2b9dd9ad835e>`__ `TSUrlPathGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#aa064a2d5256d839819d1ec8f252c01a9>`__ `TSUrlPathSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#ad73274cb5b7e98a64d53f992681110b7>`__ `TSUrlPortGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#ad99bfb408a46f47c4aa9478fc1b95e0c>`__ `TSUrlPortSet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#aab07c0482fc3c3aae1b545fb0104e3aa>`__ `TSUrlSchemeGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a24c660b5b46f17b24d7a1cc9aa9a4930>`__ `TSUrlSchemeSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a03b1a806ea8d79806dfff39bfe138934>`__ `TSUrlStringGet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a1cda3103d8dd59372609aed6c9c47417>`__ `TSUrlUserGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a3c4d7ffcbbda447c3b665dc857a3226b>`__ `TSUrlUserSet <http://people.apache.org/~amc/ats/doc/html/InkAPI_8cc.html#a3175e9c89c2bbea5ed50e2a7f52d7f9f>`__

MIME Headers

The Traffic Server **MIME header functions ** enable you to retrieve and modify information about HTTP MIME fields.

An HTTP request or response consists of a header, body, and trailer. The HTTP header contains a request (or response) line and a MIME header. A MIME header is composed of zero or more MIME fields. A MIME field is composed of a field name, a colon, and zero or more field values (values in a field are separated by commas).

In the example below: Foo is the MIME field name, bar is the first MIME field value, and car is the second MIME field value.

:::text
Foo: bar, car

The following example is an augmented Backus-Naur Form (BNF) for the form of a MIME header - it specifies exactly what was described above. A header consists of zero or more fields that contain a name, separating colon, and zero or more values. A name or value is simply a string of tokens that is potentially zero length; a token is any character except certain control characters and separators (such as colons). For the purpose of retrieving a field, field names are not case-sensitive; therefore, the field names Foo, foo and fOO are all equivalent.

    :::text
MIME-header = *MIME-field
MIME-field = field-name ":" #field-value
field-name = *token
field-value = *token

The MIME header data structure is a parsed version of a standard Internet MIME header. The MIME header data structure is similar to the URL data structure (see URLs). The actual data is stored in a marshal buffer; the MIME header functions operate on a marshal buffer and a location (TSMLoc) within the buffer.

After a call to TSMimeHdrFieldDestroy, TSMimeHdrFieldRemove, or TSUrlDestroy is made, you must deallocate the TSMLoc handle with a call to TSHandleMLocRelease. You do not need to deallocate a NULL handles. For example: if you call TSMimeHdrFieldValueStringGet to get the value of the content type field and the field does not exist, then it returns TS_NULL_MLOC. In such a case, you wouldn’t need to deallocate the handle with a call to TSHandleMLocRelease.

The location (TSMLoc) in the MIME header functions can be either an HTTP header location or a MIME header location. If an HTTP header location is passed to these functions, then the system locates the MIME header associated with that HTTP header and executes the corresponding MIME header operations specified by the functions (see the example in the description of `TSMimeHdrCopy <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a6e0a392b2e072db8e7f1d795151203b4>`__).

Note: MIME headers may contain more than one MIME field with the same name. Previous versions of Traffic Server joined multiple fields with the same name into one field with composite values, but this behavior came at a performance cost and caused compatability issues with older clients and servers. Hence, the current version of Traffic Server does not coalesce duplicate fields. Correctly-behaving plugins should check for the presence of duplicate fields and iterate over the duplicate fields by using TSMimeHdrFieldNextDup.

To facilitate fast comparisons and reduce storage size, Traffic Server defines several pre-allocated field names. These field names correspond to the field names in HTTP and NNTP headers.

TS_MIME_FIELD_ACCEPT
“Accept” TS_MIME_LEN_ACCEPT
TS_MIME_FIELD_ACCEPT_CHARSET
“Accept-Charset” TS_MIME_LEN_ACCEPT_CHARSET
TS_MIME_FIELD_ACCEPT_ENCODING
“Accept-Encoding” TS_MIME_LEN_ACCEPT_ENCODING
TS_MIME_FIELD_ACCEPT_LANGUAGE
“Accept-Language” TS_MIME_LEN_ACCEPT_LANGUAGE
TS_MIME_FIELD_ACCEPT_RANGES
“Accept-Ranges” TS_MIME_LEN_ACCEPT_RANGES
TS_MIME_FIELD_AGE
“Age” TS_MIME_LEN_AGE
TS_MIME_FIELD_ALLOW
“Allow” TS_MIME_LEN_ALLOW
TS_MIME_FIELD_APPROVED
“Approved” TS_MIME_LEN_APPROVED
TS_MIME_FIELD_AUTHORIZATION
“Authorization” TS_MIME_LEN_AUTHORIZATION
TS_MIME_FIELD_BYTES
“Bytes” TS_MIME_LEN_BYTES
TS_MIME_FIELD_CACHE_CONTROL
“Cache-Control” TS_MIME_LEN_CACHE_CONTROL
TS_MIME_FIELD_CLIENT_IP
“Client-ip” TS_MIME_LEN_CLIENT_IP
TS_MIME_FIELD_CONNECTION
“Connection” TS_MIME_LEN_CONNECTION
TS_MIME_FIELD_CONTENT_BASE
“Content-Base” TS_MIME_LEN_CONTENT_BASE
TS_MIME_FIELD_CONTENT_ENCODING
“Content-Encoding” TS_MIME_LEN_CONTENT_ENCODING
TS_MIME_FIELD_CONTENT_LANGUAGE
“Content-Language” TS_MIME_LEN_CONTENT_LANGUAGE
TS_MIME_FIELD_CONTENT_LENGTH
“Content-Length” TS_MIME_LEN_CONTENT_LENGTH
TS_MIME_FIELD_CONTENT_LOCATION
“Content-Location” TS_MIME_LEN_CONTENT_LOCATION
TS_MIME_FIELD_CONTENT_MD5
“Content-MD5” TS_MIME_LEN_CONTENT_MD5
TS_MIME_FIELD_CONTENT_RANGE
“Content-Range” TS_MIME_LEN_CONTENT_RANGE
TS_MIME_FIELD_CONTENT_TYPE
“Content-Type” TS_MIME_LEN_CONTENT_TYPE
TS_MIME_FIELD_CONTROL
“Control” TS_MIME_LEN_CONTROL
TS_MIME_FIELD_COOKIE
“Cookie” TS_MIME_LEN_COOKIE
TS_MIME_FIELD_DATE
“Date” TS_MIME_LEN_DATE
TS_MIME_FIELD_DISTRIBUTION
“Distribution” TS_MIME_LEN_DISTRIBUTION
TS_MIME_FIELD_ETAG
“Etag” TS_MIME_LEN_ETAG
TS_MIME_FIELD_EXPECT
“Expect” TS_MIME_LEN_EXPECT
TS_MIME_FIELD_EXPIRES
“Expires” TS_MIME_LEN_EXPIRES
TS_MIME_FIELD_FOLLOWUP_TO
“Followup-To” TS_MIME_LEN_FOLLOWUP_TO
TS_MIME_FIELD_FROM
“From” TS_MIME_LEN_FROM
TS_MIME_FIELD_HOST
“Host” TS_MIME_LEN_HOST
TS_MIME_FIELD_IF_MATCH
“If-Match” TS_MIME_LEN_IF_MATCH
TS_MIME_FIELD_IF_MODIFIED_SINCE
“If-Modified-Since” TS_MIME_LEN_IF_MODIFIED_SINCE
TS_MIME_FIELD_IF_NONE_MATCH
“If-None-Match” TS_MIME_LEN_IF_NONE_MATCH
TS_MIME_FIELD_IF_RANGE
“If-Range” TS_MIME_LEN_IF_RANGE
TS_MIME_FIELD_IF_UNMODIFIED_SINCE
“If-Unmodified-Since” TS_MIME_LEN_IF_UNMODIFIED_SINCE
TS_MIME_FIELD_KEEP_ALIVE
“Keep-Alive” TS_MIME_LEN_KEEP_ALIVE
TS_MIME_FIELD_KEYWORDS
“Keywords” TS_MIME_LEN_KEYWORDS
TS_MIME_FIELD_LAST_MODIFIED
“Last-Modified” TS_MIME_LEN_LAST_MODIFIED
TS_MIME_FIELD_LINES
“Lines” TS_MIME_LEN_LINES
TS_MIME_FIELD_LOCATION
“Location” TS_MIME_LEN_LOCATION
TS_MIME_FIELD_MAX_FORWARDS
“Max-Forwards” TS_MIME_LEN_MAX_FORWARDS
TS_MIME_FIELD_MESSAGE_ID
“Message-ID” TS_MIME_LEN_MESSAGE_ID
TS_MIME_FIELD_NEWSGROUPS
“Newsgroups” TS_MIME_LEN_NEWSGROUPS
TS_MIME_FIELD_ORGANIZATION
“Organization” TS_MIME_LEN_ORGANIZATION
TS_MIME_FIELD_PATH
“Path” TS_MIME_LEN_PATH
TS_MIME_FIELD_PRAGMA
“Pragma” TS_MIME_LEN_PRAGMA
TS_MIME_FIELD_PROXY_AUTHENTICATE
“Proxy-Authenticate” TS_MIME_LEN_PROXY_AUTHENTICATE
TS_MIME_FIELD_PROXY_AUTHORIZATION
“Proxy-Authorization” TS_MIME_LEN_PROXY_AUTHORIZATION
TS_MIME_FIELD_PROXY_CONNECTION
“Proxy-Connection” TS_MIME_LEN_PROXY_CONNECTION
TS_MIME_FIELD_PUBLIC
“Public” TS_MIME_LEN_PUBLIC
TS_MIME_FIELD_RANGE
“Range” TS_MIME_LEN_RANGE
TS_MIME_FIELD_REFERENCES
“References” TS_MIME_LEN_REFERENCES
TS_MIME_FIELD_REFERER
“Referer” TS_MIME_LEN_REFERER
TS_MIME_FIELD_REPLY_TO
“Reply-To” TS_MIME_LEN_REPLY_TO
TS_MIME_FIELD_RETRY_AFTER
“Retry-After” TS_MIME_LEN_RETRY_AFTER
TS_MIME_FIELD_SENDER
“Sender” TS_MIME_LEN_SENDER
TS_MIME_FIELD_SERVER
“Server” TS_MIME_LEN_SERVER
TS_MIME_FIELD_SET_COOKIE
“Set-Cookie” TS_MIME_LEN_SET_COOKIE
TS_MIME_FIELD_SUBJECT
“Subject” TS_MIME_LEN_SUBJECTTS_MIME_LEN_SUBJECT
TS_MIME_FIELD_SUMMARY
“Summary” TS_MIME_LEN_SUMMARY
TS_MIME_FIELD_TE
“TE” TS_MIME_LEN_TE
TS_MIME_FIELD_TRANSFER_ENCODING
“Transfer-Encoding” TS_MIME_LEN_TRANSFER_ENCODING
TS_MIME_FIELD_UPGRADE
“Upgrade” TS_MIME_LEN_UPGRADE
TS_MIME_FIELD_USER_AGENT
“User-Agent” TS_MIME_LEN_USER_AGENT
TS_MIME_FIELD_VARY
“Vary” TS_MIME_LEN_VARY
TS_MIME_FIELD_VIA
“Via” TS_MIME_LEN_VIA
TS_MIME_FIELD_WARNING
“Warning” TS_MIME_LEN_WARNING
TS_MIME_FIELD_WWW_AUTHENTICATE
“Www-Authenticate” TS_MIME_LEN_WWW_AUTHENTICATE
TS_MIME_FIELD_XREF
“Xref” TS_MIME_LEN_XREF

The header field names above are defined in ts.h as const char* strings. When Traffic Server sets the name portion of a header field (or any portion for that matter), it quickly checks to see if the new value is one of the known values. If it is, then Traffic Server stores a pointer into a global table instead of storing the known value in the marshal buffer. The header field names listed above are also pointers into this table, which enables simple pointer comparison of the value returned from TSMimeHdrFieldNameGet with one of the values listed above. It is recommended that you use the above values when referring to one of the known header field names to avoid the possibility of a spelling error.

Traffic Server adds one important feature to MIME fields that you may not know about: Traffic Server does not print a MIME field if the field name begins with the ‘@‘ symbol. For example: a plugin can add the field “@My-Field” to a header. Even though Traffic Server never sends that field out in a request to an origin server or in a response to a client, it can be printed to Traffic Server logs by defining a custom log configuration file that explicitly logs such fields. This provides a useful mechanism for plugins to store information about an object in one of the MIME headers associated with the object.

The MIME header functions are listed below:

About HTTP Headers

An HTTP message consists of the following:

  • HTTP header
  • body
  • trailer

The HTTP header consists of:

  • A request or response line
    • An HTTP request line contains a method, URL, and version
    • A response line contains a version, status code, and reason phrase
  • A MIME header

A MIME header is comprised of zero or more MIME fields. A MIME field is composed of a field name, a colon, and (zero or more) field values. The values in a field are separated by commas. An HTTP header containing a request line is usually referred to as a request. The following example shows a typical request header:

GET http://www.tiggerwigger.com/ HTTP/1.0
Proxy-Connection: Keep-Alive
User-Agent: Mozilla/5.0 [en] (X11; I; Linux 2.2.3 i686)
Host: www.tiggerwigger.com
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1, *, utf-8

The response header for the above request might look like the following:

HTTP/1.0 200 OK
Date: Fri, 13 Nov 2009 06:57:43 GMT
Content-Location: http://locutus.tiggerwigger.com/index.html
Etag: "07db14afa76be1:1074"
Last-Modified: Thu, 05 Nov 2009 20:01:38 GMT
Content-Length: 7931
Content-Type: text/html
Server: Microsoft-IIS/4.0
Age: 922
Proxy-Connection: close

The following figure illustrates an HTTP message with an expanded HTTP header.

Figure 10.1. HTTP Request/Response and Header Structure

HTTP Request/Response and Header Structure

HTTP Request/Response and Header Structure

The figure below shows example HTTP request and response headers.

Figure 10.2. Examples of HTTP Request and Response Headers

Examples of HTTP Request and Response Headers

Examples of HTTP Request and Response Headers

The marshal buffer or TSMBuffer is a heap data structure that stores parsed URLs, MIME headers, and HTTP headers. You can allocate new objects out of marshal buffers and change the values within the marshal buffer. Whenever you manipulate an object, you must require the handle to the object (TSMLoc) and the marshal buffer containing the object (TSMBuffer).

Figure 10.3. Marshal Buffers and Header Locations

Marshal Buffers and Header Locations

Marshal Buffers and Header Locations

The figure above shows the following:

  • The marshal buffer containing the HTTP request, reqest_bufp
  • TSMLoc location pointer for the HTTP header (http_hdr_loc)
  • TSMLoc location pointer for the request URL (url_loc)
  • TSMLoc location pointers for the MIME header (mime_hdr_loc)
  • TSMLoc location pointers for MIME fields (fieldi_loc)
  • TSMLoc location pointer for the next duplicate MIME field (next_dup_loc)

The diagram also shows that an HTTP header contains pointers to the URL location and the MIME header location. You can obtain the URL location from an HTTP header using the function TSHttpHdrUrlGet. To work with MIME headers, you can pass either a MIME header location or an HTTP header location to MIME header functions . If you pass an HTTP header to a MIME header function, then the system locates the associated MIME header and executes the MIME header function on the MIME header location.

Mutex Guide

Mutexes are used to lock shared data. This chapter explains how to use the mutex interface.

Mutexes

A mutex is the basic synchronization method used within Traffic Server to protect data from simultaneous access by multiple threads. A mutex acts as a lock that protects data in one program thread from being accessed by another thread.

The Traffic Server API provides two functions that attempt to access and lock the data: InkMutexLockTry and TSMutexLock. ``TSMutexLock`` is a blocking call - if you use it, you can slow Traffic Server performance because transaction processing pauses until the mutex is unlocked. It should be used only on threads created by the plugin TSContThreadCreate. Never use it on a continuation handler called back by the Cache, Net, or Event Processor. Even if the critical section is very small, do not use it. If you need to update a flag, then set a variable and/or use atomic operations. If TSMutexLock is used in any case other than the one recommended above, then the result will be a serious performance impact.

``TSMutexLockTry``, on the other hand, attempts to lock the mutex only if it is unlocked (i.e., not being used by another thread). It should be used in all cases other than the above mentioned TSMutexLock case. If the TSMutexLockTry attempt fails, then you can schedule a future attempt (which must be at least 10 milliseconds later).

In general, you should use TSMutexLockTry instead of TSMutexLock.

  • InkMutexLockTry is required if you are tying to lock Traffic Server internal or system resources (such as the network, cache, event processor, HTTP state machines, and IO buffers).
  • InkMutexLockTry is required if you are making any blocking calls (such as network, cache, or file IO calls).
  • TSMutexLock might not be necessary if you are not making blocking calls and if you are only accessing local resources.

The Traffic Server API uses the TSMutex type for a mutex. There are two typical uses of mutex. One use is for locking global data or data shared by various continuations. The other typical usage is for locking data associated with a continuation (i.e., data that might be accessed by other continuations).

Locking Global Data

The blacklist-1.c sample plugin implements a mutex that locks global data. The blacklist plugin reads its blacklisted sites from a configuration file; file read operations are protected by a mutex created in TSPluginInit. The blacklist-1.c code uses TSMutexLockTry instead of InkMutexLock. For more detailed information, see the `blacklist-1.c <../sample-source-code#Sample_blacklist-1.c>`__ code; start by looking at the `TSPluginInit <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a9a0b0ac9cbce9d6644f66bbe93098313>`__ function.

General guidelines for locking shared data are as follows:

  1. Create a mutex for the shared data with `TSMutexCreate <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#aa4300d8888c6962a44c9e827d633e433>`__.
  2. Whenever you need to read or modify this data, first lock it by calling `TSMutexLockTry <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#ac9c08451aa529851b9474e3c035f44bb>`__; then read or modify the data.
  3. When you are done with the data, unlock it with `TSMutexUnlock <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#afbb474c217fd5b927f1f8487c45646dd>`__. If you are unlocking data accessed during the processing of an HTTP transaction, then you must unlock it before calling `TSHttpTxnReenable <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#ac367347e02709ac809994dfb21d3288a>`__.
Protecting a Continuation’s Data

You must create a mutex to protect a continuation’s data if it might be accessed by other continuations or processes. Here’s how:

  1. Create a mutex for the continuation using TSMutexCreate.
    For example:
            ::::c
    TSMutex mutexp;
    mutexp = TSMutexCreate ();
  2. When you create the continuation, specify this mutex as the continuation’s mutex.
    For example:
            :::c
            TSCont contp;
    contp = TSContCreate (handler, mutexp);

If any other functions want to access contp‘s data, then it is up to them to get contp‘s mutex (using, for example, TSContMutexGet) to lock it. For usage, ssee the sample Protocol plugin.

How to Associate a Continuation With Every HTTP Transaction

There could be several reasons why you’d want to create a continuation for each HTTP transaction that calls back your plugin.

Some potential scenarios are listed below.

  • You want to register hooks locally with the new continuation instead of registering them globally to the continuation plugin.
  • You want to store data specific to each HTTP transaction that you might need to reuse across various hooks.
  • You’re using APIs (like TSHostLookup) that will call back the continuation with a certain event.
How to Add the New Continuation

A typical way of adding the new continuation is by registering the plugin continuation to be called back by HTTP transactions globally when they reach TS_HTTP_TXN_START_HOOK. Refer to the example below, which uses a transaction-specific continuation called txn_contp.

::::c
void TSPluginInit(int argc, const char *argv[])
{
    /* Plugin continuation */
    TSCont contp;
    if ((contp = TSContCreate (plugin_cont_handler, NULL)) == TS_ERROR_PTR) {
        LOG_ERROR("TSContCreate");
    } else {
        if (TSHttpHookAdd (TS_HTTP_TXN_START_HOOK, contp) == TS_ERROR) {
            LOG_ERROR("TSHttpHookAdd");
        }
    }
}

In the plugin continuation handler, create the new continuation txn_contp and then register it to be called back at TS_HTTP_TXN_CLOSE_HOOK:

::::c
static int plugin_cont_handler(TSCont contp, TSEvent event, void *edata)
{
    TSHttpTxn txnp = (TSHttpTxn)edata;
    TSCont txn_contp;

    switch (event) {
        case TS_EVENT_HTTP_TXN_START:
            /* Create the HTTP txn continuation */
            txn_contp = TSContCreate(txn_cont_handler, NULL);

            /* Register txn_contp to be called back when txnp reaches TS_HTTP_TXN_CLOSE_HOOK */
            if (TSHttpTxnHookAdd (txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp) == TS_ERROR) {
                LOG_ERROR("TSHttpTxnHookAdd");
            }

            break;

        default:
            TSAssert(!"Unexpected Event");
            break;
    }

    if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) {
        LOG_ERROR("TSHttpTxnReenable");
    }

    return 0;
}

Remember that the txn_contp handler must destory itself when the HTTP transaction is closed. If you forget to do this, then your plugin will have a memory leak.

::::c
static int txn_cont_handler(TSCont txn_contp, TSEvent event, void *edata)
{
    TSHttpTxn txnp;
    switch (event) {
        case TS_EVENT_HTTP_TXN_CLOSE:
            txnp = (TSHttpTxn) edata;
            TSContDestroy(txn_contp);
            break;

        default:
            TSAssert(!"Unexpected Event");
            break;
    }

    if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) {
        LOG_ERROR("TSHttpTxnReenable");
    }

    return 0;
}
How to Store Data Specific to Each HTTP Transaction

For the example above, store the data in the txn_contp data structure - this means that you’ll create your own data structure. Now suppose you want to store the state of the HTTP transaction:

    ::::c
typedef struct {
      int state;
  } ContData;

You need to allocate the memory and initialize this structure for each HTTP txnp. You can do that in the plugin continuation handler when it is called back with TS_EVENT_HTTP_TXN_START

::::c
static int plugin_cont_handler(TSCont contp, TSEvent event, void *edata)
{
    TSHttpTxn txnp = (TSHttpTxn)edata;
    TSCont txn_contp;
    ContData *contData;

    switch (event) {
        case TS_EVENT_HTTP_TXN_START:
            /* Create the HTTP txn continuation */
            txn_contp = TSContCreate(txn_cont_handler, NULL);

            /* Allocate and initialize the txn_contp data */
            contData = (ContData*) TSmalloc(sizeof(ContData));
            contData->state = 0;
            if (TSContDataSet(txn_contp, contData) == TS_ERROR) {
                LOG_ERROR("TSContDataSet");
            }

            /* Register txn_contp to be called back when txnp reaches TS_HTTP_TXN_CLOSE_HOOK */
            if (TSHttpTxnHookAdd (txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp) == TS_ERROR) {
                LOG_ERROR("TSHttpTxnHookAdd");
            }

            break;

        default:
            TSAssert(!"Unexpected Event");
            break;
    }

    if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) {
        LOG_ERROR("TSHttpTxnReenable");
    }

    return 0;
}

For accessing this data from anywhere, use TSContDataGet:

::::c
TSCont txn_contp;
ContData *contData;

contData = TSContDataGet(txn_contp);
if (contData == TS_ERROR_PTR) {
    LOG_ERROR("TSContDataGet");
}
contData->state = 1;

Remember to free this memory before destroying the continuation:

::::c
static int txn_cont_handler(TSCont txn_contp, TSEvent event, void *edata)
{
    TSHttpTxn txnp;
    ContData *contData;
    switch (event) {
        case TS_EVENT_HTTP_TXN_CLOSE:
            txnp = (TSHttpTxn) edata;
            contData = TSContDataGet(txn_contp);
            if (contData == TS_ERROR_PTR) {
                LOG_ERROR("TSContDataGet");
            } else {
                TSfree(contData);
            }
            TSContDestroy(txn_contp);
            break;

        default:
            TSAssert(!"Unexpected Event");
            break;
    }

    if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) {
        LOG_ERROR("TSHttpTxnReenable");
    }

    return 0;
}
Using Locks

You do not need to use locks when a continuation has registered itself to be called back by HTTP hooks and it only uses the HTTP APIs. In the example above, the continuation txn_contp has registered itself to be called back at HTTP hooks and it only uses the HTTP APIs. In this case only, it’s safe to access data shared between txnp and txn_contp without grabbing a lock. In the example above, txn_contp is created with a NULL mutex. This works because the HTTP transaction txnp is the only one that will call back txn_contp, and you are guaranteed that txn_contp will be called back only one hook at a time. After processing is finished, txn_contp will reenable txnp.

In all other cases, you should create a mutex with the continuation. In general, a lock is needed when you’re using iocore APIs or any other API where txn_contp is scheduled to be called back by a processor (such as the cache processor, the DNS processor, etc.). This ensures that txn_contp is called back sequentially and not simultaneously. In other words, you need to ensure that txn_contp will not be called back by both txnp and the cache processor at the same time, since this will result in a situation wherein you’re executing two pieces of code in conflict.

Special Case: Continuations Created for HTTP Transactions

If your plugin creates a new continuation for each HTTP transaction, then you probably don’t need to create a new mutex for it because each HTTP transaction (TSHttpTxn object) already has its own mutex.

In the example below, it’s not necessary to specify a mutex for the continuation created in txn_handler:

    ::::c
static void
txn_handler (TSHttpTxn txnp, TSCont contp) {
    TSCont newCont;
    ....
        newCont = TSContCreate (newCont_handler, NULL);
    //It's not necessary to create a new mutex for newCont.

    ...

        TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
}

    static int
    test_plugin (TSCont contp, TSEvent event, void *edata) {
        TSHttpTxn txnp = (TSHttpTxn) edata;

        switch (event) {
            case TS_EVENT_HTTP_READ_REQUEST_HDR:
                txn_handler (txnp, contp);
                return 0;
            default:
                break;
        }
        return 0;
    }

The mutex functions are listed below:

Continuations
How to Activate Continuations

Continuations are activated when they receive an event or by TSContSchedule (which schedules a continuation to receive an event). Continuations might receive an event because:

  • Your plugin calls TSContCall
  • The Traffic Server HTTP state machine sends an event corresponding to a particular HTTP hook
  • A Traffic Server IO processor (such as a cache processor or net processor) is letting a continuation know there is data (cache or network) available to read or write. These callbacks are a result of using functions such TSVConnRead/Write or TSCacheRead/Write
Writing Handler Functions

The handler function is the key component of a continuation. It is supposed to examine the event and event data, and then do something appropriate. The probable action might be to schedule another event for the continuation to received, to open up a connection to a server, or simply to destroy itself.

The continuation’s handler function is a function of type TSEventFunc. Its arguments are a continuation, an event, and a pointer to some data (this data is passed to the continuation by the caller - do not confuse this data with the continuation’s own data, associated by TSContDataSet). When the continuation is called back, the continuation and an event are passed to the handler function. The continuation is a handle to the same continuation that is invoked. The handler function typically has a switch statement to handle the events it receives:

static int some_handler (TScont contp, TSEvent event, void *edata)
{
   // .....
   switch(event) {
      case TS_EVENT_SOME_EVENT_1:
         do_some_thing_1;
         return;
      case TS_EVENT_SOME_EVENT_2:
         do_some_thing_2;
         return;
      case TS_EVENT_SOME_EVENT_3:
         do_some_thing_3;
         return;
      default: break;
   }
   return 0;
}

警告

You might notice that a continuation cannot determine if more events are “in flight” toward it. Do not use TSContDestroy to delete a continuation before you make sure that all incoming events, such as those sent because of TSHttpTxnHookAdd, have been handled.

The following table lists events and the corresponding type of void* data passed to handler functions:

Event Event Sender Data Type
TS_EVENT_HTTP_READ_REQUEST_HDR TS_HTTP_READ_REQUEST_HDR_HOOK TSHttpTxn
TS_EVENT_HTTP_OS_DNS TS_HTTP_OS_DNS_HOOK TSHttpTxn
TS_EVENT_HTTP_SEND_REQUEST_HDR TS_HTTP_SEND_REQUEST_HDR_HOOK TSHttpTxn
TS_EVENT_HTTP_READ_CACHE_HDR TS_HTTP_READ_CACHE_HDR_HOOK TSHttpTxn
TS_EVENT_HTTP_READ_RESPONSE_HDR TS_HTTP_READ_RESPONSE_HDR_HOOK TSHttpTxn
TS_EVENT_HTTP_SEND_RESPONSE_HDR TS_HTTP_SEND_RESPONSE_HDR_HOOK TSHttpTxn
TS_EVENT_HTTP_SELECT_ALT TS_HTTP_SELECT_ALT_HOOK TSHttpTxn
TS_EVENT_HTTP_TXN_START TS_HTTP_TXN_START_HOOK TSHttpTxn
TS_EVENT_HTTP_TXN_CLOSE TS_HTTP_TXN_CLOSE_HOOK TSHttpTxn
TS_EVENT_HTTP_SSN_START TS_HTTP_SSN_START_HOOK TSHttpSsn
TS_EVENT_HTTP_SSN_CLOSE TS_HTTP_SSN_CLOSE_HOOK TSHttpSsn
TS_EVENT_NONE    
TS_EVENT_CACHE_LOOKUP_COMPLETE TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK TSHttpTxn
TS_EVENT_IMMEDIATE TSVConnClose TSVIOReenable TSContSchedule  
TS_EVENT_IMMEDIATE TS_HTTP_REQUEST_TRANSFORM_HOOK  
TS_EVENT_IMMEDIATE TS_HTTP_RESPONSE_TRANSFORM_HOOK  
TS_EVENT_CACHE_OPEN_READ TSCacheRead Cache VC
TS_EVENT_CACHE_OPEN_READ_FAILED TSCacheRead TS_CACHE_ERROR code
TS_EVENT_CACHE_OPEN_WRITE TSCacheWrite Cache VC
TS_EVENT_CACHE_OPEN_WRITE_FAILED TSCacheWrite TS_CACHE_ERROR code
TS_EVENT_CACHE_REMOVE TSCacheRemove  
TS_EVENT_CACHE_REMOVE_FAILED TSCacheRemove TS_CACHE_ERROR code
TS_EVENT_NET_ACCEPT TSNetAccept TSHttpTxnServerIntercept TSHttpTxnIntercept NetVConnection
TS_EVENT_NET_ACCEPT_FAILED TSNetAccept TSHttpTxnServerIntercept TSHttpTxnIntercept  
TS_EVENT_HOST_LOOKUP TSHostLookup TSHostLookupResult
TS_EVENT_TIMEOUT TSContSchedule  
TS_EVENT_ERROR    
TS_EVENT_VCONN_READ_READY TSVConnRead TSVConn
TS_EVENT_VCONN_WRITE_READY TSVConnWrite TSVConn
TS_EVENT_VCONN_READ_COMPLETE TSVConnRead TSVConn
TS_EVENT_VCONN_WRITE_COMPLETE TSVConnWrite TSVConn
TS_EVENT_VCONN_EOS TSVConnRead TSVConn
TS_EVENT_NET_CONNECT TSNetConnect TSVConn
TS_EVENT_NET_CONNECT_FAILED TSNetConnect TSVConn
TS_EVENT_HTTP_CONTINUE    
TS_EVENT_HTTP_ERROR    
TS_EVENT_MGMT_UPDATE TSMgmtUpdateRegister  

The continuation functions are listed below:

  • TSContCall
  • TSContCreate
  • TSContDataGet
  • TSContDataSet
  • TSContDestroy
  • TSContMutexGet
  • TSContSchedule

The continuation interface is Traffic Server’s basic callback mechanism. Continuations are instances of the opaque data type TSCont. In its basic form, a continuation represents a handler function and a mutex.

This chapter covers the following topics:

Mutexes and Data

A continuation must be created with a mutex if your continuation does one of the following:

  • is registered globally (TSHttpHookAdd or TSHttpSsnHookAdd) to an HTTP hook and uses TSContDataSet/Get
  • is registered locally (TSHttpTxnHookAdd), but for multiple transactions uses TSContDataSet/Get
  • uses TSCacheXXX, TSNetXXX, TSHostLookup, or TSContSchedule APIs

Before being activated, a caller must grab the continuation’s mutex. This requirement makes it possible for a continuation’s handler function to safely access its data and to prevent multiple callers from running it at the same time (see the About the Sample Protocol for usage). The data protected by the mutex is any global or continuation data associated to the continuation by TSContDataSet. This does not include the local data created by the continuation handler function. A typical example of continuations created with associated data structures and mutexes is the transaction state machine created in the sample Protocol plugin (see One Way to Implement a Transaction State Machine).

A reentrant call occurs when the continuation passed as an argument to the API can be called in the same stack trace as the function calling the API. For example, if you call TSCacheRead (contp, mykey), it is possible that contp‘s handler will be called directly and then TSCacheRead returns.

Caveats that could cause issues include the following:

  • a continuation has data associated with it (TSContDataGet).
  • the reentrant call passes itself as a continuation to the reentrant API. In this case, the continuation should not try to access its data after calling the reentrant API. The reason for this is that data may be modified by the section of code in the continuation’s handler that handles the event sent by the API. It is recommended that you always return after a reentrant call to avoid accessing something that has been deallocated.

Below is an example, followed by an explanation.

continuation_handler (TSCont contp, TSEvent event, void *edata) {
    switch (event) {
        case event1:
            TSReentrantCall (contp);
            /* Return right away after this call */
            break;
        case event2:
            TSContDestroy (contp);
            break;
    }
}

The above example first assumes that the continuation is called back with event1; it then does the first reentrant call that schedules the continuation to receive event2. Because the call is reentrant, the processor calls back the continuation right away with event2 and the continuation is destroyed. If you try to access the continuation or one of its members after the reentrant call, then you might access something that has been deallocated. To avoid accessing something that has been deallocated, never access the continuation or any of its members after a reentrant call - just exit the handler.

Note: Most HTTP transaction plugin continuations do not need non-null mutexes because they’re called within the processing of an HTTP transaction, and therefore have the transaction’s mutex.

It is also possible to specify a continuation’s mutex as NULL. This should be done only when registering a continuation to a global hook, by a call to TSHttpHookAdd. In this case, the continuation can be called simultaneously by different instances of HTTP SM running on different threads. Having a mutex here would slow and/or hinder Traffic Server performance, since all the threads will try to lock the same mutex. The drawback of not having a mutex is that such a continuation cannot have data associated with it (i.e., TSContDataGet/Set cannot be used).

When using a NULL mutex it is dangerous to access the continuation’s data, but usually continuations with NULL mutexes have no data associated with them anyway. An example of such a continuation is one that gets called back every time an HTTP request is read, and then determines from the request alone if the request should go through or be rejected. An HTTP transaction gives its continuation data to the contp.

Plugin Configurations

This chapter contains the following section:

Plugin Configurations

The TSConfig family of functions provides a mechanism for accessing and changing global configuration information within a plugin.

The functions discussed in this section do not examine or modify Traffic Server configuration variables. To examine Traffic Server configuration and statistics variables, see “Reading Traffic Server Settings and Statistics”

The TSConfig family of functions is designed to provide a fast and efficient mechanism for accessing and changing global configuration information within a plugin. Such a mechanism is simple enough to provide in a single-threaded program, but the translation to a multi-threaded program such as Traffic Server is difficult. A common technique is to have a single mutex protect the global configuration information; however, the problem with this solution is that a single mutex becomes a performance bottleneck very quickly.

The TSConfig family of functions define an interface to storing and retrieving an opaque data pointer. Internally, Traffic Server maintains reference count information about the data pointer so that a call to TSConfigSet will not disturb another thread using the current data pointer. The philosophy is that once a user has a hold of the configuration pointer, it is okay for it to be used even if the configuration changes; all that a user typically wants is a non-changing snapshot of the configuration. You should use TSConfigSet for all global data updates.

Here’s how the interface works:

    ::::c
/* Assume that you have previously defined a plugin configuration
 * data structure named ConfigData, along with its constructor
 * plugin_config_allocator () and its destructor
 * plugin_config_destructor (ConfigData *data)
 */
ConfigData *plugin_config;

/* You will need to assign plugin_config a unique identifier of type
 * unsigned int. It is important to initialize this identifier to zero
 * (see the documentation of the  function).
 */
static unsigned int   my_id = 0;

/* You will need an TSConfig pointer to access a snapshot of the
 * current plugin_config.
 */
TSConfig config_ptr;

/* Initialize plugin_config. */
plugin_config = plugin_config_allocator();

/* Assign plugin_config an identifier using TSConfigSet. */
my_id = TSConfigSet (my_id, plugin_config, plugin_config_destructor);

/* Get a snapshot of the current configuration using TSConfigGet. */
config_ptr = TSConfigGet (my_id);

/* With an TSConfig pointer to the current configuration, you can
 * retrieve the configuration's current data using TSConfigDataGet.
 */
plugin_config = (ConfigData*) TSConfigDataGet (config_ptr);

/* Do something with plugin_config here. */

/* When you are done with retrieving or modifying the plugin data, you
 * release the pointers to the data with a call to TSConfigRelease.
 */
TSConfigRelease (my_id, config_ptr);

/* Any time you want to modify plugin_config, you must repeat these
 * steps, starting with
 * my_id = TSConfigSet (my_id,plugin_config, plugin_config_destructor);
 * and continuing up to TSConfigRelease.
 */

The configuration functions are:

Actions Guide
Hosts Lookup API

The hosts lookup enables plugins to ask Traffic Server to do a host lookup of a host name, much like a DNS lookup.

The hosts lookup functions are as follows:

Actions

An action is a handle to an operation initiated by a plugin that has not yet completed. For example: when a plugin connects to a remote server, it uses the call TSNetConnect - which takes TSCont as an argument to call back when the connection is established. TSNetConnect might not call the continuation back immediately and will return an TSAction structure that the caller can use to cancel the operation. Cancelling the operation does not necessarily mean that the operation will not occur; it simply means that the continuation passed into the operation will not be called back. In such an example, the connection might still occur if the action is cancelled; however, the continuation that initiated the connection would not be called back.

In the preceding example, it is also possible that the connection will complete and call back the continuation before TSNetConnect returns. If that occurs, then TSNetConnect returns a special action that causes TSActionDone to return 1. This specifies that the operation has already completed, so it’s pointless to try to cancel the operation. Also note that an action will never change from non-completed to completed. When the operation actually succeeds and the continuation is called back, the continuation must zero out its action pointer to indicate to itself that the operation succeeded.

The asynchronous nature of all operations in Traffic Server necessitates actions. You should notice from the above discussion that once a call to a function like TSNetConnect is made by a continuation and that function returns a valid action (TSActionDone returns 0), it is not safe for the continuation to do anything else except return from its handler function. It is not safe to modify or examine the continuation’s data because the continuation may have already been destroyed.

Below is an example of typical usage for an action:

::::c
#include <ts/ts.h>
static int
handler (TSCont contp, TSEvent event, void *edata)
{
    if (event == TS_EVENT_IMMEDIATE) {
        TSAction actionp = TSNetConnect (contp, 127.0.0.1, 9999);
        if (!TSActionDone (actionp)) {
            TSContDataSet (contp, actionp);
        } else {
            /* We've already been called back... */
            return 0;
        }
    } else if (event == TS_EVENT_NET_CONNECT) {
        /* Net connection succeeded */
        TSContDataSet (contp, NULL);
        return 0;
    } else if (event == TS_EVENT_NET_CONNECT_FAILED) {
        /* Net connection failed */
        TSContDataSet (contp, NULL);
        return 0;
    }
    return 0;
}

   void
TSPluginInit (int argc, const char *argv[])
{
    TSCont contp;

    contp = TSContCreate (handler, TSMutexCreate ());

    /* We don't want to call things out of TSPluginInit
       directly since it's called before the rest of the
       system is initialized. We'll simply schedule an event
       on the continuation to occur as soon as the rest of
       the system is started up. */
    TSContSchedule (contp, 0);
}

The example above shows a simple plugin that creates a continuation and then schedules it to be called immediately. When the plugin’s handler function is called the first time, the event is TS_EVENT_IMMEDIATE. The plugin then tries to open a net connection to port 9999 on localhost (127.0.0.1). The IP description was left in cider notation to further clarify what is going on; also note that the above won’t actually compile until the IP address is modified. The action returned from TSNetConnect is examined by the plugin. If the operation has not completed, then the plugin stores the action in its continuation. Otherwise, the plugin knows it has already been called back and there is no reason to store the action pointer.

A final question might be, “why would a plugin want to cancel an action?” In the above example, a valid reason could be to place a limit on the length of time it takes to open a connection. The plugin could schedule itself to get called back in 30 seconds and then initiate the net connection. If the timeout expires first, then the plugin would cancel the action. The following sample code implements this:

:::::c
#include <ts/ts.h>
static int
handler (TSCont contp, TSEvent event, void *edata)
{
    switch (event) {
        case (TS_EVENT_IMMEDIATE):
            TSContSchedule (contp, 30000);
            TSAction actionp = TSNetConnect(contp, 127.0.0.1, 9999);
            if (!TSActionDone (actionp)) {
                TSContDataSet (contp, actionp);
            } else {
                /* We've already been called back ... */
            }
            break;

        case (TS_EVENT_TIMEOUT):
            TSAction actionp = TSContDataGet (contp);
            if (!TSActionDone(actionp)) {
                TSActionCancel (actionp);
            }
            break;

        case (TS_EVENT_NET_CONNECT):
            /* Net connection succeeded */
            TSContDataSet (contp, NULL);
            break;

        case (TS_EVENT_NET_CONNECT_FAILED):
            /* Net connection failed */
            TSContDataSet (contp, NULL);
            break;

    }
    return 0;
}

  void
TSPluginInit (int argc, const char *argv[])
{
    TSCont contp;

    contp = TSContCreate (handler, TSMutexCreate ());
    /* We don't want to call things out of TSPluginInit
       directly since it's called before the rest of the
       system is initialized. We'll simply schedule an event
       on the continuation to occur as soon as the rest of
       the system is started up. */
    TSContSchedule (contp, 0);
}

The action functions are:

IO Guide

This chapter contains the following sections:

Net Vconnections

A network vconnection (or** netvconnection**) is a wrapper around a TCP socket that enables the socket to work within the Traffic Server vconnection framework. See vconnections for more information about the Traffic Server abstraction for doing asynchronous IO.

The netvconnection functions are listed below:

  • [dox ‘TSNetAccept’] in [dox “TSNetAccept” :src_file]
  • [dox %TSNetConnect%] in [dox :src_file]
Transformations
The Vconnection Implementor’s View

A VConnection implementor writes only transformations. All other VConnections (net VConnections and cache VConnections) are implemented in iocore. As mentioned earlier, a given vconnection can have a maximum of one read operation and one write operation being performed on it. The vconnection user gets information about the operation being performed by examining the VIO returned by a call to TSVConnRead or TSVConnWrite. The implementor, in turn, gets a handle on the VIO operation by examining the VIO returned by TSVConnReadVIOGet or TSVConnWriteVIOGet (recall that every vconnection created through the Traffic Server API has an associated read VIO and write VIO, even if it only supports reading or writing).

For example, the null transform plugin’s transformation examines the input VIO by calling:

:::c
input_vio = TSVConnWriteVIOGet (contp);

where contp is the transformation.

A vconnection is a continuation. This means it has a handler function that is run when an event is sent to it, or more accurately, when an event that was sent to it is received. It is the handler function’s job to examine the event, the current state of its read VIO and write VIO, and any other internal state the vconnection might have and potentially make some progress on the IO operations.

It is common for the handler function for all vconnections to look similar. Their basic form looks something like the code fragment below:

    ::::c
int
vconnection_handler (TSCont contp, TSEvent event, void *edata)
{
if (TSVConnClosedGet (contp)) {
        /* Destroy any vconnection specific data here. */
        TSContDestroy (contp);
        return 0;
   } else {
        /* Handle the incoming event */
   }
}

This code fragment basically shows that many vconnections simply want to destroy themselves when they are closed. However, the situation might also require the vconnection to do some cleanup processing - which is why TSVConnClose does not simply just destroy the vconnection.

Vconnections are state machines that are animated by the events they receive. An event is sent to the vconnection whenever an TSVConnRead, TSVConnWrite, TSVConnClose, TSVConnShutdown, or TSVIOReenable call is performed. TSVIOReenable indirectly references the vconnection through a back-pointer in the VIO structure to the vconnection. The vconnection itself only knows which call was performed by examining its state and the state of its VIOs. For example, when TSVConnClose is called, the vconnection is sent an immediate event (TS_EVENT_IMMEDIATE). For every event the vconnection receives, it needs to check its closed flag to see if it has been closed. Similarly, when TSVIOReenable is called, the vconnection is sent an immediate event. For every event the vconnection receives, it must check its VIOs to see if the buffers have been modified to a state in which it can continue processing one of its operations.

Finally, a vconnection is likely the user of other vconnections. It also receives events as the user of these other vconnections. When it receives such an event, like TS_EVENT_VCONN_WRITE_READY, it might just enable another vconnection that’s writing into the buffer used by the vconnection reading from it. The above description is merely intended to give the overall idea for what a vconnection needs to do.

Transformation VConnection

A transformation is a specific type of vconnection. It supports a subset of the vconnection functionality that enables one or more transformations to be chained together. A transformation sits as a bottleneck between an input data source and an output data sink, which enables it to view and modify all the data passing through it. Alternatively, some transformations simply scan the data and pass it on. A common transformation is one that compresses data in some manner.

A transformation can modify either the data stream being sent to an HTTP client (e.g. the document) or the data stream being sent from an HTTP client (e.g. post data). To do this, the transformation should hook on to one of the following hooks:

  • TS_HTTP_REQUEST_TRANSFORM_HOOK
  • TS_HTTP_RESPONSE_TRANSFORM_HOOK

Note that because a transformation is intimately associated with a given transaction, it is only possible to add the hook to the transaction hooks - not to the global or session hooks. Transformations reside in a chain, so their ordering is quite easily determined: transformations that add themselves to the chain are simply appended to it.

Data is passed in to the transformation by initiating a vconnection write operation on the transformation. As a consequence of this design, a transformation must support the vconnection write operation. In other words, your transformation must expect an upstream vconnection to write data to it. The transformation has to read the data, consume it, and tell the upstream vconnection it is finished by sending it an TS_EVENT_WRITE_COMPLETE event. Transformations cannot send the TS_EVENT_VCONN_WRITE_COMPLETE event to the upstream vconnection unless they are finished consuming all incoming data. If TS_EVENT_VCONN_WRITE_COMPLETE is sent prematurely, then certain internal Traffic Server data structures will not be deallocated, thereby causing a memory leak.

Here’s how to make sure that all incoming data is consumed:

  • After reading or copying data, make sure that you consume the data and increase the value of ndone for the input VIO, as in the following example taken from null-transform.c:

            :::c
    TSIOBufferCopy (TSVIOBufferGet (data->output_vio),
    TSVIOReaderGet (input_vio), towrite, 0);
    /* Tell the read buffer that we have read the data and are no longer interested in it. */
    TSIOBufferReaderConsume (TSVIOReaderGet (input_vio), towrite);
    /* Modify the input VIO to reflect how much has been read.*/
    TSVIONDoneSet (input_vio, TSVIONDoneGet (input_vio) + towrite);
  • Before sending TS_EVENT_VCONN_WRITE_COMPLETE, your transformation should check the number of bytes remaining in the upstream vconnection’s write VIO (input VIO) using the function TSVIONTodoGet (input_vio). This value should go to zero when all of the upstream data is consumed (TSVIONTodoGet = nbytes - ndone). Do not send TS_EVENT_VCONN_WRITE_COMPLETE events if TSVIONTodoGet is greater than zero.

  • The transformation passes data out of itself by using the output vconnection retrieved by TSTransformOutputVConnGet. Immediately before Traffic Server initiates the write operation (which inputs data into the transformation), it sets the output vconnection either to the next transformation in the chain of transformations or to a special terminating transformation (if it’s the last transformation in the chain). Since the transformation is handed ownership of the output vconnection, it must close it at some point in order for it to be deallocated.

  • All of the transformations in a transformation chain share the transaction’s mutex. This small restriction (enforced by TSTransformCreate) removes many of the locking complications of implementing general vconnections. For example, a transformation does not have to grab its write VIO mutex before accessing its write VIO because it knows it already holds the mutex.

The transformation functions are: * `TSTransformCreate <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a54c4902bb537d3d40763bd947ed753b9>`__ * `TSTransformOutputVConnGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#ac6832718a2d9f2658409ad231811e1e3>`__

VIOs

A VIO, or virtual IO, is a description of an IO operation that’s currently in progress. The VIO data structure is used by vconnection users to determine how much progress has been made on a particular IO operation and to re-enable an IO operation when it stalls due to buffer space issues. VIOs are used by vconnection implementors to determine the buffer for an IO operation, how much work to do on the IO operation, and which continuation to call back when progress on the IO operation is made.

The TSVIO data structure itself is opaque, but it could be defined as follows:

    ::::c
typedef struct {
    TSCont continuation;
    TSVConn vconnection;
    TSIOBufferReader reader;
    TSMutex mutex;
    int nbytes;
    int ndone;
} *TSVIO;

The VIO functions below access and modify various parts of the data structure.

IO Buffers

The IO buffer data structure is the building block of the vconnection abstraction. An IO buffer (TSIOBuffer) is composed of a list of buffer blocks that point to buffer data. Both the buffer block (TSIOBufferBlock) and buffer data (TSIOBufferData) data structures are reference-counted, so they can reside in multiple buffers at the same time. This makes it extremely efficient to copy data from one IO buffer to another via TSIOBufferCopy, since Traffic Server must only copy pointers and adjust reference counts appropriately (and doesn’t actually copy any data).

The IO buffer abstraction provides for a single writer and multiple readers. In order for the readers to have no knowledge of each other, they manipulate IO buffers through the TSIOBufferReader data structure. Since only a single writer is allowed, there is no corresponding TSIOBufferWriter data structure. The writer simply modifies the IO buffer directly. To see an example that illustrates how to use IOBuffers, refer to the sample code in the description of `TSIOBufferBlockReadStart <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a367203e6e2cf4349e019952782deb96c>`__.

Additional information about IO buffer functions:

  • The TSIOBufferReader data structure tracks how much data in TSIOBuffer has been read. It has an offset number of bytes that is the current start point of a particular buffer reader (for every read operation on an TSIOBuffer, you must allocate an TSIOBufferReader).
  • Bytes that have already been read may not necessarily be freed within the TSIOBuffer. To consume bytes that have been read, you must call TSIOBufferConsume.
Guide to the Cache API
How to Do a Cache Write

Use TSCacheWrite to write to a cache (see the sample Protocol plugin). Possible callback events include:

  • TS_EVENT_CACHE_WRITE_READ - indicates the lookup was successful. The data passed back along with this event is a cache vconnection that can be used to initiate a cache write.
  • TS_EVENT_CACHE_OPEN_WRITE_FAILED - event returned when another continuation is currently writing to this location in the cache. Data payload for this event indicates the possible reason for the write failing (TSCacheError).
How to Do a Cache Remove

Use TSCacheRemove to remove items from the cache. Possible callback events include:

  • TS_EVENT_CACHE_REMOVE - the item was removed. There is no data payload for this event.
  • TS_EVENT_CACHE_REMOVE_FAILED - indicates the cache was unable to remove the item identified by the cache key. TSCacheError data indicates why the remove failed.
Errors

Errors pertaining to the failure of various cache operations are indicated by TSCacheError (enumeration). They are as follows:

  • TS_CACHE_ERROR_NO_DOC - the key does not match a cached resource
  • TS_CACHE_ERROR_DOC_BUSY - e.g, another continuation could be writing to the cache location
  • TS_CACHE_ERROR_NOT_READY - the cache is not ready
Example

In the example below, suppose there is a cache hit and the cache returns a vconnection that enables you to read the document from cache. To do this, you need to prepare a buffer (cache_bufp) to hold the document; meanwhile, use TSVConnCachedObjectSizeGet to find out the actual size of the document (content_length). Then, issue TSVConnRead to read the document with the total data length required as content_length. Assume the following data:

    ::::c
TSIOBuffer       cache_bufp = TSIOBufferCreate ();
TSIOBufferReader cache_readerp = TSIOBufferReaderAlloc (out_bufp);
TSVConn          cache_vconnp = NULL;
TSVIO            cache_vio = NULL;
int               content_length = 0;

In the TS_CACHE_OPEN_READ handler:

    ::::c
cache_vconnp = (TSVConn) data;
    TSVConnCachedObjectSizeGet (cache_vconnp, &content_length);
    cache_vio = TSVConnRead (cache_vconn, contp, cache_bufp, content_length);

In the TS_EVENT_VCONN_READ_READY handler:

    ::::c
(usual VCONN_READ_READY handler logic)
int nbytes = TSVIONBytesGet (cache_vio);
int ntodo  = TSVIONTodoGet (cache_vio);
int ndone  = TSVIONDoneGet (cache_vio);
(consume data in cache_bufp)
TSVIOReenable (cache_vio);

Do not try to get continuations or VIOs from TSVConn objects for cache vconnections. Also note that the following APIs can only be used on transformation vconnections and must not be used on cache vconnections or net vconnections:

  • TSVConnWriteVIOGet
  • TSVConnReadVIOGet
  • TSVConnClosedGet

APIs such as TSVConnRead, TSVConnWrite, TSVConnClose, TSVConnAbort, and TSVConnShutdown can be used on any kind of vconnections.

When you are finished:

TSCacheKeyDestroy (key);

The cache API enables plugins to read, write, and remove objects in the Traffic Server cache. All cache APIs are keyed by an object called an TSCacheKey; cache keys are created via TSCacheKeyCreate; keys are destroyed via TSCacheKeyDestroy. Use TSCacheKeyDigestSet to set the hash of the cache key.

Note that the cache APIs differentiate between HTTP data and plugin data. The cache APIs do not allow you to write HTTP docs in the cache; you can only write plugin-specific data (a specific type of data that differs from the HTTP type).

Example:

    :::c
const unsigned char *key_name = "example key name";

TSCacheKey key;
TSCacheKeyCreate (&key);
TSCacheKeyDigestSet (key, (unsigned char *) key_name , strlen(key_name));
TSCacheKeyDestroy (key);
How to Do a Cache Read

TSCacheRead does not really read - it is used for lookups (see the sample Protocol plugin). Possible callback events include:

  • TS_EVENT_CACHE_OPEN_READ - indicates the lookup was successful. The data passed back along with this event is a cache vconnection that can be used to initiate a read on this keyed data.
  • TS_EVENT_CACHE_OPEN_READ_FAILED - indicates the lookup was unsuccessful. Reasons for this event could be that another continuation is writing to that cache location, or the cache key doesn’t refer to a cached resource. Data payload for this event indicates the possible reason the read failed (TSCacheError).
Vconnections
Vconnections: a User’s Perspective

To use a vconnection, a user must first get a handle to one. This is usually accomplished by having it handed to the user; the user may also simply issue a call that creates a vconnection (such as TSNetConnect). In the case of transform plugins, the plugin creates a transformation vconnection viav TSTransformCreate and then accesses the output vconnection using TSTransformOutputVConnGet.

After getting a handle to a vconnection, the user can then issue a read or write call. It’s important to note that not all vconnections support both reading and writing - as of yet, there has not been a need to query a vconnection about whether it can perform a read or write operation. That ability should be obvious from context.

To issue a read or write operation, a user calls TSVConnRead or TSVConnWrite. These two operations both return VIO (TSVIO). The VIO describes the operation being performed and how much progress has been made. Transform plugins initiate output to the downstream vconnection by calling TSVConnWrite.

A vconnection read or write operation is different from a normal UNIX read(2) or write(2) operation. Specifically, the vconnection operation can specify more data to be read or written than exists in the buffer handed to the operation. For example, it’s typical to issue a read for INT64_MAX (9 quintillion) bytes from a network vconnection in order to read all the data from the network connection until the end of stream is reached. This contrasts with the usual UNIX fashion of issuing repeated calls to read(2) until one of the calls finally returns 0 to indicate the end of stream was reached (indeed, the underlying implementation of vconnections on UNIX still does issue those calls to read(2), but the interface does not expose that detail).

At most, a given vconnection can have one read operation and one write operation being performed on it. This is restricted both by design and common sense: if two write operations were performed on a single vconnection, then the user would not be able to specify which should occur first and the output would occur in an intermingled fashion. Note that both a read operation and a write operation can happen on a single vconnection at the same time; the restriction is for more than one operation of the same type.

One obvious issue is that the buffer passed to TSVConnRead and TSVConnWrite won’t be large enough - there is no reasonable way to make a buffer that can hold INT64_MAX (9 quintillion) bytes! The secret is that vconnections engage in a protocol whereby they signal to the user (via the continuation passed to TSVConnRead and TSVConnWrite) that they have emptied the buffers passed to them and are ready for more data. When this occurs, it is up to the user to add more data to the buffers (or wait for more data to be added) and then wake up the vconnection by calling TSVIOReenable on the VIO describing the operation. TSVIOReenable specifies that the buffer for the operation has been modified and that the vconnection should reexamine it to see if it can make further progress.

The null transform plugin provides an example of how this is done. Below is a prototype for TSVConnWrite:

::::c
TSVIO TSVConnWrite (TSVConn connp, TSCont contp, TSIOBufferReader readerp, int nbytes)

The connp is the vconnection the user is writing to and contp is the “user” - i.e., the continuation that connp calls back when it has emptied its buffer and is ready for more data.

The call made in the null transform plugin is:

:::c
TSVConnWrite (output_conn, contp, data->output_reader, TSVIONBytesGet (input_vio));

In the example above, contp is the transformation vconnection that is writing to the output vconnection. The number of bytes to be written is obtained from input_vio by TSVIONBytesGet.

When a vconnection calls back its user to indicate that it wants more data (or when some other condition has occurred), it issues a call to TSContCall. It passes the TSVIO describing the operation as the data parameter, and one of the values below as the event parameter.

TS_EVENT_ERROR
Indicates an error has occurred on the vconnection. This will happen for network IO if the underlying read(2) or write(2) call returns an error.
TS_EVENT_VCONN_READ_READY
The vconnection has placed data in the buffer passed to an TSVConnRead operation and it would like to do more IO, but the buffer is now full. When the user consumes the data from the buffer, this should re-enable the VIO so it indicates to the vconnection that the buffer has been modified.
TS_EVENT_VCONN_WRITE_READY
The vconnection has removed data from the buffer passed to an TSVConnWrite operation and it would like to do more IO, but the buffer does not have enough data in it. When placing more data in the buffer, the user should re-enable the VIO so it indicates to the vconnection that the buffer has been modified.
TS_EVENT_VCONN_READ_COMPLETE
The vconnection has read all the bytes specified by an TSVConnRead operation. The vconnection can now be used to initiate a new IO operation.
TS_EVENT_VCONN_WRITE_COMPLETE
The vconnection has written all the bytes specified by an TSVConnWrite operation and can now be used to initiate a new IO operation.
TS_EVENT_VCONN_EOS
An attempt was made to read past the end of the stream of bytes during the handling of an TSVConnRead operation. This event occurs when the number of bytes available for reading from a vconnection is less than the number of bytes the user specifies should be read from the vconnection in a call to TSVConnRead. A common case where this occurs is when the user specifies that INT64_MAX bytes are to be read from a network connection.

For example: the null transform plugin’s transformation receives TS_EVENT_VCONN_WRITE_READY and TS_EVENT_VCONN_WRITE_COMPLETE events from the downstream vconnection as a result of the call to TSVConnWrite.

After using a vconnection, the user must call TSVConnClose or TSVConnAbort. While both calls indicate that the vconnection can destroy itself, TSVConnAbort should be used when the connection is being closed abnormally. After a call to TSVConnClose or TSVConnAbort, the user will not be called back by the vconnection again.

Sometimes it’s desirable to simply close down the write portion of a connection while keeping the read portion open. This can be accomplished via the TSVConnShutdown function, which shuts down either the read or write portion of a vconnection. Shutdown means that the vconnection will no longer call back the user with events for the portion of the connection that was shut down. For example: if the user shuts down the write portion of a connection, then the TS_EVENT_VCONN_WRITE_READY or TS_EVENT_VCONN_WRITE_COMPLETE events will not be produced. In the null transform plugin, the write operation is shut down with a call to TSVConnShutdown. To learn how vconnections are used in transformation plugins, see Writing Content Transform Plugins.

The vconnection functions are listed below:

Plugin Management

This chapter covers the following topics:

Reading Traffic Server Settings and Statistics

Your plugin might need to know information about Traffic Server’s current configuration and performance. The functions described in this section read this information from the Traffic Server records.config file. Configuration settings are stored in CONFIG variables and statistics are stored in PROCESS variables.

警告

Not all CONFIG and PROCESS variables in records.config are relevant to Traffic Server’s configuration and statistics. Therefore, retrieve only the records.config variables that are documented in the Traffic Server Administrator’s Guide.

To retrieve a variable, you need to know its type (int, counter, float, or string). Plugins store the records.config values as an TSMgmtInt, TSMgmtCounter, TSMgmtFloat, or TSMgmtString. You can look up records.config variable types in the Traffic Server Administrator’s Guide.

Depending on the result type, you’ll use TSMgmtIntGet, TSMgmtCounterGet, TSMgmtFloatGet, or TSMgmtStringGet to obtain the variable value (see the example for `TSMgmtIntGet <http://people.apache.org/~amc/ats/doc/html/ts_8h.html#a097aaecda41d04b522796ae25eea9a3d>`__.

The TSMgmt*Get functions are:

Guide to the Logging API

The logging API enables your plugin to log entries in a custom text log file that you create with the call TSTextLogObjectCreate. This log file is part of Traffic Server’s logging system; by default, it is stored in the logging directory. Once you have created the log object, you can set log properties.

The logging API enables you to:

The steps below show how the logging API is used in the blacklist-1.c sample plugin. For the complete source code, see the *Sample Source Code* appendix.

  1. A new log file is defined as a global variable.

    ::::c
    static TSTextLogObject log;
  2. In TSPluginInit, a new log object is allocated:

    ::::c
    log = TSTextLogObjectCreate("blacklist", TS_LOG_MODE_ADD_TIMESTAMP, NULL, &error);

    The new log is named blacklist.log. Each entry written to the log will have a timestamp. The NULL argument specifies that the new log does not have a log header. The error argument stores the result of the log creation; if the log is created successfully, then an error will be equal to TS_LOG_ERROR_NO_ERROR.

  3. After creating the log, the plugin makes sure that the log was created successfully:

    ::::c
    if (!log) {
        printf("Blacklist plugin: error %d while creating log\n", error);
    }
  4. The blacklist-1 plugin matches the host portion of the URL (in each client request) with a list of blacklisted sites (stored in the array sites[]):

    ::::c for (i = 0; i < nsites; i++) { if (strncmp (host, sites[i], host_length) == 0) { If the host matches one of the blacklisted sites (such as sites[i]), then the plugin writes a blacklist entry to blacklist.log:

    ::::c if (log) { TSTextLogObjectWrite(log, “blacklisting site: %s”, sites[i]); The format of the log entry is as follows:

    :::text blacklisting site: sites[i] The log is not flushed or destroyed in the blacklist-1 plugin - it lives for the life of the plugin.

Adding Statistics

This chapter describes how to add statistics to your plugins. Statistics can be coupled or uncoupled; coupled statistics are quantities that are related and must therefore be updated together. The Traffic Server API statistics functions add your plugin’s statistics to the Traffic Server statistics system. You can view your plugin statistics as you would any other Traffic Server statistic, using Traffic Line (Traffic Server’s command line interface). This chapter contains the following topics:

Coupled Statistics

Use coupled statistics for quantities that are related and therefore must be updated jointly.

As a very simple example, suppose you have three statistics: sum, part_1, and part_2. They must always preserve the relationship that sum = part_1  + part_2. If you update part_1 without updating sum at the same time, then the equation becomes untrue. Therefore, the statistics are said to be coupled.

The mechanism for updating coupled statistics jointly is to create local copies of global coupled statistics in the routines that modifiy them. When each local copy is updated appropriately, do a global update using TSStatsCoupledUpdate. To specify which statistics are related to one another, establish a coupled statistic category and make sure that each coupled statistic belongs to the appropriate category. When it is time to do the global update, specify the category to be updated.

注解

The local statistic copy must have a duplicate set of statistics as that of the master copy. Local statistics must also be added to the local statistic category in the same order as their master copy counterparts were originally added.

Below are the steps you need to follow, along with a code example taken from the redirect-1.c sample plugin.

To add coupled statistics:
  1. Declare the global category for your coupled statistics as a global TSCoupledStat variable in your plugin.
  2. Declare your coupled statistics as global TSStat variables in your plugin.
  3. In TSPluginInit, create a new global coupled category using TSStatCoupledGlobalCategoryCreate.
  4. In TSPluginInit, create new global coupled statistics using TSStatCoupledGlobalAdd. When you create a new statistic, you need to give it an “external” name that the Traffic Server command line interface (Traffic Line) uses to access the statistic.
  5. In any routine wherein you want to modify (increment, decrement, or other modification) your coupled statistics, declare local copies of the coupled category and coupled statistics.
  6. Create local copies using TSStatCoupledLocalCopyCreate and TSStatCoupledLocalAdd.
  7. Modify the local copies of your statistics. Then call TSStatsCoupledUpdate to update the global copies jointly.
  8. When you are finished, you must destroy all of the local copies in the category via TSStatCoupledLocalCopyDestroy.
Example Using the redirect-1.c Sample Plugin
    :::c
static TSCoupledStat request_outcomes;

static TSStat requests_all;
static TSStat requests_redirects;
static TSStat requests_unchanged;

request_outcomes = TSStatCoupledGlobalCategoryCreate ("request_outcomes");

requests_all = TSStatCoupledGlobalAdd (request_outcomes, "requests.all", TSSTAT_TYPE_FLOAT);
requests_redirects = TSStatCoupledGlobalAdd (request_outcomes, "requests.redirects",
    TSSTAT_TYPE_INT64);
requests_unchanged = TSStatCoupledGlobalAdd (request_outcomes, "requests.unchanged",
    TSSTAT_TYPE_INT64);

TSCoupledStat local_request_outcomes;
TSStat local_requests_all;
TSStat local_requests_redirects;
TSStat local_requests_unchanged;

local_request_outcomes = TSStatCoupledLocalCopyCreate("local_request_outcomes",
    request_outcomes);
local_requests_all = TSStatCoupledLocalAdd(local_request_outcomes, "requests.all.local",
    TSSTAT_TYPE_FLOAT);
local_requests_redirects = TSStatCoupledLocalAdd(local_request_outcomes,
    "requests.redirects.local", TSSTAT_TYPE_INT64);
local_requests_unchanged = TSStatCoupledLocalAdd(local_request_outcomes,
    "requests.unchanged.local", TSSTAT_TYPE_INT64);

TSStatFloatAddTo( local_requests_all, 1.0 ) ;
...
TSStatIncrement (local_requests_unchanged);
TSStatsCoupledUpdate(local_request_outcomes);

TSStatCoupledLocalCopyDestroy(local_request_outcomes);
Viewing Statistics Using Traffic Line

To view statistics for your plugin, follow the steps below:

  1. Make sure you know the name of your statistic (i.e., the name used in the TSStatCoupledGlobalAdd, TSStatCreate, or TSStatCoupledGlobalCategoryCreate call).

  2. In your <Traffic Server>/bin directory, enter the following:

    ::::text ./traffic_line -r the_name

Uncoupled Statistics

A statistic is an object of type TSStat. The value of the statistic is of type TSStatType. The possible TSStatTypes are:

  • TSSTAT_TYPE_INT64
  • TSSTAT_TYPE_FLOAT

There is no TSSTAT_TYPE_INT32.

To add uncoupled statistics, follow the steps below:

  1. Declare your statistic as a global variable in your plugin. For example:

    static TSStat my_statistic;
    
  2. In TSPluginInit, create new statistics using TSStatCreate. When you create a new statistic, you need to give it an “external” name that the Traffic Server command line interface (Traffic Line) uses to access the statistic. For example:

    my_statistic = TSStatCreate ("my.statistic", TSSTAT_TYPE_INT64);
    
  3. Modify (increment, decrement, or other modification) your statistic in plugin functions.

Sample Source Code

This appendix provides several source code examples. In the online formats of this book, function calls are linked to their references in the previous chapters. The following sample plugins are provided:

blacklist-1.c

The sample blacklisting plugin included in the Traffic Server SDK is blacklist-1.c. This plugin checks every incoming HTTP client request against a list of blacklisted web sites. If the client requests a blacklisted site, then the plugin returns an Access forbidden message to the client.

This plugin illustrates:

  • An HTTP transaction extension
  • How to examine HTTP request headers
  • How to use the logging interface
  • How to use the plugin configuration management interface
    /* blacklist-1.c:  An example program that denies client access
     *                 to blacklisted sites. This plugin illustrates
     *                 how to use configuration information from the
     *                 blacklist.txt configuration file.
     *
     * Usage:
     * (Solaris) : blacklist-1.so
     *
     *
     */

    #include 
    #include 
    #include 

    #define MAX_NSITES 500

    static char* sites[MAX_NSITES];
    static int nsites;
    static TSMutex sites_mutex;
    static TSTextLogObject log;

    static void
    handle_dns (TSHttpTxn txnp, TSCont contp)
    {
        TSMBuffer bufp;
        TSMLoc hdr_loc;
        TSMLoc url_loc;
        const char *host;
        int i;
        int host_length;

        if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
            TSError ("couldn't retrieve client request header\n");
            goto done;
        }

        url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
        if (!url_loc) {
            TSError ("couldn't retrieve request url\n");
            TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
            goto done;
        }

        host = TSUrlHostGet (bufp, url_loc, &host_length);
        if (!host) {
            TSError ("couldn't retrieve request hostname\n");
            TSHandleMLocRelease (bufp, hdr_loc, url_loc);
            TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
            goto done;
        }

        TSMutexLock(sites_mutex);

        for (i = 0; i < nsites; i++) {
            if (strncmp (host, sites[i], host_length) == 0) {
                if (log) {
                    TSTextLogObjectWrite(log, "blacklisting site: %s", sites[i]);
                } else {
                    printf ("blacklisting site: %s\n", sites[i]);
                }
                TSHttpTxnHookAdd (txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
                TSHandleMLocRelease (bufp, hdr_loc, url_loc);
                TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
                TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
                TSMutexUnlock(sites_mutex);
                return;
            }
        }

        TSMutexUnlock(sites_mutex);
        TSHandleMLocRelease (bufp, hdr_loc, url_loc);
        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);

     done:
        TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
    }

    static void
    handle_response (TSHttpTxn txnp)
    {
        TSMBuffer bufp;
        TSMLoc hdr_loc;
        TSMLoc url_loc;
        char *url_str;
        char *buf;
        int url_length;

        if (!TSHttpTxnClientRespGet (txnp, &bufp, &hdr_loc)) {
            TSError ("couldn't retrieve client response header\n");
            goto done;
        }

        TSHttpHdrStatusSet (bufp, hdr_loc, TS_HTTP_STATUS_FORBIDDEN);
        TSHttpHdrReasonSet (bufp, hdr_loc,
            TSHttpHdrReasonLookup (TS_HTTP_STATUS_FORBIDDEN),
            strlen (TSHttpHdrReasonLookup (TS_HTTP_STATUS_FORBIDDEN)) );

        if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
            TSError ("couldn't retrieve client request header\n");
            TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
            goto done;
        }

        url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
        if (!url_loc) {
            TSError ("couldn't retrieve request url\n");
            TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
            goto done;
        }

        buf = (char *)TSmalloc (4096);

        url_str = TSUrlStringGet (bufp, url_loc, &url_length);
        sprintf (buf, "You are forbidden from accessing \"%s\"\n", url_str);
        TSfree (url_str);
        TSHandleMLocRelease (bufp, hdr_loc, url_loc);
        TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);

        TSHttpTxnErrorBodySet (txnp, buf, strlen (buf), NULL);

     done:
        TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
    }

    static void
    read_blacklist (void)
    {
        char blacklist_file[1024];
        TSFile file;

        sprintf (blacklist_file, "%s/blacklist.txt", TSPluginDirGet());
        file = TSfopen(blacklist_file, "r");

        TSMutexLock (sites_mutex);
        nsites = 0;

        if (file != NULL) {
            char buffer[1024];

            while (TSfgets (file, buffer, sizeof(buffer)-1) != NULL && nsites < MAX_NSITES) {
                char* eol;
                if ((eol = strstr(buffer, "\r\n")) != NULL) {
                    /* To handle newlines on Windows */
                    *eol = '\0';
                } else if ((eol = strchr(buffer, '\n')) != NULL) {
                    *eol = '\0';
                } else {
                    /* Not a valid line, skip it */
                    continue;
               }
               if (sites[nsites] != NULL) {
                    TSfree (sites[nsites]);
               }
               sites[nsites] = TSstrdup (buffer);
               nsites++;
           }

            TSfclose (file);
        } else {
           TSError ("unable to open %s\n", blacklist_file);
           TSError ("all sites will be allowed\n", blacklist_file);
        }

        TSMutexUnlock (sites_mutex);
    }

    static int
    blacklist_plugin (TSCont contp, TSEvent event, void *edata)
    {
        TSHttpTxn txnp = (TSHttpTxn) edata;

        switch (event) {
        case TS_EVENT_HTTP_OS_DNS:
            handle_dns (txnp, contp);
            return 0;
        case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
            handle_response (txnp);
            return 0;
        case TS_EVENT_MGMT_UPDATE:
            read_blacklist ();
            return 0;
        default:
            break;
        }
        return 0;
    }

    int
    check_ts_version()
    {

       const char *ts_version = TSTrafficServerVersionGet();
       int result = 0;

       if (ts_version) {
           int major_ts_version = 0;
           int minor_ts_version = 0;
           int patch_ts_version = 0;

           if (sscanf(ts_version, "%d.%d.%d", &major_ts_version, &minor_ts_version, &patch_ts_version) != 3) {
                return 0;
           }

           /* Need at least TS 2.0 */
           if (major_ts_version >= 2) {
                result = 1;
           }

       }

       return result;
    }

    void
    TSPluginInit (int argc, const char *argv[])
    {
        int i;
        TSCont contp;
        TSPluginRegistrationInfo info;
        int error;

        info.plugin_name = "blacklist-1";
        info.vendor_name = "DsCompany";
        info.support_email = "ts-api-support@DsCompany.com";

        if (!TSPluginRegister (TS_SDK_VERSION_2_0 , &info)) {
            TSError ("Plugin registration failed.\n");
        }

        if (!check_ts_version()) {
           TSError ("Plugin requires Traffic Server 2.0 or later\n");
           return;
        }

        /* create an TSTextLogObject to log blacklisted requests to */
        log = TSTextLogObjectCreate("blacklist", TS_LOG_MODE_ADD_TIMESTAMP,
                 NULL, &error);
        if (!log) {
            printf("Blacklist plugin: error %d while creating log\n", error);
        }

        sites_mutex = TSMutexCreate ();

        nsites = 0;
        for (i = 0; i < MAX_NSITES; i++) {
            sites[i] = NULL;
        }

        read_blacklist ();

        contp = TSContCreate (blacklist_plugin, NULL);

        TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, contp);

        TSMgmtUpdateRegister (contp, "Super Blacklist Plugin", "blacklist.cgi");
    }

Troubleshooting Tips

This appendix lists the following troubleshooting tips.

Unable to Load Plugins

To load plugins, follow the steps below.

  1. Make sure that your plugin source code contains an TSPluginInit initialization function.
  2. Compile your plugin source code, creating a shared library.
  3. Add an entry to the plugin.config file for your plugin.
  4. Add the path to your plugin shared library to the records.config file.
  5. Restart Traffic Server.

For detailed information about each step above, refer to A Simple Plugin.

Using Debug Tags

Use the API void TSDebug (const char *tag, const char *format_str, ...) to add traces in your plugin. In this API:

  • tag is the Traffic Server parameter that enables Traffic Server to print out ``format_str``
  • ... are variables for ``format_str`` in the standard printf style.

Run Traffic Server with the -Ttag option. For example, if the tag is my-plugin, then the debug output goes to traffic.out.See below:

:::text
traffic_server -T"my-plugin"

Set the following variables in records.config (in the Traffic Server config directory):

:::text
CONFIG proxy.config.diags.debug.enabled INT 1
CONFIG proxy.config.diags.debug.tags STRING debug-tag-name

In this case, debug output goes to traffic.out.

Example:

:::c
TSDebug ("my-plugin", "Starting my-plugin at %d\n", the_time);

The statement "Starting my-plugin at <time>" appears whenever you run Traffic Server with the my-plugin tag:

:::text
traffic_server -T"my-plugin"
Other Useful Internal Debug Tags

Embedded in the base Traffic Server code are many debug tags for internal debugging purposes. These can also be used to follow Traffic Server behavior for testing and analysis.

The debug tag setting (-T and proxy.config.diag.debug.tags) is a anchored regular expression against which the tag for a specific debug message is matched. This means the value “http” matches debug emssages with the tag “http” but also “http_seq” and “http_trans”. If you want multiple tags then use a pipe symbol to separate the tags. For example “http_tproxy|dns|hostdb” will match any of the message tags “http_tproxy”, “dns”, “hostdb”, or “dns_srv” (but not “http_trans” nor “splitdns”).

Some of the useful HTTP debug tags are:

  • http_hdrs - traces all incoming and outgoing HTTP headers.
  • http_trans - traces actions in an HTTP transaction.
  • http_seq - traces the sequence of the HTTP state machine.
  • http_tproxy - transparency related HTTP events
  • dns - DNS operations
  • hostdb - Host name lookup
  • iocore_net - Socket and low level IO (very voluminous)
  • socket - socket operations
  • ssl - SSL related events
  • cache - Cache operations (many subtags, examine the output to narrow the tag set)
  • cache_update - Cache updates including writes
  • cache_read - Cache read events.
  • dir_probe - Cache searches.
  • sdk - gives some warning concerning API usage.
Using a Debugger

A debugger can set breakpoints in a plugin. Use a Traffic Server debug build and compile the plugin with the -g option. A debugger can also be used to analyze a core dump. To generate core, set the size limit of the core files in the records.config file to -1 as follows:

:::c
CONFIG proxy.config.core_limit INT -1

This is the equivalent of setting ulimit -c unlimited

Debugging Tips:
  • Use a Traffic Server debug version.
  • Use assertions in your plugin (TSAssert/TSReleaseAssert).
Debugging Memory Leaks

Memory leaks in a plugin can be detected using e.g. an MRTG graph related to memory - you can use memory dump information. Enable mem dump in records.config as follows:

:::text
CONFIG proxy.config.dump_mem_info_frequency INT <value>

This causes Traffic Server to dump memory information to traffic.out at <value> (intervals are in seconds). A zero value means that it is disabled.

Unable to Compile Plugins

The process for compiling a shared library varies with the platform used, so the Traffic Server API includes the tsxs script you can use to create shared libraries on all supported Traffic Server platforms.

Example

Assuming the sample program is stored in the file hello-world.c, you could use the following commands to building a shared library:

:::text
tsxs -c hello-world.c -o hello-world.so

To install this plugin in your plugindir use the equivalent of sudo on your platform to execute:

:::text
sudo tsxs -o hello-world.so -i

Configuration File Reference

cache.config

The cache.config file (by default, located in /opt/trafficserver/etc/trafficserver/) defines how Traffic Server caches web objects. You can add caching rules to specify the following:

  • Not to cache objects from specific IP addresses
  • How long to pin particular objects in the cache
  • How long to consider cached objects as fresh
  • Whether to ignore no-cache directives from the server

重要

After you modify the cache.config file, navigate to the Traffic Server bin directory; then run the traffic_line -x command to apply changes. When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the cache.config file contains a caching rule. Traffic Server recognizes three space-delimited tags:

primary_destination=value secondary_specifier=value action=value

You can use more than one secondary specifier in a rule. However, you cannot repeat a secondary specifier. The following list shows the possible primary destinations with allowed values.

dest_domain
A requested domain name. Traffic Server matches the domain name of the destination from the URL in the request.
dest_host
A requested hostname. Traffic Server matches the hostname of the destination from the URL in the request.
dest_ip
A requested IP address. Traffic Server matches the IP address of the destination in the request.
url_regex
A regular expression (regex) to be found in a URL.

The secondary specifiers are optional in the cache.config file. The following list shows possible secondary specifiers with allowed values.

port
A requested URL port.
scheme
A request URL protocol: http or https.
prefix
A prefix in the path part of a URL.
suffix
A file suffix in the URL.
method
A request URL method: get, put, post, trace.
time
A time range, such as 08:00-14:00.
src_ip
A client IP address.

The following list shows possible actions and their allowed values.

action

One of the following values:

  • never-cache configures Traffic Server to never cache specified objects.
  • ignore-no-cache configures Traffic Server to ignore all Cache-Control: no-cache headers.
  • ignore-client-no-cache configures Traffic Server to ignore Cache-Control: no-cache headers from client requests.
  • ignore-server-no-cache configures Traffic Server to ignore Cache-Control: no-cache headers from origin server responses.
  • cluster-cache-local configures the cluster cache to allow for this content to be stored locally on every cluster node.
cache-responses-to-cookies
Change the style of caching with regard to cookies. This effectively overrides the configuration parameter proxy.config.http.cache.cache_responses_to_cookies and uses the same values with the same semantics. The override happens only for requests that match.
pin-in-cache

Preserves objects in cache, preventing them from being overwritten. Does not affect objects that are determined not to be cacheable. This setting can have performance issues, and severely affect the cache. For instance, if the primary destination matches all objects, once the cache is full, no new objects could get written as nothing would be evicted. Similarly, for each cache-miss, each object would incur extra checks to determine if the object it would replace could be overwritten.

The value is the amount of time you want to keep the object(s) in the cache. The following time formats are allowed:

  • d for days; for example: 2d
  • h for hours; for example: 10h
  • m for minutes; for example: 5m
  • s for seconds; for example: 20s
  • mixed units; for example: 1h15m20s
revalidate
For objects that are in cache, overrides the the amount of time the object(s) are to be considered fresh. Use the same time formats as pin-in-cache.
ttl-in-cache
Forces object(s) to become cached, as if they had a Cache-Control: max-age:<time> header. Can be overruled by requests with cookies. The value is the amount of time object(s) are to be kept in the cache, regardless of Cache-Control response headers. Use the same time formats as pin-in-cache and revalidate.
Examples

The following example configures Traffic Server to revalidate gif and jpeg objects in the domain mydomain.com every 6 hours, and all other objects in mydomain.com every hour. The rules are applied in the order listed.

dest_domain=mydomain.com suffix=gif revalidate=6h
dest_domain=mydomain.com suffix=jpeg revalidate=6h
dest_domain=mydomain.com revalidate=1h

Force a specific regex to be in cache between 7-11pm of the server’s time for 26hours.

url_regex=example.com/articles/popular.* time=19:00-23:00 ttl-in-cache=1d2h

Prevent objects from being evicted from cache:

url_regex=example.com/game/.* pin-in-cache=1h

congestion.config

The congestion.config file (by default, located in /opt/trafficserver/etc/trafficserver/) enables you to configure Traffic Server to stop forwarding HTTP requests to origin servers when they become congested, and then send the client a message to retry the congested origin server later. After you modify the congestion.config file, navigate to the Traffic Server bin directory; then run the traffic_line -x command to apply changes. When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster. Traffic Server uses the congestion.config file only if you enable the Congestion Control option.

You can create rules in the congestion.config file to specify:

  • Which origin servers Traffic Server tracks for congestion.
  • The timeouts Traffic Server uses, depending on whether a server is congested.
  • The page Traffic Server sends to the client when a server becomes congested.
  • If Traffic Server tracks the origin servers per IP address or per hostname.
Format

Each line in congestion.config must follow the format below. Traffic Server applies the rules in the order listed, starting at the top of the file. Traffic Server recognizes three space-delimited tags:

primary_destination=value secondary_specifier=value action=value

The following list shows possible primary destinations with allowed values.

``dest_domain`` {#dest_domain}
A requested domain name.
``dest_host`` {#dest_host}
A requested hostname.
``dest_ip`` {#dest_ip}
A requested IP address.
``url_regex`` {#url_regex}
A regular expression (regex) to be found in a URL.

The secondary specifiers are optional in the congestion.config file. The following list shows possible secondary specifiers with allowed values. You can use more than one secondary specifier in a rule; however, you cannot repeat a secondary specifier.

``port`` {#port}
A requested URL port or range of ports.
``prefix`` {#prefix}
A prefix in the path part of a URL.

The following list shows the possible tags and their allowed values.

``max_connection_failures`` {#max_connection_failures}
Default: 5 The maximum number of connection failures allowed within the fail window described below before Traffic Server marks the origin server as congested.
``fail_window`` {#fail_window}
Default: 120 seconds. The time period during which the maximum number of connection failures can occur before Traffic Server marks the origin server as congested.
``proxy_retry_interval`` {#proxy_retry_interval}
Default: 10 seconds. The number of seconds that Traffic Server waits before contacting a congested origin server again.
``client_wait_interval`` {#client_wait_interval}
Default: 300 seconds. The number of seconds that the client is advised to wait before retrying the congested origin server.
``wait_interval_alpha`` {#wait_interval_alpha}
Default: 30 seconds The upper limit for a random number that is added to the wait interval.
``live_os_conn_timeout`` {#live_os_conn_timeout}
Default: 60 seconds. The connection timeout to the live (uncongested) origin server. If a client stops a request before the timeout occurs, then Traffic Server does not record a connection failure.
``live_os_conn_retries`` {#live_os_conn_retries}
Default: 2 The maximum number of retries allowed to the live (uncongested) origin server.
``dead_os_conn_timeout`` {#dead_os_conn_timeout}
Default: 15 seconds. The connection timeout to the congested origin server.
``dead_os_conn_retries`` {#dead_os_conn_retries}
Default: 1 The maximum number of retries allowed to the congested origin server.
``max_connection`` {#max_connection}
Default: -1 The maximum number of connections allowed from Traffic Server to the origin server.
``error_page`` {#error_page}
Default: "congestion#retryAfter" The error page sent to the client when a server is congested. You must enclose the value in quotes;
:file:`congestion.config` {#congestion_scheme}

Default: "per_ip" Specifies if Traffic Server applies the rule on a per-host ("per_host") or per-IP basis ("per_ip"). You must enclose the value in quotes.

For example: if the server www.host1.com has two IP addresses and you use the tag value "per_ip", then each IP address has its own number of connection failures and is marked as congested independently. If you use the tag value "per_host" and the server www.host1.com is marked as congested, then both IP addresses are marked as congested.

Examples

The following congestion.config rule configures Traffic Server to stop forwarding requests to the server www.host.com on port 80 (HTTP traffic) if the server is congested, according to the timeouts specified. Traffic Server uses the default tag values because no tag has been specified.

dest_host=www.host.com port=80

You can use one or more tags in a rule, but each tag must have one value only. If you specify no tags in the rule, then Traffic Server uses the default values.

You can override any of the default tag values by adding configuration variables at the end of records.config as follows:

CONFIG proxy.config.http.congestion_control.default.tag INT|STRING value

where tag is one of the tags described in the list under congestion.config and value is the value you want to use.

For example:

CONFIG proxy.config.http.congestion_control.default.congestion_scheme STRING per_host

重要

Rules in the congestion.config file override the following variables in the records.config file:

proxy.config.http.connect_attempts_max_retries
proxy.config.http.connect_attempts_max_retries_dead_server
proxy.config.http.connect_attempts_rr_retries
proxy.config.http.connect_attempts_timeout
proxy.config.http.down_server.cache_time
proxy.config.http.down_server.abort_threshold

hosting.config

The hosting.config file (by default, located in /opt/trafficserver/etc/trafficserver/) you to assign cache partitions to specific origin servers and/or domains so that you can manage cache space efficiently and restrict disk usage. For step-by-step instructions on partitioning the cache according to origin servers and/or domains, refer to Partitioning the Cache.

Before you can assign cache partitions to specific origin servers and/or domains, you must first partition your cache according to size and protocol in the volume.config file.

After you modify hosting.config, navigate to the Traffic Server bin directory and run traffic_line -x to apply your changes.

When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

重要

The volume.config configuration must be the same on all nodes in a cluster.

Format

Each line in the hosting.config file must have one of the following formats:

hostname=HOST partition=NUMBERS
domain=DOMAIN partition=NUMBERS

where HOST is the fully-qualified hostname of the origin server whose content you want to store on a particular partition (for example, www.myhost.com); DOMAIN is the domain whose content you want to store on a particular partition(for example, mydomain.com); and NUMBERS is a comma-separated list of the partitions on which you want to store the content that belongs to the origin server or domain listed. The partition numbers must be valid numbers listed in the file:volume.config.

Note: To allocate more than one partition to an origin server or domain, you must enter the partitions in a comma-separated list on one line, as shown in the example below. The hosting.config file cannot contain multiple entries for the same origin server or domain.

Generic Partition

When configuring the hosting.config file, you must assign a generic partition to use for content that does not belong to any of the origin servers or domains listed. If all partitions for a particular origin server become corrupt, Traffic Server will also use the generic partition to store content for that origin server.

The generic partition must have the following format:

hostname=* partition=NUMBERS

where NUMBERS is a comma-separated list of generic partitions.

Examples

The following example configures Traffic Server to store content from the domain mydomain.com in partition 1 and content from www.myhost.com in partition 2. Traffic Server stores content from all other origin servers in partitions 3 and 4.

domain=mydomain.com partition=1
hostname=www.myhost.com partition=2
hostname=* partition=3,4

icp.config

警告

The Traffic Server ICP feature is not functional in this release.

The icp.config file defines ICP peers (parent and sibling caches).

重要

After you modify the icp.config file, navigate to the Traffic Server bin directory and run the traffic_line -x command to apply the changes. When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the icp.config file contains the name and configuration information for a single ICP peer in the following format:

host : host_IP : peer_type : proxy_port : icp_port : MC_on : MC_IP : MC_TTL :

Each field is described in the following list.

``host`` {#host}

The hostname of the ICP peer.

This field is optional; if you do not specify the hostname of the ICP peer, you must specify the IP address.

``host_IP`` {#host_IP}

The IP address of the ICP peer.

This field is optional; if you do not specify the IP address of the ICP peer, you must specify the hostname.

``ctype`` {#ctype}

Use the following options:

  • 1 to indicate an ICP parent cache
  • 2 to indicate an ICP sibling cache
``proxy_port`` {#proxy_port}
The port number of the TCP port used by the ICP peer for proxy communication.
``icp_port`` {#icp_port}
The port number of the UDP port used by the ICP peer for ICP communication.
``MC_on`` {#mc_on}

Enable or disable MultiCast:

  • 0 if multicast is disabled
  • 1 if multicast is enabled
``MC_ip`` {#mc_ip}
The MultiCast IP address.
``MC_ttl`` {#mc_ttl}

The multicast time to live. Use the following options:

  • 1 if IP multicast datagrams will not be forwarded beyond a single subnetwork
  • 2 to allow delivery of IP multicast datagrams to more than one subnet (if there are one or more multicast routers attached to the first hop subnet).
Examples

The following example configuration is for three nodes: the local host, one parent, and one sibling.

:::text
localhost:0.0.0.0:3:8080:3130:0:0.0.0.0:1
host1:123.12.1.23:1:8080:3131:0:0.0.0.0:1
host2:123.12.1.24:2:8080:3131:0:0.0.0.0:1

ip_allow.config

The ip_allow.config file controls client access to the Traffic Server proxy cache. You can specify ranges of IP addresses that are allowed to use the Traffic Server as a web proxy cache. After you modify the ip_allow.config file, navigate to the Traffic Server bin directory and run the traffic_line -x command to apply changes. When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the ip_allow.config file must have the following format:

src_ip=<range of IP addresses> action=<action> [method=<list of methods separated by '|'>]

where src_ip is the IP address or range of IP addresses of the client(s). The action ip_allow enables the specified client(s) to access the Traffic Server proxy cache, and ip_deny denies the specified client(s) to access the Traffic Server proxy cache. Multiple method keywords can be specified (method=GET method=HEAD), or multiple methods can be separated by an ‘|’ (method=GET|HEAD). The method keyword is optional and it is defaulted to ALL. Available methods: ALL, GET, CONNECT, DELETE, HEAD, ICP_QUERY, OPTIONS, POST, PURGE, PUT, TRACE, PUSH

By default, the ip_allow.config file contains the following lines, which allows all methods to localhost to access the Traffic Server proxy cache and denies PUSH, PURGE and DELETE to all IPs (note this allows all other methods to all IPs):

src_ip=127.0.0.1                                  action=ip_allow method=ALL
src_ip=::1                                        action=ip_allow method=ALL
src_ip=0.0.0.0-255.255.255.255                    action=ip_deny  method=PUSH|PURGE|DELETE
src_ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff action=ip_deny  method=PUSH|PURGE|DELETE
Examples

The following example enables all clients to access the Traffic Server proxy cache:

src_ip=0.0.0.0-255.255.255.255 action=ip_allow

The following example allows all clients on a specific subnet to access the Traffic Server proxy cache:

src_ip=123.12.3.000-123.12.3.123 action=ip_allow

The following example denies all clients on a specific subnet to access the Traffic Server proxy cache:

src_ip=123.45.6.0-123.45.6.123 action=ip_deny

log_hosts.config

To record HTTP transactions for different origin servers in separate log files, you must list each origin server hostname in the log_hosts.config file. In addition, you must enable the HTTP Host Log Splitting option. You should use the same log_hosts.config file on every Traffic Server node in your cluster. After you modify the log_hosts.config file, run the traffic_line -x command to apply the changes. When you apply the changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the log_hosts.config file has the following format:

hostname

where hostname is the hostname of the origin server.

提示

You can specify keywords in the log_hosts.config file to record all transactions from origin servers with the specified keyword in their names in a separate log file. See the example below.

Examples

The following example configures Traffic Server to create separate log files containing all HTTP transactions for the origin servers webserver1, webserver2, and webserver3:

webserver1
webserver2
webserver3

The following example records all HTTP transactions from origin servers that contain sports in their names. For example: sports.yahoo.com and www.foxsports.com in a log file called squid-sport.log (the Squid format is enabled):

sports

logs_xml.config

The logs_xml.config file defines the custom log file formats, filters, and processing options. The format of this file is modeled after XML, the Extensible Markup Language.

Format

The logs_xml.config file contains the specifications below:

  • LogFormat specifies the fields to be gathered from each protocol event access.
  • LogFilter specifies the filters that are used to include or exclude certain entries being logged based on the value of a field within that entry.
  • LogObject specifies an object that contains a particular format, a local filename, filters, and collation servers.

The logs_xml.config file ignores extra white space, blank lines, and all comments.

LogFormat

The following list shows LogFormat specifications.

<Name = "valid_format_name"/>
Required Valid format names include any name except squid, common, extended, or extended2, which are pre-defined formats. There is no default for this tag.
<Format = "valid_format_specification"/>

Required A valid format specification is a printf-style string describing each log entry when formatted for ASCII output.

The printf-style could accept Oct/Hex escape representation:

  • \abc is Oct escape sequence, a,b,c should be one of [0-9], and (a*8^2 + b*8 + c) should be greater than 0 and less than 255.
  • \xab is Hex escape sequence, a,b should be one of [0-9, a-f, A-F], and (a*16 + b) should be greater than 0 and less than 255.

Use %< field > as a placeholder for valid field names. For more information, refer to Custom Logging Fields.

The specified field can be one of the following types:

Simple. For example: %<cqu> A field within a container, such as an HTTP header or a statistic. Fields of this type have the syntax:

%<{ field } container>

Aggregates, such as COUNT, SUM, AVG, FIRST, LAST. Fields of this type have the syntax: %<operator ( field )>

注解

You cannot create a format specification that contains both aggregate operators and regular fields.

<Interval = "aggregate_interval_secs"/>

Optional Use this tag when the format contains aggregate operators. The value “aggregate_interval_secs” represents the number of seconds between individual aggregate values being produced.

The valid set of aggregate operators are:

  • COUNT
  • SUM
  • AVG
  • FIRST
  • LAST
LogFilters

The following list shows the LogFilter specifications.

<Name = "valid_filter_name"/>
Required All filters must be uniquely named.
<Condition = "valid_log_field valid_operator valid_comparison_value"/>

Required This field contains the following elements:

valid_log_field - the field that will be compared against the given value. For more information, refer to Logging Format Cross-Reference.

valid_operator_field - any one of the following: MATCH, CASE_INSENSITIVE_MATCH, CONTAIN, CASE_INSENSITIVE_CONTAIN.

  • MATCH is true if the field and value are identical (case-sensitive).
  • CASE_INSENSITIVE_MATCH is similar to MATCH, except that it is case-insensitive.
  • CONTAIN is true if the field contains the value (the value is a substring of the field).
  • CASE_INSENSITIVE_CONTAIN is a case-insensitive version of CONTAIN.

valid_comparison_value - any string or integer matching the field type. For integer values, all of the operators are equivalent and mean that the field must be equal to the specified value.

注解

There are no negative comparison operators. If you want to specify a negative condition, then use the Action field to REJECT the record.

<Action = "valid_action_field"/>
Required: ACCEPT or REJECT . This instructs Traffic Server to either accept or reject records that satisfy the filter condition.
LogObject

The following list shows the LogObject specifications.

<Format = "valid_format_name"/>
Required Valid format names include the predefined logging formats: squid, common, extended, and extended2, as well as any previously-defined custom log formats. There is no default for this tag.
<Filename = "file_name"/>

Required The filename to which the given log file is written on the local file system or on a remote collation server. No local log file will be created if you fail to specify this tag. All filenames are relative to the default logging directory.

If the name does not contain an extension (for example, squid), then the extension .log is automatically appended to it for ASCII logs and .blog for binary logs (refer to Mode = “valid_logging_mode”).

If you do not want an extension to be added, then end the filename with a single (.) dot (for example: squid. ).

<Mode = "valid_logging_mode"/>

Optional Valid logging modes include ascii , binary , and ascii_pipe . The default is ascii .

  • Use ascii to create event log files in human-readable form (plain ASCII).
  • Use binary to create event log files in binary format. Binary log files generate lower system overhead and occupy less space on the disk (depending on the information being logged). You must use the traffic_logcat utility to translate binary log files to ASCII format before you can read them.
  • Use ascii_pipe to write log entries to a UNIX named pipe (a buffer in memory). Other processes can then read the data using standard I/O functions. The advantage of using this option is that Traffic Server does not have to write to disk, which frees disk space and bandwidth for other tasks. In addition, writing to a pipe does not stop when logging space is exhausted because the pipe does not use disk space.

If you are using a collation server, then the log is written to a pipe on the collation server. A local pipe is created even before a transaction is processed, so you can see the pipe right after Traffic Server starts. Pipes on a collation server, however, are created when Traffic Server starts.

<Filters = "list_of_valid_filter_names"/>
Optional A comma-separated list of names of any previously-defined log filters. If more than one filter is specified, then all filters must accept a record for the record to be logged.
<Protocols = "list_of_valid_protocols"/>
Optional A comma-separated list of the protocols this object should log. Valid protocol names for this release are HTTP (FTP is deprecated).
<ServerHosts = "list_of_valid_servers"/>
Optional A comma-separated list of valid hostnames.This tag indicates that only entries from the named servers will be included in the file.
<CollationHosts = "list_of_valid_hostnames:port|failover hosts"/>
Optional A comma-separated list of collation servers (with pipe delimited failover servers) to which all log entries (for this object) are forwarded. Collation servers can be specified by name or IP address. Specify the collation port with a colon after the name. For example, in host1:5000|failhostA:5000|failhostB:6000, host2:6000 logs would be sent to host1 and host2, with failhostA and failhostB acting as failover hosts for host1. When host1 disconnects, logs would be sent to failhostA. If failhostA disconnects, log entries would be sent to failhostB until host1 or failhostA comes back. Logs would also be sent to host2.
<Header = "header"/>
Optional The header text you want the log files to contain. The header text appears at the beginning of the log file, just before the first record.
<RollingEnabled = "truth value"/>

Optional Enables or disables log file rolling for the LogObject. This setting overrides the value for the proxy.config.log.rolling_enabled variable in the records.config file. Set truth value to one of the following values:

  • 0 to disable rolling for this particular LogObject.
  • 1 to roll log files at specific intervals during the day (you specify time intervals with the RollingIntervalSec and RollingOffsetHr fields).
  • 2 to roll log files when they reach a certain size (you specify the size with the RollingSizeMb field).
  • 3 to roll log files at specific intervals during the day or when they reach a certain size (whichever occurs first).
  • 4 to roll log files at specific intervals during the day when log files reach a specific size (at a specified time if the file is of the specified size).
<RollingIntervalSec = "seconds"/>

Optional The seconds between log file rolling for the LogObject; enables you to specify different rolling intervals for different LogObjects.

This setting overrides the value for proxy.config.log.rolling_interval_sec in the records.config file.

<RollingOffsetHr = "hour"/>
Optional Specifies an hour (from 0 to 23) at which rolling is guaranteed to align. Rolling might start before then, but a rolled file will be produced only at that time. The impact of this setting is only noticeable if the rolling interval is larger than one hour. This setting overrides the configuration setting for proxy.config.log.rolling_offset_hr in the records.config file.
<RollingSizeMb = "size_in_MB"/>
Optional The size at which log files are rolled.
Examples

The following is an example of a LogFormat specification that collects information using three common fields:

<LogFormat>
    <Name="minimal"/>
    <Format = "%<chi> : %<cqu> : %<pssc>"/>
</LogFormat>

The following is an example of a LogFormat specification that uses aggregate operators:

<LogFormat>
    <Name = "summary"/>
    <Format = "%<LAST(cqts)> : %<COUNT(*)> : %<SUM(psql)>"/>
    <Interval = "10"/>
</LogFormat>

The following is an example of a LogFilter that will cause only REFRESH_HIT entries to be logged:

<LogFilter>
     <Name = "only_refresh_hits"/>
     <Action = "ACCEPT"/>
     <Condition = "%<pssc> MATCH REFRESH_HIT"/>
</LogFilter>

注解

When specifying the field in the filter condition, you can omit the %<>. This means that the filter below is equivalent to the example directly above:

<LogFilter>
    <Name = "only_refresh_hits"/>
    <Action = "ACCEPT"/>
    <Condition = "pssc MATCH REFRESH_HIT"/>
</LogFilter>

The following is an example of a LogObject specification that creates a local log file for the minimal format defined earlier. The log filename will be minimal.log because this is an ASCII log file (the default).:

<LogObject>
    <Format = "minimal"/>
    <Filename = "minimal"/>
</LogObject>

The following is an example of a LogObject specification that includes only HTTP requests served by hosts in the domain company.com or by the specific server server.somewhere.com. Log entries are sent to port 4000 of the collation host logs.company.com and to port 5000 of the collation host 209.131.52.129.

<LogObject>
     <Format = "minimal"/>
     <Filename = "minimal"/>
     <ServerHosts = "company.com,server.somewhere.com"/>
     <Protocols = "http"/>
     <CollationHosts = "logs.company.com:4000,209.131.52.129:5000"/>
</LogObject>
WELF

Traffic Server supports WELF (WebTrends Enhanced Log Format) so you can analyze Traffic Server log files with WebTrends reporting tools. A predefined <LogFormat> that is compatible with WELF is provided in the logs_xml.config file (shown below). To create a WELF format log file, create a <LogObject> that uses this predefined format.

<LogFormat>
    <Name = "welf"/>
    <Format = "id=firewall time=\"%<cqtd> %<cqtt>\" fw=%<phn> pri=6
       proto=%<cqus> duration=%<ttmsf> sent=%<psql> rcvd=%<cqhl>
       src=%<chi> dst=%<shi> dstname=%<shn> user=%<caun> op=%<cqhm>
       arg=\"%<cqup>\" result=%<pssc> ref=\"%<{Referer}cqh>\"
       agent=\"%<{user-agent}cqh>\" cache=%<crc>"/>
</LogFormat>

parent.config

The parent.config file identifies the parent proxies used in an cache hierarchy. Use this file to perform the following configuration:

  • Set up parent cache hierarchies, with multiple parents and parent failover
  • Configure selected URL requests to bypass parent proxies

Traffic Server uses the parent.config file only when the parent caching option is enabled (refer to Configuring Traffic Server to Use a Parent Cache).

After you modify the parent.config file, run the traffic_line -x command to apply your changes. When you apply the changes to one node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the parent.config file must contain a parent caching rule. Traffic Server recognizes three space-delimited tags:

primary_destination=value secondary_specifier=value  action=value

The following list shows the possible primary destinations and their allowed values.

dest_domain
A requested domain name.
dest_host
A requested hostname.
dest_ip
A requested IP address or range of IP addresses separated by a dash (-).
url_regex
A regular expression (regex) to be found in a URL

The secondary specifiers are optional in the parent.config file. The following list shows the possible secondary specifiers and their allowed values.

port
A requested URL port.
scheme
A request URL protocol: http or https.
prefix
A prefix in the path part of a URL.
suffix
A file suffix in the URL.
method

A request URL method. It can be one of the following:

  • get
  • post
  • put
  • trace
time
A time range, such as 08:00-14:00, during which the parent cache is used to serve requests.
src_ip
A client IP address.

The following list shows the possible actions and their allowed values.

parent
An ordered list of parent servers. If the request cannot be handled by the last parent server in the list, then it will be routed to the origin server. You can specify either a hostname or an IP address, but; you must specify the port number.
round_robin

One of the following values:

  • true - Traffic Server goes through the parent cache list in a round robin-based on client IP address.
  • strict - Traffic Server machines serve requests strictly in turn. For example: machine proxy1 serves the first request, proxy2 serves the second request, and so on.
  • false - Round robin selection does not occur.
go_direct

One of the following values:

  • true - requests bypass parent hierarchies and go directly to the origin server.
  • false - requests do not bypass parent hierarchies.
Examples

The following rule configures a parent cache hierarchy consisting of Traffic Server (which is the child) and two parents, p1.x.com and p2.x.com. Traffic Server forwards the requests it cannot serve to the parent servers p1.x.com and p2.x.com in a round-robin fashion:

round_robin=true
dest_domain=. method=get parent="p1.x.com:8080; p2.y.com:8080" round_robin=true

The following rule configures Traffic Server to route all requests containing the regular expression politics and the path /viewpoint directly to the origin server (bypassing any parent hierarchies): url_regex=politics prefix=/viewpoint go_direct=true

Every line in the parent.config file must contain either a parent= or go_direct= directive.

plugin.config

Description

The plugin.config file controls run-time loadable plugins available to the Traffic Server, as well as their configuration. Plugins listed in this file are referred to as global plugins because they are always loaded and have global effect. This is in contrast to plugins specified in remap.config, whose effects are limited to the specific mapping rules they are applied to.

Each configuration line consists of a path to an .so file. This path can either be absolute, or relative to the plugin directory (usually /usr/local/libexec/trafficserver). Failure to load a plugin is fatal, and will cause Traffic Server to abort. In general, it is not possible to know whether it is safe for the service to run without a particular plugin, since plugins can have arbitrary effects on caching and authorization policies.

Plugins should only be listed once. The order in which the plugins are listed is also the order in which they are chained for request processing.

An option list of whitespace-separated arguments may follow the plugin name. These are passed as an argument vector to the plugin’s initialization function, TSPluginInit(). Arguments that begin with the $ character designate Traffic Server configuration variables. These arguments will be replaced with the value of the corresponding configuration variable before the plugin is loaded. When using configuration variable expansion, note that most Traffic Server configuration can be changed. If a plugin requires the current value, it must obtain that using the management API.

Examples
# Comments start with a '#' and continue to the end of the line
# Blank lines are ignored
#
# test-plugin.so arg1 arg2 arg3
#
plugins/iwx/iwx.so
plugins/abuse/abuse.so etc/trafficserver/abuse.config
plugins/icx/icx.so etc/trafficserver/icx.config $proxy.config.http.connect_attempts_timeout
See also

TSAPI(3ts), TSPluginInit(3ts), remap.config(5)

records.config

The records.config file (by default, located in /opt/trafficserver/etc/trafficserver/) is a list of configurable variables used by the Traffic Server software. Many of the variables in the records.config file are set automatically when you set configuration options in Traffic Line or Traffic Shell. After you modify the records.config file, run the command traffic_line -x to apply the changes. When you apply changes to one node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each variable has the following format:

SCOPE variable_name DATATYPE variable_value

where

SCOPE is related to clustering and is either CONFIG (all members of the cluster) or LOCAL (only the local machine)

DATATYPE is one of INT (integer), STRING (string), FLOAT (floating point). : A variable marked as Deprecated is still functional but should be avoided as it may be removed in a future release without warning.

A variable marked as Reloadable can be updated via the command:

traffic_line -x

INT type configurations are expressed as any normal integer, e.g. 32768. They can also be expressed using more human readable values using standard prefixes, e.g. 32K. The following prefixes are supported for all INT type configurations

  • K Kilobytes (1024 bytes)
  • M Megabytes (1024^2 or 1,048,576 bytes)
  • G Gigabytes (1024^3 or 1,073,741,824 bytes)
  • T Terabytes (1024^4 or 1,099,511,627,776 bytes)

注解

Traffic Server currently writes back configurations to disk periodically, and when doing so, will not preserve the prefixes.

Examples

In the following example, the variable proxy.config.proxy_name is a STRING datatype with the value my_server. This means that the name of the Traffic Server proxy is my_server.

CONFIG proxy.config.proxy_name STRING my_server

If the server name should be that_server the line would be

CONFIG proxy.config.proxy_name STRING that_server

In the following example, the variable proxy.config.arm.enabled is a yes/no flag. A value of 0 (zero) disables the option; a value of 1 enables the option.

CONFIG proxy.config.arm.enabled INT 0

In the following example, the variable sets the cluster startup timeout to 10 seconds.

CONFIG proxy.config.cluster.startup_timeout INT 10

The last examples configures a 64GB RAM cache, using a human readable prefix.

CONFIG proxy.config.cache.ram_cache.size INT 64G
Environment Overrides

Every records.config configuration variable can be overridden by a corresponding environment variable. This can be useful in situations where you need a static records.config but still want to tweak one or two settings. The override variable is formed by converting the records.config variable name to upper case, and replacing any dot separators with an underscore.

Overriding a variable from the environment is permanent and will not be affected by future configuration changes made in records.config or applied with traffic_line.

For example, we could override the proxy.config.product_company variable like this:

$ PROXY_CONFIG_PRODUCT_COMPANY=example traffic_cop &
$ traffic_line -r proxy.config.product_company
Configuration Variables

The following list describes the configuration variables available in the records.config file.

System Variables
proxy.config.product_company
Scope:CONFIG
Type:STRING
Default:Apache Software Foundation

The name of the organization developing Traffic Server.

proxy.config.product_vendor
Scope:CONFIG
Type:STRING
Default:Apache

The name of the vendor providing Traffic Server.

proxy.config.product_name
Scope:CONFIG
Type:STRING
Default:Traffic Server

The name of the product.

proxy.config.proxy_name
Scope:CONFIG
Type:STRING
Default:``build_machine``
Reloadable:Yes

The name of the Traffic Server node.

proxy.config.bin_path
Scope:CONFIG
Type:STRING
Default:bin

The location of the Traffic Server bin directory.

proxy.config.proxy_binary
Scope:CONFIG
Type:STRING
Default:traffic_server

The name of the executable that runs the traffic_server process.

proxy.config.proxy_binary_opts
Scope:CONFIG
Type:STRING
Default:-M

The command-line options for starting Traffic Server.

proxy.config.manager_binary
Scope:CONFIG
Type:STRING
Default:traffic_manager

The name of the executable that runs the traffic_manager process.

proxy.config.env_prep
Scope:CONFIG
Type:STRING
Default:*NONE*

The script executed before the traffic_manager process spawns the traffic_server process.

proxy.config.config_dir
Scope:CONFIG
Type:STRING
Default:etc/trafficserver

The directory that contains Traffic Server configuration files. This is a read-only configuration option that contains the SYSCONFDIR value specified at build time relative to the installation prefix. The $TS_ROOT environment variable can be used alter the installation prefix at run time.

proxy.config.alarm_email
Scope:CONFIG
Type:STRING
Default:*NONE*
Reloadable:Yes

The email address to which Traffic Server sends alarm messages.

During a custom Traffic Server installation, you can specify the email address; otherwise, Traffic Server uses the Traffic Server user account name as the default value for this variable.

proxy.config.syslog_facility
Scope:CONFIG
Type:STRING
Default:LOG_DAEMON

The facility used to record system log files. Refer to Understanding Traffic Server Log Files.

proxy.config.cop.core_signal
Scope:CONFIG
Type:INT
Default:0

The signal sent to traffic_cop‘s managed processes to stop them.

A value of 0 means no signal will be sent.

proxy.config.cop.linux_min_memfree_kb
Scope:CONFIG
Type:INT
Default:10240

The minimum amount of free memory space allowed before Traffic Server stops the traffic_server and traffic_manager processes to prevent the system from hanging.

proxy.config.cop.linux_min_swapfree_kb
Scope:CONFIG
Type:INT
Default:10240

The minimum amount of free swap space allowed before Traffic Server stops the traffic_server and traffic_manager processes to prevent the system from hanging. This configuration variable applies if swap is enabled in Linux 2.2 only.

proxy.config.output.logfile
Scope:CONFIG
Type:STRING
Default:traffic.out

The name and location of the file that contains warnings, status messages, and error messages produced by the Traffic Server processes. If no path is specified, then Traffic Server creates the file in its logging directory.

proxy.config.snapshot_dir
Scope:CONFIG
Type:STRING
Default:snapshots

The directory in which Traffic Server stores configuration snapshots on the local system. Unless you specify an absolute path, this directory is located in the Traffic Server SYSCONFDIR directory.

proxy.config.exec_thread.autoconfig
Scope:CONFIG
Type:INT
Default:1

When enabled (the default, 1), Traffic Server scales threads according to the available CPU cores. See the config option below.

proxy.config.exec_thread.autoconfig.scale
Scope:CONFIG
Type:FLOAT
Default:1.5

Factor by which Traffic Server scales the number of threads. The multiplier is usually the number of available CPU cores. By default this is scaling factor is 1.5.

proxy.config.exec_thread.limit
Scope:CONFIG
Type:INT
Default:2

XXX What does this do?

proxy.config.accept_threads
Scope:CONFIG
Type:INT
Default:0

When enabled (1), runs a separate thread for accept processing. If disabled (0), then only 1 thread can be created.

proxy.config.thread.default.stacksize
Scope:CONFIG
Type:INT
Default:1096908

The new default thread stack size, for all threads. The original default is set at 1 MB.

proxy.config.exec_thread.affinity
Scope:CONFIG
Type:INT
Default:0

Bind threads to specific processing units.

Value Effect
0 assign threads to machine
1 assign threads to NUMA nodes
2 assign threads to sockets
3 assign threads to cores
4 assign threads to processing units

注解

This option only has an affect when Traffic Server has been compiled with --enable-hwloc.

Network
proxy.config.net.connections_throttle
Scope:CONFIG
Type:INT
Default:10000

The total number of client and origin server connections that the server can handle simultaneously. This is in fact the max number of file descriptors that the traffic_server process can have open at any given time. Roughly 10% of these connections are reserved for origin server connections, i.e. from the default, only ~9,000 client connections can be handled. This should be tuned according to your memory size, and expected work load.

proxy.local.incoming_ip_to_bind
Scope:LOCAL
Type:STRING
Default:0.0.0.0 [::]

Controls the global default IP addresses to which to bind proxy server ports. The value is a space separated list of IP addresses, one per supported IP address family (currently IPv4 and IPv6).

Unless explicitly specified in proxy.config.http.server_ports the server port will be bound to one of these addresses, selected by IP address family. The built in default is any address. This is used if no address for a family is specified. This setting is useful if most or all server ports should be bound to the same address.

注解

This is ignored for inbound transparent server ports because they must be able to accept connections on arbitrary IP addresses.

Example

Set the global default for IPv4 to 192.168.101.18 and leave the global default for IPv6 as any address.:

LOCAL proxy.local.incoming_ip_to_bind STRING 192.168.101.18

Example

Set the global default for IPv4 to 191.68.101.18 and the global default for IPv6 to fc07:192:168:101::17.:

LOCAL proxy.local.incoming_ip_to_bind STRING 192.168.101.18 [fc07:192:168:101::17]
proxy.local.outgoing_ip_to_bind
Scope:LOCAL
Type:STRING
Default:0.0.0.0 [::]

This controls the global default for the local IP address for outbound connections to origin servers. The value is a list of space separated IP addresses, one per supported IP address family (currently IPv4 and IPv6).

Unless explicitly specified in proxy.config.http.server_ports one of these addresses, selected by IP address family, will be used as the local address for outbound connections. This setting is useful if most or all of the server ports should use the same outbound IP addresses.

注解

This is ignored for outbound transparent ports as the local outbound address will be the same as the client local address.

Example

Set the default local outbound IP address for IPv4 connections to 192.168.101.18.:

LOCAL proxy.local.outgoing_ip_to_bind STRING 192.168.101.18

Example

Set the default local outbound IP address to 192.168.101.17 for IPv4 and fc07:192:168:101::17 for IPv6.:

LOCAL proxy.local.outgoing_ip_to_bind STRING 192.168.101.17 [fc07:192:168:101::17]
Cluster
proxy.local.cluster.type
Scope:LOCAL
Type:INT
Default:3

Sets the clustering mode:

Value Effect
1 full-clustering mode
2 management-only mode
3 no clustering
proxy.config.cluster.ethernet_interface
Scope:CONFIG
Type:INT
Default:eth0

The network interface to be used for cluster communication. This has to be identical on all members of a clsuter. ToDo: Is that reasonable ?? Should this be local”

proxy.config.cluster.rsport
Scope:CONFIG
Type:INT
Default:8088

The reliable service port. The reliable service port is used to send configuration information between the nodes in a cluster. All nodes in a cluster must use the same reliable service port.

proxy.config.cluster.threads
Scope:CONFIG
Type:INT
Default:1

The number of threads for cluster communication. On heavy cluster, the number should be adjusted. It is recommend that take the thread CPU usage as a reference when adjusting.

proxy.config.clustger.ethernet_interface
Scope:CONFIG
Type:STRING
Default:*NONE*

Set the interface to use for cluster communications.

proxy.config.http.cache.cluster_cache_local
Scope:CONFIG
Type:INT
Default:0

This turns on the local caching of objects in cluster mode. The point of this is to allow for popular or hot content to be cached on all nodes in a cluster. Be aware that the primary way to configure this behavior is via the cache.config configuration file using action=cluster-cache-local directives.

This particular records.config configuration can be controlled per transaction or per remap rule. As such, it augments the cache.config directives, since you can turn on the local caching feature without complex regular expression matching.

This implies that turning this on in your global records.config is almost never what you want; instead, you want to use this either via e.g. conf_remap.so overrides for a certain remap rule, or through a custom plugin using the appropriate APIs.

Local Manager
proxy.config.lm.sem_id
Scope:CONFIG
Type:INT
Default:11452

The semaphore ID for the local manager.

proxy.config.admin.autoconf_port
Scope:CONFIG
Type:INT
Default:8083

The autoconfiguration port.

proxy.config.admin.number_config_bak
Scope:CONFIG
Type:INT
Default:3

The maximum number of copies of rolled configuration files to keep.

proxy.config.admin.user_id
Scope:CONFIG
Type:STRING
Default:nobody

Option used to specify who to run the traffic_server process as; also used to specify ownership of config and log files.

The nonprivileged user account designated to Traffic Server.

As of version 2.1.1 if the user_id is prefixed with pound character (#) the remaining of the string is considered to be a numeric user identifier. If the value is set to #-1 Traffic Server will not change the user during startup.

Setting user_id to root or #0 is now forbidden to increase security. Trying to do so, will cause the traffic_server fatal failure. However there are two ways to bypass that restriction

  • Specify -DBIG_SECURITY_HOLE in CXXFLAGS during compilation.
  • Set the user_id=#-1 and start trafficserver as root.
Process Manager
proxy.config.process_manager.mgmt_port
Scope:CONFIG
Type:INT
Default:8084

The port used for internal communication between the traffic_manager and traffic_server processes.

Alarm Configuration
proxy.config.alarm.bin
Scope:CONFIG
Type:STRING
Default:example_alarm_bin.sh

Name of the script file that can execute certain actions when an alarm is signaled. The default file is a sample script named example_alarm_bin.sh located in the bin directory. You must edit the script to suit your needs.

proxy.config.alarm.abs_path
Scope:CONFIG
Type:STRING
Default:NULL

The full path to the script file that sends email to alert someone about Traffic Server problems.

HTTP Engine
proxy.config.http.server_ports
Scope:CONFIG
Type:STRING
Default:8080

Ports used for proxying HTTP traffic.

This is a list, separated by space or comma, of port descriptors. Each descriptor is a sequence of keywords and values separated by colons. Not all keywords have values, those that do are specifically noted. Keywords with values can have an optional ‘=’ character separating the keyword and value. The case of keywords is ignored. The order of keywords is irrelevant but unspecified results may occur if incompatible options are used (noted below). Options without values are idempotent. Options with values use the last (right most) value specified, except for ip-out as detailed later.

Quick reference chart.

Name Note Definition
number Required The local port.
ipv4 Default Bind to IPv4 address family.
ipv6   Bind to IPv6 address family.
tr-in   Inbound transparent.
tr-out   Outbound transparent.
tr-full   Fully transparent (inbound and outbound)
tr-pass   Pass through enabled.
ssl   SSL terminated.
ip-in Value Local inbound IP address.
ip-out Value Local outbound IP address.
ip-resolve Value IP address resolution style.
blind   Blind (CONNECT) port.
compress N/I Compressed. Not implemented.
number
Local IP port to bind. This is the port to which ATS clients will connect.
ipv4
Use IPv4. This is the default and is included primarily for completeness. This forced if the ip-in option is used with an IPv4 address.
ipv6
Use IPv6. This is forced if the ip-in option is used with an IPv6 address.
tr-in

Inbound transparent. The proxy port will accept connections to any IP address on the port. To have IPv6 inbound transparent you must use this and the ipv6 option. This overrides proxy.local.incoming_ip_to_bind for this port.

Not compatible with: ip-in, ssl, blind

tr-out

Outbound transparent. If ATS connects to an origin server for a transaction on this port, it will use the client’s address as its local address. This overrides proxy.local.outgoing_ip_to_bind for this port.

Not compatible with: ip-out, ip-resolve

tr-full

Fully transparent. This is a convenience option and is identical to specifying both tr-in and tr-out.

Not compatible with: Any option not compatible with tr-in or tr-out.

tr-pass
Transparent pass through. This option is useful only for inbound transparent proxy ports. If the parsing of the expected HTTP header fails, then the transaction is switched to a blind tunnel instead of generating an error response to the client. It effectively enables proxy.config.http.use_client_target_addr for the transaction as there is no other place to obtain the origin server address.
ip-in

Set the local IP address for the port. This is the address to which clients will connect. This forces the IP address family for the port. The ipv4 or ipv6 can be used but it is optional and is an error for it to disagree with the IP address family of this value. An IPv6 address must be enclosed in square brackets. If this option is omitted proxy.local.incoming_ip_to_bind is used.

Not compatible with: tr-in.

ip-out

Set the local IP address for outbound connections. This is the address used by ATS locally when it connects to an origin server for transactions on this port. If this is omitted proxy.local.outgoing_ip_to_bind is used.

This option can used multiple times, once for each IP address family. The address used is selected by the IP address family of the origin server address.

Not compatible with: tr-out.

ip-resolve

Set the host resolution style for transactions on this proxy port.

Not compatible with: tr-out.

ssl

Require SSL termination for inbound connections. SSL must be configured for this option to provide a functional server port.

Not compatible with: tr-in, blind.

blind

Accept only CONNECT transactions on this port.

Not compatible with: tr-in, ssl.

compress
Compress the connection. Retained only by inertia, should be considered “not implemented”.

Example

Listen on port 80 on any address for IPv4 and IPv6.:

80 80:ipv6

Example

Listen transparently on any IPv4 address on port 8080, and transparently on port 8080 on local address fc01:10:10:1::1 (which implies ipv6).:

IPv4:tr-FULL:8080 TR-full:IP-in=[fc02:10:10:1::1]:8080

Example

Listen on port 8080 for IPv6, fully transparent. Set up an SSL port on 443. These ports will use the IP address from proxy.local.incoming_ip_to_bind. Listen on IP address 192.168.17.1, port 80, IPv4, and connect to origin servers using the local address 10.10.10.1 for IPv4 and fc01:10:10:1::1 for IPv6.:

8080:ipv6:tr-full 443:ssl ip-in=192.168.17.1:80:ip-out=[fc01:10:10:1::1]:ip-out=10.10.10.1
proxy.config.http.connect_ports
Scope:CONFIG
Type:STRING
Default:443 563

The range of origin server ports that can be used for tunneling via CONNECT.

Traffic Server allows tunnels only to the specified ports. Supports both wildcards (‘*’) and ranges (“0-1023”).

注解

These are the ports on the origin server, not Traffic Server proxy ports.

proxy.config.http.insert_request_via_str
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Set how the Via field is handled on a request to the origin server.

Value Effect
0 Do not modify / set this via header
1 Update the via, with normal verbosity
2 Update the via, with higher verbosity
3 Update the via, with highest verbosity

注解

The Via header string can be decoded with the Via Decoder Ring.

proxy.config.http.insert_response_via_str
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Set how the Via field is handled on the response to the client.

Value Effect
0 Do not modify / set this via header
1 Update the via, with normal verbosity
2 Update the via, with higher verbosity
3 Update the via, with highest verbosity

注解

The Via header string can be decoded with the Via Decoder Ring.

proxy.config.http.response_server_enabled
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

You can specify one of the following:

  • 0 no Server: header is added to the response.
  • 1 the Server: header is added (see string below).
  • 2 the Server: header is added only if the response from rigin does not have one already.
proxy.config.http.insert_age_in_response
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

This option specifies whether Traffic Server should insert an Age header in the response. The Age field value is the cache’s estimate of the amount of time since the response was generated or revalidated by the origin server.

  • 0 no Age header is added
  • 1 the Age header is added
proxy.config.http.response_server_str
Scope:CONFIG
Type:STRING
Default:ATS/
Reloadable:Yes

The Server: string that ATS will insert in a response header (if requested, see above). Note that the current version number is always appended to this string.

proxy.config.http.enable_url_expandomatic
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) .com domain expansion. This configures the Traffic Server to resolve unqualified hostnames by prepending with www. and appending with .com before redirecting to the expanded address. For example: if a client makes a request to host, then Traffic Server redirects the request to www.host.com.

proxy.config.http.chunking_enabled
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Specifies whether Traffic Sever can generate a chunked response:

  • 0 Never
  • 1 Always
  • 2 Generate a chunked response if the server has returned HTTP/1.1 before
  • 3 = Generate a chunked response if the client request is HTTP/1.1 and the origin server has returned HTTP/1.1 before

注解

If HTTP/1.1 is used, then Traffic Server can use keep-alive connections with pipelining to origin servers. If HTTP/0.9 is used, then Traffic Server does not use keep-alive connections to origin servers. If HTTP/1.0 is used, then Traffic Server can use keep-alive connections without pipelining to origin servers.

proxy.config.http.share_server_sessions
Scope:CONFIG
Type:INT
Default:1
Deprecated:Yes

Enables (1) or disables (0) the reuse of server sessions.

proxy.config.http.server_session_sharing.match
Scope:CONFIG
Type:STRING
Default:both

Enable and set the ability to re-use server connections across client connections. The valid values are

none
Do not match, do not re-use server sessions.
ip
Re-use server sessions, check only that the IP address and port of the origin server matches.
host
Re-use server sessions, check only that the fully qualified domain name matches.
both
Re-use server sessions, but only if the IP address and fully qualified domain name match.

It is strongly recommended to use either none or both for this value unless you have a specific need to use ip or host. The most common reason is virtual hosts that share an IP address in which case performance can be enhanced if those sessions can be re-used. However, not all web servers support requests for different virtual hosts on the same connection so use with caution.

proxy.config.http.server_session_sharing.pool
Scope:CONFIG
Type:STRING
Default:thread

Control the scope of server session re-use if it is enabled by proxy.config.http.server_session_sharing.match. The valid values are

global
Re-use sessions from a global pool of all server sessions.
thread
Re-use sessions from a per-thread pool.
proxy.config.http.record_heartbeat
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) traffic_cop heartbeat ogging.

proxy.config.http.use_client_target_addr
Scope:CONFIG
Type:INT
Default:0

For fully transparent ports use the same origin server address as the client.

This option causes Traffic Server to avoid where possible doing DNS lookups in forward transparent proxy mode. The option is only effective if the following three conditions are true -

  • Traffic Server is in forward proxy mode.
  • The proxy port is inbound transparent.
  • The target URL has not been modified by either remapping or a plugin.

If any of these conditions are not true, then normal DNS processing is done for the connection.

If all of these conditions are met, then the origin server IP address is retrieved from the original client connection, rather than through HostDB or DNS lookup. In effect, client DNS resolution is used instead of Traffic Server DNS.

This can be used to be a little more efficient (looking up the target once by the client rather than by both the client and Traffic Server) but the primary use is when client DNS resolution can differ from that of Traffic Server. Two known uses cases are:

  1. Embedded IP addresses in a protocol with DNS load sharing. In this case, even though Traffic Server and the client both make the same request to the same DNS resolver chain, they may get different origin server addresses. If the address is embedded in the protocol then the overall exchange will fail. One current example is Microsoft Windows update, which presumably embeds the address as a security measure.
  2. The client has access to local DNS zone information which is not available to Traffic Server. There are corporate nets with local DNS information for internal servers which, by design, is not propagated outside the core corporate network. Depending a network topology it can be the case that Traffic Server can access the servers by IP address but cannot resolve such addresses by name. In such as case the client supplied target address must be used.

This solution must be considered interim. In the longer term, it should be possible to arrange for much finer grained control of DNS lookup so that wildcard domain can be set to use Traffic Server or client resolution. In both known use cases, marking specific domains as client determined (rather than a single global switch) would suffice. It is possible to do this crudely with this flag by enabling it and then use identity URL mappings to re-disable it for specific domains.

proxy.config.http.keep_alive_enabled_in
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) incoming keep-alive connections.

proxy.config.http.keep_alive_enabled_out
Scope:CONFIG
Type:INT
Default:0
Enables (1) or disables (0) outgoing keep-alive connections.

注解

Enabling keep-alive does not automatically enable purging of keep-alive requests when nearing the connection limit, that is controlled by proxy.config.http.server_max_connections.

proxy.config.http.keep_alive_post_out
Scope:CONFIG
Type:INT
Default:0

Controls wether new POST requests re-use keep-alive sessions (1) or create new connections per request (0).

Parent Proxy Configuration
proxy.config.http.parent_proxy_routing_enable
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) the parent caching option. Refer to Hierarchical Caching.

proxy.config.http.parent_proxy.retry_time
Scope:CONFIG
Type:INT
Default:300
Reloadable:Yes

The amount of time allowed between connection retries to a parent cache that is unavailable.

proxy.config.http.parent_proxy.fail_threshold
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

The number of times the connection to the parent cache can fail before Traffic Server considers the parent unavailable.

proxy.config.http.parent_proxy.total_connect_attempts
Scope:CONFIG
Type:INT
Default:4
Reloadable:Yes

The total number of connection attempts allowed to a parent cache before Traffic Server bypasses the parent or fails the request (depending on the go_direct option in the parent.config file).

proxy.config.http.parent_proxy.per_parent_connect_attempts
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

The total number of connection attempts allowed per parent, if multiple parents are used.

proxy.config.http.parent_proxy.connect_attempts_timeout
Scope:CONFIG
Type:INT
Default:30
Reloadable:Yes

The timeout value (in seconds) for parent cache connection attempts.

proxy.config.http.forward.proxy_auth_to_parent
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Configures Traffic Server to send proxy authentication headers on to the parent cache.

proxy.config.http.no_dns_just_forward_to_parent
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Don’t try to resolve DNS, forward all DNS requests to the parent. This is off (0) by default.

HTTP Connection Timeouts
proxy.config.http.keep_alive_no_activity_timeout_in
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

Specifies how long Traffic Server keeps connections to clients open for a subsequent request after a transaction ends.

proxy.config.http.keep_alive_no_activity_timeout_out
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

Specifies how long Traffic Server keeps connections to origin servers open for a subsequent transfer of data after a transaction ends.

proxy.config.http.transaction_no_activity_timeout_in
Scope:CONFIG
Type:INT
Default:120
Reloadable:Yes

Specifies how long Traffic Server keeps connections to clients open if a transaction stalls.

proxy.config.http.transaction_no_activity_timeout_out
Scope:CONFIG
Type:INT
Default:120
Reloadable:Yes

Specifies how long Traffic Server keeps connections to origin servers open if the transaction stalls.

proxy.config.http.transaction_active_timeout_in
Scope:CONFIG
Type:INT
Default:900
Reloadable:Yes

The maximum amount of time Traffic Server can remain connected to a client. If the transfer to the client is not complete before this timeout expires, then Traffic Server closes the connection.

The value of 0 specifies that there is no timeout.

proxy.config.http.transaction_active_timeout_out
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

The maximum amount of time Traffic Server waits for fulfillment of a connection request to an origin server. If Traffic Server does not complete the transfer to the origin server before this timeout expires, then Traffic Server terminates the connection request.

The default value of 0 specifies that there is no timeout.

proxy.config.http.accept_no_activity_timeout
Scope:CONFIG
Type:INT
Default:120
Reloadable:Yes

The timeout interval in seconds before Traffic Server closes a connection that has no activity.

proxy.config.http.background_fill_active_timeout
Scope:CONFIG
Type:INT
Default:60
Reloadable:Yes

Specifies how long Traffic Server continues a background fill before giving up and dropping the origin server connection.

proxy.config.http.background_fill_completed_threshold
Scope:CONFIG
Type:FLOAT
Default:0.50000
Reloadable:Yes

The proportion of total document size already transferred when a client aborts at which the proxy continues fetching the document from the origin server to get it into the cache (a background fill).

Origin Server Connect Attempts
proxy.config.http.connect_attempts_max_retries
Scope:CONFIG
Type:INT
Default:6
Reloadable:Yes

The maximum number of connection retries Traffic Server can make when the origin server is not responding.

proxy.config.http.connect_attempts_max_retries_dead_server
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

The maximum number of connection retries Traffic Server can make when the origin server is unavailable.

proxy.config.http.server_max_connections
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Limits the number of socket connections across all origin servers to the value specified. To disable, set to zero (0).

注解

This value is used in determining when and if to prune active origin sessions. Without this value set connections to origins can consume all the way up to ts:cv:proxy.config.net.connections_throttle connections, which in turn can starve incoming requests from available connections.

proxy.config.http.origin_max_connections
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Limits the number of socket connections per origin server to the value specified. To enable, set to one (1).

proxy.config.http.origin_min_keep_alive_connections
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

As connection to an origin server are opened, keep at least ‘n’ number of connections open to that origin, even if the connection isn’t used for a long time period. Useful when the origin supports keep-alive, removing the time needed to set up a new connection from the next request at the expense of added (inactive) connections. To enable, set to one (1).

proxy.config.http.connect_attempts_rr_retries
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

The maximum number of failed connection attempts allowed before a round-robin entry is marked as ‘down’ if a server has round-robin DNS entries.

proxy.config.http.connect_attempts_timeout
Scope:CONFIG
Type:INT
Default:30
Reloadable:Yes

The timeout value (in seconds) for an origin server connection.

proxy.config.http.post_connect_attempts_timeout
Scope:CONFIG
Type:INT
Default:1800
Reloadable:Yes

The timeout value (in seconds) for an origin server connection when the client request is a POST or PUT request.

proxy.config.http.down_server.cache_time
Scope:CONFIG
Type:INT
Default:900
Reloadable:Yes

Specifies how long (in seconds) Traffic Server remembers that an origin server was unreachable.

proxy.config.http.down_server.abort_threshold
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

The number of seconds before Traffic Server marks an origin server as unavailable after a client abandons a request because the origin server was too slow in sending the response header.

proxy.config.http.uncacheable_requests_bypass_parent
Scope:CONFIG
Type:INT
Default:1

When enabled (1), Traffic Server bypasses the parent proxy for a request that is not cacheable.

Congestion Control
proxy.config.http.congestion_control.enabled
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) the Congestion Control option, which configures Traffic Server to stop forwarding HTTP requests to origin servers when they become congested. Traffic Server sends the client a message to retry the congested origin server later. Refer to Using Congestion Control.

proxy.config.http.flow_control.enabled
Scope:CONFIG
Type:INT
Default:0

Transaction buffering / flow control is enabled if this is set to a non-zero value. Otherwise no flow control is done.

proxy.config.http.flow_control.high_water
Scope:CONFIG
Type:INT
Default:65536
Metric:bytes

The high water mark for transaction buffer control. External source I/O is halted when the total buffer space in use by the transaction exceeds this value.

proxy.config.http.flow_control.low_water
Scope:CONFIG
Type:INT
Default:65536
Metric:bytes

The low water mark for transaction buffer control. External source I/O is resumed when the total buffer space in use by the transaction is no more than this value.

Negative Response Caching
proxy.config.http.negative_caching_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server caches negative responses (such as 404 Not Found) when a requested page does not exist. The next time a client requests the same page, Traffic Server serves the negative response directly from cache. When disabled (0) Traffic Server will only cache the response if the response has Cache-Control headers.

注解

Cache-Control directives from the server forbidding ache are ignored for the following HTTP response codes, regardless of the value specified for the proxy.config.http.negative_caching_enabled variable.

The following negative responses are cached by Traffic Server::

204  No Content
305  Use Proxy
400  Bad Request
403  Forbidden
404  Not Found
405  Method Not Allowed
500  Internal Server Error
501  Not Implemented
502  Bad Gateway
503  Service Unavailable
504  Gateway Timeout

The cache lifetime for objects cached from this setting is controlled via proxy.config.http.negative_caching_lifetime.

proxy.config.http.negative_caching_lifetime
Scope:CONFIG
Type:INT
Default:1800

How long (in seconds) Traffic Server keeps the negative responses valid in cache. This value only affects negative responses that do have explicit Expires: or Cache-Control: lifetimes set by the server.

Proxy User Variables
proxy.config.http.anonymize_remove_from
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server removes the From header to protect the privacy of your users.

proxy.config.http.anonymize_remove_referer
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server removes the Referrer header to protect the privacy of your site and users.

proxy.config.http.anonymize_remove_user_agent
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server removes the User-agent header to protect the privacy of your site and users.

Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server removes the Cookie header to protect the privacy of your site and users.

proxy.config.http.anonymize_remove_client_ip
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server removes Client-IP headers for more privacy.

proxy.config.http.anonymize_insert_client_ip
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

When enabled (1), Traffic Server inserts Client-IP headers to retain the client IP address.

proxy.config.http.append_xforwards_header
Scope:CONFIG
Type:INT
Default:0

When enabled (1), Traffic Server appends X-Forwards headers to outgoing requests.

proxy.config.http.anonymize_other_header_list
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

Comma separated list of headers Traffic Server should remove from outgoing requests.

proxy.config.http.insert_squid_x_forwarded_for
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server adds the client IP address to the X-Forwarded-For header.

proxy.config.http.normalize_ae_gzip
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enable (1) to normalize all Accept-Encoding: headers to one of the following:

  • Accept-Encoding: gzip (if the header has gzip or x-gzip with any q) OR
  • blank (for any header that does not include gzip)

This is useful for minimizing cached alternates of documents (e.g. gzip, deflate vs. deflate, gzip). Enabling this option is recommended if your origin servers use no encodings other than gzip.

Security
proxy.config.http.push_method_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) the HTTP PUSH option, which allows you to deliver content directly to the cache without a user request.

重要

If you enable this option, then you must also specify a filtering rule in the ip_allow.config file to allow only certain machines to push content into the cache.

Cache Control
proxy.config.cache.enable_read_while_writer
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) ability to a read cached object while the another connection is completing the write to cache for the same object. Several other configuration values need to be set for this to become active. See Reducing Origin Server Requests (Avoiding the Thundering Herd)

proxy.config.cache.force_sector_size
Scope:CONFIG
Type:INT
Default:512
Reloadable:Yes

Forces the use of a specific hardware sector size (512 - 8192 bytes).

proxy.config.http.cache.http
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) caching of HTTP requests.

proxy.config.http.cache.allow_empty_doc
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) caching objects that have an empty response body. This is particularly useful for caching 301 or 302 responses with a Location header but no document body. This only works if the origin response also has a Content-Length header.

proxy.config.http.cache.ignore_client_no_cache
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server ignores client requests to bypass the cache.

proxy.config.http.cache.ims_on_client_no_cache
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server issues a conditional request to the origin server if an incoming request has a No-Cache header.

proxy.config.http.cache.ignore_server_no_cache
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server ignores origin server requests to bypass the cache.

proxy.config.http.cache.cache_responses_to_cookies
Scope:CONFIG
Type:INT
Default:3
Reloadable:Yes

Specifies how cookies are cached:

  • 0 = do not cache any responses to cookies
  • 1 = cache for any content-type
  • 2 = cache only for image types
  • 3 = cache for all but text content-types
proxy.config.http.cache.ignore_authentication
Scope:CONFIG
Type:INT
Default:0

When enabled (1), Traffic Server ignores WWW-Authentication headers in responses WWW-Authentication headers are removed and not cached.

proxy.config.http.cache.cache_urls_that_look_dynamic
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) caching of URLs that look dynamic, i.e.: URLs that end in ``.asp`` or contain a question mark (``?``), a semicolon (``;``), or ``cgi``. For a full list, please refer to HttpTransact::url_looks_dynamic

proxy.config.http.cache.enable_default_vary_headers
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) caching of alternate versions of HTTP objects that do not contain the Vary header.

proxy.config.http.cache.when_to_revalidate
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Specifies when to revalidate content:

  • 0 = use cache directives or heuristic (the default value)

  • 1 = stale if heuristic

  • 2 = always stale (always revalidate)

  • 3 = never stale

  • 4 = use cache directives or heuristic (0) unless the request

    has an If-Modified-Since header

If the request contains the If-Modified-Since header, then Traffic Server always revalidates the cached content and uses the client’s If-Modified-Since header for the proxy request.

proxy.config.http.cache.when_to_add_no_cache_to_msie_requests
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Specifies when to add no-cache directives to Microsoft Internet Explorer requests. You can specify the following:

  • 0 = no-cache is not added to MSIE requests
  • 1 = no-cache is added to IMS MSIE requests
  • 2 = no-cache is added to all MSIE requests
proxy.config.http.cache.required_headers
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

The type of headers required in a request for the request to be cacheable.

  • 0 = no headers required to make document cacheable
  • 1 = either the Last-Modified header, or an explicit lifetime header, Expires or Cache-Control: max-age, is required
  • 2 = explicit lifetime is required, Expires or Cache-Control: max-age
proxy.config.http.cache.max_stale_age
Scope:CONFIG
Type:INT
Default:604800
Reloadable:Yes

The maximum age allowed for a stale response before it cannot be cached.

proxy.config.http.cache.range.lookup
Scope:CONFIG
Type:INT
Default:1

When enabled (1), Traffic Server looks up range requests in the cache.

proxy.config.http.cache.ignore_accept_mismatch
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

When enabled with a value of 1, Traffic Server serves documents from cache with a Content-Type: header even if it does not match the Accept: header of the request. If set to 2 (default), this logic only happens in the absence of a Vary header in the cached response (which is the recommended and safe use).

注解

This option should only be enabled with 1 if you’re having problems with caching and you origin server doesn’t set the Vary header. Alternatively, if the origin is incorrectly setting Vary: Accept or doesn’t respond with 406 (Not Acceptable), you can also enable this configuration with a 1.

proxy.config.http.cache.ignore_accept_language_mismatch
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

When enabled with a value of 1, Traffic Server serves documents from cache with a Content-Language: header even if it does not match the Accept-Language: header of the request. If set to 2 (default), this logic only happens in the absence of a Vary header in the cached response (which is the recommended and safe use).

注解

This option should only be enabled with 1 if you’re having problems with caching and you origin server doesn’t set the Vary header. Alternatively, if the origin is incorrectly setting Vary: Accept-Language or doesn’t respond with 406 (Not Acceptable), you can also enable this configuration with a 1.

proxy.config.http.cache.ignore_accept_encoding_mismatch
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

When enabled with a value of 1, Traffic Server serves documents from cache with a Content-Encoding: header even if it does not match the Accept-Encoding: header of the request. If set to 2 (default), this logic only happens in the absence of a Vary header in the cached response (which is the recommended and safe use).

注解

This option should only be enabled with 1 if you’re having problems with caching and you origin server doesn’t set the Vary header. Alternatively, if the origin is incorrectly setting Vary: Accept-Encoding or doesn’t respond with 406 (Not Acceptable) you can also enable this configuration with a 1.

proxy.config.http.cache.ignore_accept_charset_mismatch
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

When enabled with a value of 1, Traffic Server serves documents from cache with a Content-Type: header even if it does not match the Accept-Charset: header of the request. If set to 2 (default), this logic only happens in the absence of a Vary header in the cached response (which is the recommended and safe use).

注解

This option should only be enabled with 1 if you’re having problems with caching and you origin server doesn’t set the Vary header. Alternatively, if the origin is incorrectly setting Vary: Accept-Charset or doesn’t respond with 406 (Not Acceptable), you can also enable this configuration with a 1.

proxy.config.http.cache.ignore_client_cc_max_age
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server ignores any Cache-Control: max-age headers from the client. This technically violates the HTTP RFC, but avoids a problem where a client can forcefully invalidate a cached object.

proxy.config.cache.max_doc_size
Scope:CONFIG
Type:INT
Default:0

Specifies the maximum object size that will be cached. 0 is unlimited.

proxy.config.cache.permit.pinning
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), Traffic Server will keep certain HTTP objects in the cache for a certain time as specified in cache.config.

proxy.config.cache.hit_evacuate_percent
Scope:CONFIG
Type:INT
Default:0

The size of the region (as a percentage of the total content storage in a cache stripe) in front of the write cursor that constitutes a recent access hit for evacutating the accessed object.

When an object is accessed it can be marked for evacuation, that is to be copied over the write cursor and thereby preserved from being overwritten. This is done if it is no more than a specific number of bytes in front of the write cursor. The number of bytes is a percentage of the total number of bytes of content storage in the cache stripe where the object is stored and that percentage is set by this variable.

By default, the feature is off (set to 0).

proxy.config.cache.hit_evacuate_size_limit
Scope:CONFIG
Type:INT
Default:0
Metric:bytes

Limit the size of objects that are hit evacuated.

Objects larger than the limit are not hit evacuated. A value of 0 disables the limit.

proxy.config.cache.limits.http.max_alts
Scope:CONFIG
Type:INT
Default:5

The maximum number of alternates that are allowed for any given URL. Disable by setting to 0. Note that this setting will not strictly enforce this if the variable proxy.config.cache.vary_on_user_agent is set to 1 (by default it is 0).

proxy.config.cache.target_fragment_size
Scope:CONFIG
Type:INT
Default:1048576

Sets the target size of a contiguous fragment of a file in the disk cache. Accepts values that are powers of 2, e.g. 65536, 131072, 262144, 524288, 1048576, 2097152, etc. When setting this, consider that larger numbers could waste memory on slow connections, but smaller numbers could increase (waste) seeks.

RAM Cache
proxy.config.cache.ram_cache.size
Scope:CONFIG
Type:INT
Default:-1

By default the RAM cache size is automatically determined, based on disk cache size; approximately 10 MB of RAM cache per GB of disk cache. Alternatively, it can be set to a fixed value such as 20GB (21474836480)

proxy.config.cache.ram_cache.algorithm
Scope:CONFIG
Type:INT
Default:0

Two distinct RAM caches are supported, the default (0) being the CLFUS (Clocked Least Frequently Used by Size). As an alternative, a simpler LRU (Least Recently Used) cache is also available, by changing this configuration to 1.

proxy.config.cache.ram_cache.use_seen_filter
Scope:CONFIG
Type:INT
Default:0

Enabling this option will filter inserts into the RAM cache to ensure that they have been seen at least once. For the LRU, this provides scan resistance. Note that CLFUS already requires that a document have history before it is inserted, so for CLFUS, setting this option means that a document must be seen three times before it is added to the RAM cache.

proxy.config.cache.ram_cache.compress
Scope:CONFIG
Type:INT
Default:0

The CLFUS RAM cache also supports an optional in-memory compression. This is not to be confused with Content-Encoding: gzip compression. The RAM cache compression is intended to try to save space in the RAM, and is not visible to the User-Agent (client).

Possible values are:

  • 0 = no compression
  • 1 = fastlz (extremely fast, relatively low compression)
  • 2 = libz (moderate speed, reasonable compression)
  • 3 = liblzma (very slow, high compression)

注解

Compression runs on task threads. To use more cores for RAM cache compression, increase proxy.config.task_threads.

Heuristic Expiration
proxy.config.http.cache.heuristic_min_lifetime
Scope:CONFIG
Type:INT
Default:3600
Reloadable:Yes

The minimum amount of time an HTTP object without an expiration date can remain fresh in the cache before is considered to be stale.

proxy.config.http.cache.heuristic_max_lifetime
Scope:CONFIG
Type:INT
Default:86400
Reloadable:Yes

The maximum amount of time an HTTP object without an expiration date can remain fresh in the cache before is considered to be stale.

proxy.config.http.cache.heuristic_lm_factor
Scope:CONFIG
Type:FLOAT
Default:0.10000
Reloadable:Yes

The aging factor for freshness computations. Traffic Server stores an object for this percentage of the time that elapsed since it last changed.

proxy.config.http.cache.fuzz.time
Scope:CONFIG
Type:INT
Default:240
Reloadable:Yes

How often Traffic Server checks for an early refresh, during the period before the document stale time. The interval specified must be in seconds. See Fuzzy Revalidation

proxy.config.http.cache.fuzz.probability
Scope:CONFIG
Type:FLOAT
Default:0.00500
Reloadable:Yes

The probability that a refresh is made on a document during the specified fuzz time.

proxy.config.http.cache.fuzz.min_time
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Handles requests with a TTL less than fuzz.time – it allows for different times to evaluate the probability of revalidation for small TTLs and big TTLs. Objects with small TTLs will start “rolling the revalidation dice” near the fuzz.min_time, while objects with large TTLs would start at fuzz.time. A logarithmic like function between determines the revalidation evaluation start time (which will be between fuzz.min_time and fuzz.time). As the object gets closer to expiring, the window start becomes more likely. By default this setting is not enabled, but should be enabled anytime you have objects with small TTLs. The default value is 0.

Dynamic Content & Content Negotiation
proxy.config.http.cache.vary_default_text
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The header on which Traffic Server varies for text documents.

For example: if you specify User-agent, then Traffic Server caches all the different user-agent versions of documents it encounters.

proxy.config.http.cache.vary_default_images
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The header on which Traffic Server varies for images.

proxy.config.http.cache.vary_default_other
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The header on which Traffic Server varies for anything other than text and images.

Customizable User Response Pages
proxy.config.body_factory.enable_customizations
Scope:CONFIG
Type:INT
Default:1

Specifies whether customizable response pages are language specific or not:

  • 1 = enable customizable user response pages in the default directory only
  • 2 = enable language-targeted user response pages
proxy.config.body_factory.enable_logging
Scope:CONFIG
Type:INT
Default:1

Enables (1) or disables (0) logging for customizable response pages. When enabled, Traffic Server records a message in the error log each time a customized response page is used or modified.

proxy.config.body_factory.template_sets_dir
Scope:CONFIG
Type:STRING
Default:etc/trafficserver/body_factory

The customizable response page default directory. If this is a relative path, Traffic Server resolves it relative to the PREFIX directory.

proxy.config.body_factory.response_suppression_mode
Scope:CONFIG
Type:INT
Default:0

Specifies when Traffic Server suppresses generated response pages:

  • 0 = never suppress generated response pages
  • 1 = always suppress generated response pages
  • 2 = suppress response pages only for intercepted traffic
proxy.config.http_ui_enabled
Scope:CONFIG
Type:INT
Default:0

Enable the user interface page.

DNS
proxy.config.dns.search_default_domains
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) local domain expansion.

Traffic Server can attempt to resolve unqualified hostnames by expanding to the local domain. For example if a client makes a request to an unqualified host (host_x) and the Traffic Server local domain is y.com , then Traffic Server will expand the hostname to host_x.y.com.

proxy.config.dns.splitDNS.enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) DNS server selection. When enabled, Traffic Server refers to the splitdns.config file for the selection specification. Refer to Configuring DNS Server Selection (Split DNS).

proxy.config.dns.url_expansions
Scope:CONFIG
Type:STRING
Default:NULL

Specifies a list of hostname extensions that are automatically added to the hostname after a failed lookup. For example: if you want Traffic Server to add the hostname extension .org, then specify org as the value for this variable (Traffic Server automatically adds the dot (.)).

注解

If the variable proxy.config.http.enable_url_expandomatic is set to 1 (the default value), then you do not have to add ``www.`` and ``.com`` to this list because Traffic Server automatically tries www. and .com after trying the values you’ve specified.

proxy.config.dns.resolv_conf
Scope:CONFIG
Type:STRING
Default:/etc/resolv.conf

Allows to specify which resolv.conf file to use for finding resolvers. While the format of this file must be the same as the standard resolv.conf file, this option allows an administrator to manage the set of resolvers in an external configuration file, without affecting how the rest of the operating system uses DNS.

proxy.config.dns.round_robin_nameservers
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) DNS server round-robin.

proxy.config.dns.nameservers
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The DNS servers.

proxy.config.srv_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Indicates whether to use SRV records for orgin server lookup.

proxy.config.dns.dedicated_thread
Scope:CONFIG
Type:INT
Default:0

Create and dedicate a thread entirely for DNS processing. This is probably most useful on system which do a significant number of DNS lookups, typically forward proxies. But even on other systems, it can avoid some contention on the first worker thread (which otherwise takes on the burden of all DNS lookups).

proxy.config.dns.validate_query_name
Scope:CONFIG
Type:INT
Default:0

When enabled (1) provides additional resilience against DNS forgery (for instance in DNS Injection attacks), particularly in forward or transparent proxies, but requires that the resolver populates the queries section of the response properly.

HostDB
proxy.config.hostdb.serve_stale_for
Scope:CONFIG
Type:INT
Default:*NONE*
Metric:seconds
Reloadable:Yes

The number of seconds for which to use a stale NS record while initiating a background fetch for the new data.

If not set then stale records are not served.

proxy.config.hostdb.storage_size
Scope:CONFIG
Type:INT
Default:33554432
Metric:bytes

The amount of space (in bytes) used to store hostdb. The value of this variable must be increased if you increase the size of the proxy.config.hostdb.size variable.

proxy.config.hostdb.size
Scope:CONFIG
Type:INT
Default:200000

The maximum number of entries that can be stored in the database.

注解

For values above 200000, you must increase proxy.config.hostdb.storage_size by at least 44 bytes per entry.

proxy.config.hostdb.ttl_mode
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

A host entry will eventually time out and be discarded. This variable controls how that time is calculated. A DNS request will return a TTL value and an internal value can be set with proxy.config.hostdb.timeout. This variable determines which value will be used.

Value TTL
0 The TTL from the DNS response.
1 The internal timeout value.
2 The smaller of the DNS and internal TTL values. The internal timeout value becomes a maximum TTL.
3 The larger of the DNS and internal TTL values. The internal timeout value become a minimum TTL.
proxy.config.hostdb.timeout
Scope:CONFIG
Type:INT
Default:1440
Metric:minutes
Reloadable:Yes

Internal time to live value for host DB entries, in minutes.

See proxy.config.hostdb.ttl_mode for when this value is used.

proxy.config.hostdb.strict_round_robin
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Set host resolution to use strict round robin.

When this and proxy.config.hostdb.timed_round_robin are both disabled (set to 0), Traffic Server always uses the same origin server for the same client, for as long as the origin server is available. Otherwise if this is set then IP address is rotated on every request. This setting takes precedence over proxy.config.hostdb.timed_round_robin.

proxy.config.hostdb.timed_round_robin
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Set host resolution to use timed round robin.

When this and proxy.config.hostdb.strict_round_robin are both disabled (set to 0), Traffic Server always uses the same origin server for the same client, for as long as the origin server is available. Otherwise if this is set to N the IP address is rotated if more than N seconds have past since the first time the current address was used.

proxy.config.hostdb.ip_resolve
Scope:CONFIG
Type:STRING
Default:ipv4;ipv6

Set the host resolution style.

This is an ordered list of keywords separated by semicolons that specify how a host name is to be resolved to an IP address. The keywords are case insensitive.

Keyword Meaning
ipv4 Resolve to an IPv4 address.
ipv6 Resolve to an IPv6 address.
client Resolve to the same family as the client IP address.
none Stop resolving.

The order of the keywords is critical. When a host name needs to be resolved it is resolved in same order as the keywords. If a resolution fails, the next option in the list is tried. The keyword none means to give up resolution entirely. The keyword list has a maximum length of three keywords, more are never needed. By default there is an implicit ipv4;ipv6 attached to the end of the string unless the keyword none appears.

Example

Use the incoming client family, then try IPv4 and IPv6.

client;ipv4;ipv6

Because of the implicit resolution this can also be expressed as just

client

Example

Resolve only to IPv4.

ipv4;none

Example

Resolve only to the same family as the client (do not permit cross family transactions).

client;none

This value is a global default that can be overridden by proxy.config.http.server_ports.

注解

This style is used as a convenience for the administrator. During a resolution the resolution order will be one family, then possibly the other. This is determined by changing client to ipv4 or ipv6 based on the client IP address and then removing duplicates.

重要

This option has no effect on outbound transparent connections The local IP address used in the connection to the origin server is determined by the client, which forces the IP address family of the address used for the origin server. In effect, outbound transparent connections always use a resolution style of “client”.

Logging Configuration
proxy.config.log.logging_enabled
Scope:CONFIG
Type:INT
Default:3
Reloadable:Yes

Enables and disables event logging:

  • 0 = logging disabled
  • 1 = log errors only
  • 2 = log transactions only
  • 3 = full logging (errors + transactions)

Refer to Working with Log Files.

proxy.config.log.max_secs_per_buffer
Scope:CONFIG
Type:INT
Default:5
Reloadable:Yes

The maximum amount of time before data in the buffer is flushed to disk.

proxy.config.log.max_space_mb_for_logs
Scope:CONFIG
Type:INT
Default:2500
Metric:megabytes
Reloadable:Yes

The amount of space allocated to the logging directory (in MB).

注解

All files in the logging directory contribute to the space used, even if they are not log files. In collation client mode, if there is no local disk logging, or proxy.config.log.max_space_mb_for_orphan_logs is set to a higher value than proxy.config.log.max_space_mb_for_logs, TS will take proxy.config.log.max_space_mb_for_orphan_logs for maximum allowed log space.

proxy.config.log.max_space_mb_for_orphan_logs
Scope:CONFIG
Type:INT
Default:25
Metric:megabytes
Reloadable:Yes

The amount of space allocated to the logging directory (in MB) if this node is acting as a collation client.

注解

When max_space_mb_for_orphan_logs is take as the maximum allowedlog space in the logging system, the same rule apply to proxy.config.log.max_space_mb_for_logs also apply to proxy.config.log.max_space_mb_for_orphan_logs, ie: All files in the logging directory contribute to the space used, even if they are not log files. you may need to consider this when you enable full remote logging, and bump to the same size as proxy.config.log.max_space_mb_for_logs.

proxy.config.log.max_space_mb_headroom
Scope:CONFIG
Type:INT
Default:10
Metric:megabytes
Reloadable:Yes

The tolerance for the log space limit (in megabytes). If the variable proxy.config.log.auto_delete_rolled_files is set to 1 (enabled), then autodeletion of log files is triggered when the amount of free space available in the logging directory is less than the value specified here.

proxy.config.log.hostname
Scope:CONFIG
Type:STRING
Default:localhost
Reloadable:Yes

The hostname of the machine running Traffic Server.

proxy.config.log.logfile_dir
Scope:CONFIG
Type:STRING
Default:var/log/trafficserver
Reloadable:Yes

The path to the logging directory. This can be an absolute path or a path relative to the PREFIX directory in which Traffic Server is installed.

注解

The directory you specify must already exist.

proxy.config.log.logfile_perm
Scope:CONFIG
Type:STRING
Default:rw-r–r–
Reloadable:Yes

The log file permissions. The standard UNIX file permissions are used (owner, group, other). Permissible values are:

- no permission r read permission w write permission x execute permission

Permissions are subject to the umask settings for the Traffic Server process. This means that a umask setting of002 will not allow write permission for others, even if specified in the configuration file. Permissions for existing log files are not changed when the configuration is changed.

proxy.config.log.custom_logs_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) custom logging.

proxy.config.log.squid_log_enabled
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) the squid log file format.

proxy.config.log.squid_log_is_ascii
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

The squid log file type:

  • 1 = ASCII
  • 0 = binary
proxy.config.log.squid_log_name
Scope:CONFIG
Type:STRING
Default:squid
Reloadable:Yes

The squid log filename.

proxy.config.log.squid_log_header
Scope:CONFIG
Type:STRING
Default:NULL

The squid log file header text.

proxy.config.log.common_log_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) the Netscape common log file format.

proxy.config.log.common_log_is_ascii
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

The Netscape common log file type:

  • 1 = ASCII
  • 0 = binary
proxy.config.log.common_log_name
Scope:CONFIG
Type:STRING
Default:common
Reloadable:Yes

The Netscape common log filename.

proxy.config.log.common_log_header
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The Netscape common log file header text.

proxy.config.log.extended_log_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) the Netscape extended log file format.

proxy.confg.log.extended_log_is_ascii
Scope:CONFIG
Type:INT
Default:1

The Netscape extended log file type:

  • 1 = ASCII
  • 0 = binary
proxy.config.log.extended_log_name
Scope:CONFIG
Type:STRING
Default:extended

The Netscape extended log filename.

proxy.config.log.extended_log_header
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The Netscape extended log file header text.

proxy.config.log.extended_log_is_ascii
Scope:CONFIG
Type:INT
Default:0

Set whether the extend log is written as ASCII (text) or binary.

proxy.config.log.extended2_log_enabled
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) the Netscape Extended-2 log file format.

proxy.config.log.extended2_log_is_ascii
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

The Netscape Extended-2 log file type:

  • 1 = ASCII
  • 0 = binary
proxy.config.log.extended2_log_name
Scope:CONFIG
Type:STRING
Default:extended2
Reloadable:Yes

The Netscape Extended-2 log filename.

proxy.config.log.extended2_log_header
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The Netscape Extended-2 log file header text.

proxy.config.log.separate_icp_logs
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), configures Traffic Server to store ICP transactions in a separate log file.

  • 0 = separation is disabled, all ICP transactions are recorded in the same file as HTTP transactions
  • 1 = all ICP transactions are recorded in a separate log file.
  • -1 = filter all ICP transactions from the default log files; ICP transactions are not logged anywhere.
proxy.config.log.separate_host_logs
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), configures Traffic Server to create a separate log file for HTTP transactions for each origin server listed in the log_hosts.config file. Refer to HTTP Host Log Splitting.

proxy.local.log.collation_mode
Scope:LOCAL
Type:INT
Default:0
Reloadable:Yes

Set the log collation mode.

Value Effect
0 collation is disabled
1 this host is a log collation server
2 this host is a collation client and sends entries using standard formats to the collation server
3 this host is a collation client and sends entries using the traditional custom formats to the collation server
4 this host is a collation client and sends entries that use both the standard and traditional custom formats to the collation server

For information on sending XML-based custom formats to the collation server, refer to logs_xml.config.

注解

Although Traffic Server supports traditional custom logging, you should use the more versatile XML-based custom formats.

proxy.config.log.collation_host
Scope:CONFIG
Type:STRING
Default:NULL

The hostname of the log collation server.

proxy.config.log.collation_port
Scope:CONFIG
Type:INT
Default:8085
Reloadable:Yes

The port used for communication between the collation server and client.

proxy.config.log.collation_secret
Scope:CONFIG
Type:STRING
Default:foobar
Reloadable:Yes

The password used to validate logging data and prevent the exchange of unauthorized information when a collation server is being used.

proxy.config.log.collation_host_tagged
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

When enabled (1), configures Traffic Server to include the hostname of the collation client that generated the log entry in each entry.

proxy.config.log.collation_retry_sec
Scope:CONFIG
Type:INT
Default:5
Reloadable:Yes

The number of seconds between collation server connection retries.

proxy.config.log.rolling_enabled
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Specifies how log files are rolled. You can specify the following values:

  • 0 = disables log file rolling

  • 1 = enables log file rolling at specific intervals during the day (specified with the

    proxy.config.log.rolling_interval_sec and proxy.config.log.rolling_offset_hr variables)

  • 2 = enables log file rolling when log files reach a specific size (specified with the proxy.config.log.rolling_size_mb variable)

  • 3 = enables log file rolling at specific intervals during the day or when log files reach a specific size (whichever occurs first)

  • 4 = enables log file rolling at specific intervals during the day when log files reach a specific size (i.e., at a specified

    time if the file is of the specified size)

proxy.config.log.rolling_interval_sec
Scope:CONFIG
Type:INT
Default:86400
Reloadable:Yes

The log file rolling interval, in seconds. The minimum value is 300 (5 minutes). The maximum, and default, value is 86400 seconds (one day).

注解

If you start Traffic Server within a few minutes of the next rolling time, then rolling might not occur until the next rolling time.

proxy.config.log.rolling_offset_hr
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

The file rolling offset hour. The hour of the day that starts the log rolling period.

proxy.config.log.rolling_size_mb
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

The size that log files must reach before rolling takes place.

proxy.config.log.auto_delete_rolled_files
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) automatic deletion of rolled files.

proxy.config.log.sampling_frequency
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Configures Traffic Server to log only a sample of transactions rather than every transaction. You can specify the following values:

  • 1 = log every transaction
  • 2 = log every second transaction
  • 3 = log every third transaction and so on...
proxy.config.http.slow.log.threshold
Scope:CONFIG
Type:INT
Default:0
Metric:milliseconds
Reloadable:Yes

If set to a non-zero value N then any connection that takes longer than N milliseconds from accept to completion will cause its timing stats to be written to the debugging log file. This is identifying data about the transaction and all of the transaction milestones.

Diagnostic Logging Configuration
proxy.config.diags.output.diag
Scope:CONFIG
Type:STRING
Default:E
proxy.config.diags.output.debug
Scope:CONFIG
Type:STRING
Default:E
proxy.config.diags.output.status
Scope:CONFIG
Type:STRING
Default:L
proxy.config.diags.output.note
Scope:CONFIG
Type:STRING
Default:L
proxy.config.diags.output.warning
Scope:CONFIG
Type:STRING
Default:L
proxy.config.diags.output.error
Scope:CONFIG
Type:STRING
Default:SL
proxy.config.diags.output.fatal
Scope:CONFIG
Type:STRING
Default:SL
proxy.config.diags.output.alert
Scope:CONFIG
Type:STRING
Default:L
proxy.config.diags.output.emergency
Scope:CONFIG
Type:STRING
Default:SL

The diagnosic output configuration variables control where Traffic Server should log diagnostic output. Messages at each diagnostic level can be directed to any combination of diagnostic destinations. Valid diagnostic message destinations are:

  • ‘O’ = Log to standard output
  • ‘E’ = Log to standard error
  • ‘S’ = Log to syslog
  • ‘L’ = Log to diags.log

Example

To log debug diagnostics to both syslog and diags.log:

CONFIG proxy.config.diags.output.debug STRING SL
proxy.config.diags.show_location
Scope:CONFIG
Type:INT
Default:0

Annotates diagnostic messages with the source code location.

proxy.config.diags.debug.enabled
Scope:CONFIG
Type:INT
Default:0

Enables logging for diagnostic messages whose log level is diag or debug.

proxy.config.diags.debug.tags
Scope:CONFIG
Type:STRING
Default:NULL

Each Traffic Server diag and debug level message is annotated with a subsytem tag. This configuration contains a regular expression that filters the messages based on the tag. Some commonly used debug tags are:

Tag Subsytem usage
ssl TLS termination and certificate processing
dns DNS query resolution
http_hdrs Logs the headers for HTTP requests and responses
Traffic Server plugins will typically log debug messages using the TSDebug() API, passing the plugin name as the debug tag.
Reverse Proxy
proxy.config.reverse_proxy.enabled
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Enables (1) or disables (0) HTTP reverse proxy.

proxy.config.header.parse.no_host_url_redirect
Scope:CONFIG
Type:STRING
Default:NULL
Reloadable:Yes

The URL to which to redirect requests with no host headers (reverse proxy).

URL Remap Rules
proxy.config.url_remap.filename
Scope:CONFIG
Type:STRING
Default:remap.config

Sets the name of the remap.config file.

proxy.config.url_remap.default_to_server_pac
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) requests for a PAC file on the proxy service port (8080 by default) to be redirected to the PAC port. For this type of redirection to work, the variable proxy.config.reverse_proxy.enabled must be set to 1.

proxy.config.url_remap.default_to_server_pac_port
Scope:CONFIG
Type:INT
Default:-1
Reloadable:Yes

Sets the PAC port so that PAC requests made to the Traffic Server proxy service port are redirected this port. -1 is the default setting that sets the PAC port to the autoconfiguration port (the default autoconfiguration port is 8083). This variable can be used together with the proxy.config.url_remap.default_to_server_pac variable to get a PAC file from a different port. You must create and run a process that serves a PAC file on this port. For example: if you create a Perl script that listens on port 9000 and writes a PAC file in response to any request, then you can set this variable to 9000. Browsers that request the PAC file from a proxy server on port 8080 will get the PAC file served by the Perl script.

proxy.config.url_remap.remap_required
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Set this variable to 1 if you want Traffic Server to serve requests only from origin servers listed in the mapping rules of the remap.config file. If a request does not match, then the browser will receive an error.

proxy.config.url_remap.pristine_host_hdr
Scope:CONFIG
Type:INT
Default:1
Reloadable:Yes

Set this variable to 1 if you want to retain the client host header in a request during remapping.

SSL Termination
proxy.config.ssl.SSLv2
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) SSLv2. Please don’t enable it.

proxy.config.ssl.SSLv3
Scope:CONFIG
Type:INT
Default:1

Enables (1) or disables (0) SSLv3.

proxy.config.ssl.TLSv1
Scope:CONFIG
Type:INT
Default:1

Enables (1) or disables (0) TLSv1.

proxy.config.ssl.TLSv1_1
Scope:CONFIG
Type:INT
Default:1

Enables (1) or disables (0) TLS v1.1. If not specified, enabled by default. [Requires OpenSSL v1.0.1 and higher]

proxy.config.ssl.TLSv1_2
Scope:CONFIG
Type:INT
Default:1

Enables (1) or disables (0) TLS v1.2. If not specified, DISABLED by default. [Requires OpenSSL v1.0.1 and higher]

proxy.config.ssl.client.certification_level
Scope:CONFIG
Type:INT
Default:0

Sets the client certification level:

  • 0 = no client certificates are required. Traffic Server does

    not verify client certificates during the SSL handshake. Access to Traffic Server depends on Traffic Server configuration options (such as access control lists).

  • 1 = client certificates are optional. If a client has a

    certificate, then the certificate is validated. If the client does not have a certificate, then the client is still allowed access to Traffic Server unless access is denied through other Traffic Server configuration options.

  • 2 = client certificates are required. The client must be

    authenticated during the SSL handshake. Clients without a certificate are not allowed to access Traffic Server.

proxy.config.ssl.server.multicert.filename
Scope:CONFIG
Type:STRING
Default:ssl_multicert.config

The location of the ssl_multicert.config file, relative to the Traffic Server configuration directory. In the following example, if the Traffic Server configuration directory is /etc/trafficserver, the Traffic Server SSL configuration file and the corresponding certificates are located in /etc/trafficserver/ssl:

CONFIG proxy.config.ssl.server.multicert.filename STRING ssl/ssl_multicert.config
CONFIG proxy.config.ssl.server.cert.path STRING etc/trafficserver/ssl
CONFIG proxy.config.ssl.server.private_key.path STRING etc/trafficserver/ssl
proxy.config.ssl.server.cert.path
Scope:CONFIG
Type:STRING
Default:/config

The location of the SSL certificates and chains used for accepting and validation new SSL sessions. If this is a relative path, it is appended to the Traffic Server installation PREFIX. All certificates and certificate chains listed in ssl_multicert.config will be loaded relative to this path.

proxy.config.ssl.server.private_key.path
Scope:CONFIG
Type:STRING
Default:NULL

The location of the SSL certificate private keys. Change this variable only if the private key is not located in the SSL certificate file. All private keys listed in ssl_multicert.config will be loaded relative to this path.

proxy.config.ssl.server.cert_chain.filename
Scope:CONFIG
Type:STRING
Default:NULL

The name of a file containing a global certificate chain that should be used with every server certificate. This file is only used if there are certificates defined in ssl_multicert.config. Unless this is an absolute path, it is loaded relative to the path specified by proxy.config.ssl.server.cert.path.

proxy.config.ssl.CA.cert.path
Scope:CONFIG
Type:STRING
Default:NULL

The location of the certificate authority file that client certificates will be verified against.

proxy.config.ssl.CA.cert.filename
Scope:CONFIG
Type:STRING
Default:NULL

The filename of the certificate authority that client certificates will be verified against.

proxy.config.ssl.auth.enabled
Scope:CONFIG
Type:INT
Default:0

TBD

proxy.config.ssl.max_record_size
Scope:CONFIG
Type:INT
Default:0

This configuration specifies the maximum number of bytes to write into a SSL record when replying over a SSL session. In some circumstances this setting can improve response latency by reducing buffering at the SSL layer. The default of 0 means to always write all available data into a single SSL record.

proxy.config.ssl.session_cache.timeout
Scope:CONFIG
Type:INT
Default:0

This configuration specifies the lifetime of SSL session cache entries in seconds. If it is 0, then the SSL library will use a default value, typically 300 seconds.

proxy.config.ssl.hsts_max_age
Scope:CONFIG
Type:INT
Default:-1

This configuration specifies the max-age value that will be used when adding the Strict-Transport-Security header. The value is in seconds. A value of 0 will set the max-age value to 0 and should remove the HSTS entry from the client. A value of -1 will disable this feature and not set the header. This option is only used for HTTPS requests and the header will not be set on HTTP requests.

proxy.config.ssl.hsts_include_subdomains
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) adding the includeSubdomain value to the Strict-Transport-Security header. proxy.config.ssl.hsts_max_age needs to be set to a non -1 value for this configuration to take effect.

proxy.config.ssl.allow_client_renegotiation
Scope:CONFIG
Type:INT
Default:0

This configuration specifies whether the client is able to initiate renegotiation of the SSL connection. The default of 0, means the client can’t initiate renegotiation.

proxy.config.ssl.cert.load_elevated
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) elevation of traffic_server privileges during loading of SSL certificates. By enabling this, SSL certificate files’ access rights can be restricted to help reduce the vulnerability of certificates.

ICP Configuration
proxy.config.icp.enabled
Scope:CONFIG
Type:INT
Default:0

Sets ICP mode for hierarchical caching:

  • 0 = disables ICP
  • 1 = allows Traffic Server to receive ICP queries only
  • 2 = allows Traffic Server to send and receive ICP queries

Refer to ICP Peering.

proxy.config.icp.icp_interface
Scope:CONFIG
Type:STRING
Default:your_interface

Specifies the network interface used for ICP traffic.

注解

The Traffic Server installation script detects your network interface and sets this variable appropriately. If your system has multiple network interfaces, check that this variable specifies the correct interface.

proxy.config.icp.icp_port
Scope:CONFIG
Type:INT
Default:3130
Reloadable:Yes

Specifies the UDP port that you want to use for ICP messages.

proxy.config.icp.query_timeout
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

Specifies the timeout used for ICP queries.

Scheduled Update Configuration
proxy.config.update.enabled
Scope:CONFIG
Type:INT
Default:0

Enables (1) or disables (0) the Scheduled Update option.

proxy.config.update.force
Scope:CONFIG
Type:INT
Default:0
Reloadable:Yes

Enables (1) or disables (0) a force immediate update. When enabled, Traffic Server overrides the scheduling expiration time for all scheduled update entries and initiates updates until this option is disabled.

proxy.config.update.retry_count
Scope:CONFIG
Type:INT
Default:10
Reloadable:Yes

Specifies the number of times Traffic Server can retry the scheduled update of a URL in the event of failure.

proxy.config.update.retry_interval
Scope:CONFIG
Type:INT
Default:2
Reloadable:Yes

Specifies the delay (in seconds) between each scheduled update retry for a URL in the event of failure.

proxy.config.update.concurrent_updates
Scope:CONFIG
Type:INT
Default:100
Reloadable:Yes

Specifies the maximum simultaneous update requests allowed at any time. This option prevents the scheduled update process from overburdening the host.

Plug-in Configuration
proxy.config.plugin.plugin_dir
Scope:CONFIG
Type:STRING
Default:config/plugins

Specifies the location of Traffic Server plugins.

proxy.config.remap.num_remap_threads
Scope:CONFIG
Type:INT
Default:0

When this variable is set to 0, plugin remap callbacks are executed in line on network threads. If remap processing takes significant time, this can be cause additional request latency. Setting this variable to causes remap processing to take place on a dedicated thread pool, freeing the network threads to service additional requests.

Sockets
proxy.config.net.defer_accept
Scope:CONFIG
Type:INT
Default:`1`

default: 1 meaning on all Platforms except Linux: 45 seconds

This directive enables operating system specific optimizations for a listening socket. defer_accept holds a call to accept(2) back until data has arrived. In Linux’ special case this is up to a maximum of 45 seconds.

proxy.config.net.sock_send_buffer_size_in
Scope:CONFIG
Type:INT
Default:0

Sets the send buffer size for connections from the client to Traffic Server.

proxy.config.net.sock_recv_buffer_size_in
Scope:CONFIG
Type:INT
Default:0

Sets the receive buffer size for connections from the client to Traffic Server.

proxy.config.net.sock_option_flag_in
Scope:CONFIG
Type:INT
Default:0

Turns different options “on” for the socket handling client connections::

TCP_NODELAY (1)
SO_KEEPALIVE (2)

注解

This is a flag and you look at the bits set. Therefore, you must set the value to 3 if you want to enable both options above.

proxy.config.net.sock_send_buffer_size_out
Scope:CONFIG
Type:INT
Default:0

Sets the send buffer size for connections from Traffic Server to the origin server.

proxy.config.net.sock_recv_buffer_size_out
Scope:CONFIG
Type:INT
Default:0

Sets the receive buffer size for connections from Traffic Server to the origin server.

proxy.config.net.sock_option_flag_out
Scope:CONFIG
Type:INT
Default:1

Turns different options “on” for the origin server socket::

TCP_NODELAY (1)
SO_KEEPALIVE (2)

注解

This is a flag and you look at the bits set. Therefore, you must set the value to 3 if you want to enable both options above.

proxy.config.net.sock_mss_in
Scope:CONFIG
Type:INT
Default:0

Same as the command line option --accept_mss that sets the MSS for all incoming requests.

proxy.config.net.poll_timeout
Scope:CONFIG
Type:INT
Default:10 (or 30 on Solaris)

Same as the command line option --poll_timeout, or -t, which specifies the timeout used for the polling mechanism used. This timeout is always in milliseconds (ms). This is the timeout to epoll_wait() on Linux platforms, and to kevent() on BSD type OSs. The default value is 10 on all platforms.

Changing this configuration can reduce CPU usage on an idle system, since periodic tasks gets processed at these intervals. On busy servers, this overhead is diminished, since polled events triggers morefrequently. However, increasing the setting can also introduce additional latency for certain operations, and timed events. It’s recommended not to touch this setting unless your CPU usage is unacceptable at idle workload. Some alternatives to this could be:

Reduce the number of worker threads (net-threads)
Reduce the number of disk (AIO) threads
Make sure accept threads are enabled

The relevant configurations for this are:

CONFIG proxy.config.exec_thread.autoconfig INT 0
CONFIG proxy.config.exec_thread.limit INT 2
CONFIG proxy.config.accept_threads INT 1
CONFIG proxy.config.cache.threads_per_disk INT 8
Undocumented

These are referenced but not documented. Please contribute a definition.

proxy.config.task_threads
Scope:CONFIG
Type:INT
Default:0
proxy.config.http.enabled
Scope:CONFIG
Type:INT
Default:1

remap.config

The remap.config file (by default, located in /opt/trafficserver/etc/trafficserver/) contains mapping rules that Traffic Server uses to perform the following actions:

  • Map URL requests for a specific origin server to the appropriate location on Traffic Server when Traffic Server acts as a reverse proxy for that particular origin server
  • Reverse-map server location headers so that when origin servers respond to a request with a location header that redirects the client to another location, the clients do not bypass Traffic Server
  • Redirect HTTP requests permanently or temporarily without Traffic Server having to contact any origin servers

Refer to Reverse Proxy and HTTP Redirects, for information about redirecting HTTP requests and using reverse proxy.

After you modify the remap.config run the traffic_line -x to apply the changes. When you apply the changes to one node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the remap.config file must contain a mapping rule. Empty lines, or lines starting with # are ignored. Each line can be broken up into multiple lines for better readability by using \ as continuation marker.

Traffic Server recognizes three space-delimited fields: type, target, and replacement. The following list describes the format of each field.

type

Enter one of the following:

  • map –translates an incoming request URL to the appropriate origin server URL.
  • map_with_recv_port –exactly like ‘map’ except that it uses the port at which the request was received to perform the mapping instead of the port present in the request. The regex qualifier can also be used for this type. When present, ‘map_with_recv_port’ mappings are checked first. If there is a match, then it is chosen without evaluating the “regular” forward mapping rules.
  • map_with_referer – extended version of ‘map’, which can be used to activate “deep linking protection”, where target URLs are only accessible when the Referer header is set to a URL that is allowed to link to the target.
  • reverse_map –translates the URL in origin server redirect responses to point to the Traffic Server.
  • redirect –redirects HTTP requests permanently without having to contact the origin server. Permanent redirects notify the browser of the URL change (by returning an HTTP status code 301) so that the browser can update bookmarks.
  • redirect_temporary –redirects HTTP requests temporarily without having to contact the origin server. Temporary redirects notify the browser of the URL change for the current request only (by returning an HTTP status code 307).
target

Enter the origin (“from”) URL. You can enter up to four components:

scheme://host:port/path_prefix

where scheme is http.

replacement

Enter the origin (“from”) URL. You can enter up to four components:

scheme://host:port/path_prefix

where scheme can be http or https.

Precedence

Remap rules are not processed top-down, but based on an internal priority

  1. map_with_recv_port
  2. map and reverse_map
  3. regex_map
  4. redirect and redirect_temporary
  5. regex_redirect and regex_redirect_temporary
Match-All

A map rule with a single / acts as a wildcard, it will match any request. This should be use with care, and certainly only once at the end of the remap.config file. E.g.

map / http://all.example.com
Examples

The following section shows example mapping rules in the remap.config file.

Reverse Proxy Mapping Rules

The following example shows a map rule that does not specify a path prefix in the target or replacement:

map http://www.x.com/ http://server.hoster.com/
reverse_map http://server.hoster.com/ http://www.x.com/

This rule results in the following translations:

Client Request Translated Request
http://www.x.com/Widgets/index.html http://server.hoster.com/Widgets/index.html
http://www.x.com/cgi/form/submit.sh?arg=true http://server.hoster.com/cgi/form/submit.sh?arg=true

The following example shows a map rule with path prefixes specified in the target:

map http://www.y.com/marketing/ http://marketing.y.com/
reverse_map http://marketing.y.com/ http://www.y.com/marketing/
map http://www.y.com/sales/ http://sales.y.com/
reverse_map http://sales.y.com/ http://www.y.com/sales/
map http://www.y.com/engineering/ http://engineering.y.com/
reverse_map http://engineering.y.com/ http://www.y.com/engineering/
map http://www.y.com/stuff/ http://info.y.com/
reverse_map http://info.y.com/ http://www.y.com/stuff/

These rules result in the following translations:

Client Request Translated Request
http://www.y.com/marketing/projects/manhattan/specs.html http://marketing.y.com/projects/manhattan/specs.html
http://www.y.com/stuff/marketing/projects/boston/specs.html http://info.y.com/marketing/projects/boston/specs.html
http://www.y.com/engineering/marketing/requirements.html http://engineering.y.com/marketing/requirements.html

The following example shows that the order of the rules matters:

map http://www.g.com/ http://external.g.com/
reverse_map http://external.g.com/ http://www.g.com/
map http://www.g.com/stuff/ http://stuff.g.com/
reverse_map http://stuff.g.com/ http://www.g.com/stuff/

These rules result in the following translation.

Client Request Translated Request
http://www.g.com/stuff/a.gif http://external.g.com/stuff/a.gif

In the above examples, the second rule is never applied because all URLs that match the second rule also match the first rule. The first rule takes precedence because it appears earlier in the remap.config file.

The following example shows a mapping with a path prefix specified in the target and replacement:

map http://www.h.com/a/b/ http://server.h.com/customers/x/y
reverse_map http://server.h.com/customers/x/y/ http://www.h.com/a/b/

This rule results in the following translation.

Client Request Translated Request
http://www.h.com/a/b/c/d/doc.html http://server.h.com/customers/x/y/c/d/doc.html
http://www.h.com/a/index.html Translation fails

The following example shows reverse-map rules:

map http://www.x.com/ http://server.hoster.com/x/
reverse_map http://server.hoster.com/x/ http://www.x.com/

These rules result in the following translations.

Client Request Translated Request
http://www.x.com/Widgets http://server.hoster.com/x/Widgets
Client Request Origin Server Header Translated Request
http://www.x.com/Widgets http://server.hoster.com/x/Widgets/ http://www.x.com/Widgets/

When acting as a reverse proxy for multiple servers, Traffic Server is unable to route to URLs from older browsers that do not send the Host: header. As a solution, set the variable proxy.config.header.parse.no_host_url_redirect in the records.config file to the URL to which Traffic Server will redirect requests without host headers.

Redirect Mapping Rules

The following rule permanently redirects all HTTP requests for www.company.com to www.company2.com:

redirect http://www.company.com/ http://www.company2.com/

The following rule temporarily redirects all HTTP requests for www.company1.com to www.company2.com:

redirect_temporary http://www.company1.com/ http://www.company2.com/
Regular Expression (regex) Remap Support

Regular expressions can be specified in remapping rules, with the limitations below:

  • Only the host field can contain a regex; the scheme, port, and other fields cannot. For path manipulation via regexes, use the regex_remap plugin.
  • The number of capturing subpatterns is limited to 9. This means that $0 through $9 can be used as subtraction placeholders ($0 will be the entire input string).
  • The number of substitutions in the expansion string is limited to 10.
  • There is no regex_ equivalent to reverse_remap, so when using regex_remap you should make sure the reverse path is clear by setting (proxy.config.url_remap.pristine_host_hdr)
Examples
regex_map http://x([0-9]+).z.com/ http://real-x$1.z.com/
regex_redirect http://old.(.*).z.com http://new.$1.z.com
map_with_referer

the format of is the following:

map_with_referer client-URL origin-server-URL redirect-URL regex1 [regex2 ...]

‘redirect-URL’ is a redirection URL specified according to RFC 2616 and can contain special formatting instructions for run-time modifications of the resulting redirection URL. All regexes Perl compatible regular expressions, which describes the content of the “Referer” header which must be verified. In case an actual request does not have “Referer” header or it does not match with referer regular expression, the HTTP request will be redirected to ‘redirect-URL’.

At least one regular expressions must be specified in order to activate ‘deep linking protection’. There are limitations for the number of referer regular expression strings - 2048. In order to enable the ‘deep linking protection’ feature in Traffic Server, configure records.config with:

CONFIG proxy.config.http.referer_filter INT 1

In order to enable run-time formatting for redirect URL, configure:

CONFIG proxy.config.http.referer_format_redirect INT 1

When run-time formatting for redirect-URL was enabled the following format symbols can be used:

%r - to substitute original "Referer" header string
%f - to substitute client-URL from 'map_with_referer' record
%t - to substitute origin-server-URL from 'map_with_referer' record
%o - to substitute request URL to origin server, which was created a
     the result of a mapping operation

Note: There is a special referer type “~*” that can be used in order to specify that the Referer header is optional in the request. If “~*” referer was used in map_with_referer mapping, only requests with Referer header will be verified for validity. If the “~” symbol was specified before referer regular expression, it means that the request with a matching referer header will be redirected to redirectURL. It can be used to create a so-called negative referer list. If “*” was used as a referer regular expression - all referers are allowed. Various combinations of “*” and “~” in a referer list can be used to create different filtering rules.

map_with_referer Examples
map_with_referer http://y.foo.bar.com/x/yy/  http://foo.bar.com/x/yy/ http://games.bar.com/new_games .*\.bar\.com www.bar-friends.com

Explanation: Referer header must be in the request, only ”.*.bar.com” and “www.bar-friends.com” are allowed.

map_with_referer http://y.foo.bar.com/x/yy/  http://foo.bar.com/x/yy/ http://games.bar.com/new_games * ~.*\.evil\.com

Explanation: Referer header must be in the request but all referers are allowed except ”.*.evil.com”.

map_with_referer http://y.foo.bar.com/x/yy/  http://foo.bar.com/x/yy/ http://games.bar.com/error ~* * ~.*\.evil\.com

Explanation: Referer header is optional. However, if Referer header exists, only request from ”.*.evil.com” will be redirected to redirect-URL.

Plugin Chaining

Plugins can be configured to be evaluated in a specific order, passing the results from one in to the next (unless a plugin returns 0, then the “chain” is broken).

Examples
map http://url/path http://url/path \
    @plugin=/etc/traffic_server/config/plugins/plugin1.so @pparam=1 @pparam=2 \
    @plugin=/etc/traffic_server/config/plugins/plugin2.so @pparam=3

will pass “1” and “2” to plugin1.so and “3” to plugin2.so.

This will pass “1” and “2” to plugin1.so and “3” to plugin2.so

Named Filters

Named filters can be created and applied to blocks of mappings using the .definefilter, .activatefilter, and .deactivatefilter directives. Named filters must be defined using .definefilter before being used. Once defined, .activatefilter can used to activate a filter for all mappings that follow until deactivated with .deactivatefilter.

Examples
.definefilter disable_delete_purge @action=deny @method=delete @method=purge
.definefilter internal_only @action=allow @src_ip=192.168.0.1-192.168.0.254 @src_ip=10.0.0.1-10.0.0.254

.activatefilter disable_delete_purge

map http://foo.example.com/ http://bar.example.com/

.activatefilter internal_only
map http://www.example.com/admin http://internal.example.com/admin
.deactivatefilter internal_only

map http://www.example.com/ http://internal.example.com/

The filter disable_delete_purge will be applied to all of the mapping rules. (It is activated before any mappings and is never deactivated.) The filter internal_only will only be applied to the second mapping.

Including Additional Remap Files

The .include directive allows mapping rules to be spread across multiple files. The argument to the .include directive is a list of file names to be parsed for additional mapping rules. Unless the names are absolute paths, they are resolved relative to the Traffic Server configuration directory.

The effect of the .include directive is as if the contents of the listed files is included in the parent and parsing restarted at the point of inclusion. This means that and filters named in the included files are global in scope, and that additional .include directives are allowed.

注解

Included remap files are not currently tracked by the configuration subsystem. Changes to included remap files will not be noticed by online configuration changes applied by traffic_line -x unless remap.config has also changed.

Examples

In this example, a top-level remap.config file simply references additional mapping rules files

.include filters.config
.include one.example.com.config two.example.com.config

The file filters.config contains

.definefilter deny_purge @action=deny @method=purge
.definefilter allow_purge @action=allow @method=purge

The file one.example.com.config contains:

.activatefilter deny_purge
map http://one.example.com http://origin-one.example.com
.deactivatefilter deny_purge

The file two.example.com.config contains:

.activatefilter allow_purge
map http://two.example.com http://origin-two.example.com
.deactivatefilter dallowpurge

splitdns.config

The splitdns.config file enables you to specify the DNS server that Traffic Server should use for resolving hosts under specific conditions. For more information, refer to Configuring DNS Server Selection (Split DNS).

To specify a DNS server, you must supply the following information in each active line within the file:

  • A primary destination specifier in the form of a destination domain, a destination host, or a URL regular expression
  • A set of server directives, listing one or more DNS servers with corresponding port numbers

You can also include the following optional information with each DNS server specification:

  • A default domain for resolving hosts
  • A search list specifying the domain search order when multiple domains are specified

After you modify the splitdns.config file, run the traffic_line -x command to apply the changes. When you apply changes to a node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Format

Each line in the splitdns.config file uses one of the following formats:

dest_domain=dest_domain | dest_host | url_regex named=dns_server def_domain=def_domain search_list=search_list

The following list describes each field.

dest_domain
A valid domain name. This specifies that DNS server selection will be based on the destination domain. You can prefix the domain with an exclamation mark (!) to indicate the NOT logical operator.
dest_host
A valid hostname. This specifies that DNS server selection will be based on the destination host. You can prefix the host with an exclamation mark (!) to indicate the NOT logical operator.
url_regex
A valid URL regular expression. This specifies that DNS server selection will be based on a regular expression.
dns_server

This is a required directive. It identifies the DNS server that Traffic Server should use with the given destination specifier. You can specify a port using a colon (:). If you do not specify a port, then 53 is used. Specify multiple DNS servers with spaces or semicolons (;) as separators.

You must specify the domains with IP addresses in CIDR (“dot”) notation.

def_domain
A valid domain name. This optional directive specifies the default domain name to use for resolving hosts. Only one entry is allowed. If you do not provide the default domain, the system determines its value from /etc/resolv.conf
search_list
A list of domains separated by spaces or semicolons (;). This specifies the domain search order. If you do not provide the search list, the system determines the value from resolv.conf(5)
Examples

Consider the following DNS server selection specifications:

dest_domain=internal.company.com named=255.255.255.255:212 255.255.255.254 def_domain=company.com search_list=company.com company1.com
dest_domain=!internal.company.com named=255.255.255.253

Now consider the following two requests:

http://minstar.internal.company.com

This request matches the first line and therefore selects DNS server 255.255.255.255 on port 212. All resolver requests use company.com as the default domain, and company.com and company1.com as the set of domains to search first.

http://www.microsoft.com

This request matches the second line. Therefore, Traffic Server selects DNS server 255.255.255.253. Because no def_domain or search_list was supplied, Traffic Server retrieves this information from resolv.conf(5)

ssl_multicert.config

The ssl_multicert.config file lets you configure Traffic Server to use multiple SSL server certificates to terminate the SSL sessions. If you have a Traffic Server system with more than one IP address assigned to it, then you can assign a different SSL certificate to be served when a client requests a particular IP address or host name.

At configuration time, certificates are parsed to extract the certificate subject and all the DNS subject alternative names. A certificate will be presented for connections requesting any of the hostnames found in the certificate. Wildcard names are supported, but only of the form *.domain.com, ie. where * is the leftmost domain component.

Changes to ssl_multicert.config can be applied to a running Traffic Server using traffic_line -x.

Format

Each ssl_multicert.config line consists of a sequence of key=value fields that specify how Traffic Server should use a particular SSL certificate.

ssl_cert_name=FILENAME
The name of the file containing the TLS certificate. FILENAME is located relative to the directory specified by the proxy.config.ssl.server.cert.path configuration variable. This is the only field that is required to be present.
dest_ip=ADDRESS
The IP (v4 or v6) address that the certificate should be presented on. This is now only used as a fallback in the case that the TLS SubjectNameIndication extension is not supported. If ADDRESS is *, the corresponding certificate will be used as the global default fallback if no other match can be made. The address may contain a port specifier, in which case the corresponding certificate will only match for connections accepted on the specified port. IPv6 addresses must be enclosed by square brackets if they have a port, eg, [::1]:80.
ssl_key_name=FILENAME
The name of the file containing the private key for this certificate. If the key is contained in the certificate file, this field can be omitted, otherwise FILENAME is resolved relative to the proxy.config.ssl.server.private_key.path configuration variable.
ssl_ca_name=FILENAME
If the certificate is issued by an authority that is not in the system CA bundle, additional certificates may be needed to validate the certificate chain. FILENAME is resolved relative to the proxy.config.ssl.CA.cert.path configuration variable.
ssl_ticket_enabled=1|0
Enable RFC 5077 stateless TLS session tickets. To support this, OpenSSL should be upgraded to version 0.9.8f or higher. This option must be set to 0 to disable session ticket support.
ticket_key_name=FILENAME

The name of session ticket key file which contains a secret for encrypting and decrypting TLS session tickets. If FILENAME is not an absolute path, it is resolved relative to the proxy.config.ssl.server.cert.path configuration variable. This option has no effect if session tickets are disabled by the ssl_ticket_enabled option. The contents of the key file should be 48 random bytes.

Session ticket support is enabled by default. If neither of the ssl_ticket_enabled and ticket_key_name options are specified, and internal session ticket key is generated. This key will be different each time Traffic Server is started.

ssl_key_dialog=builtin|”exec:/path/to/program [args]”

Method used to provide a pass phrase for encrypted private keys. If the pass phrase is incorrect, SSL negotiation for this dest_ip will fail for clients who attempt to connect. Two options are supported: builtin and exec:

builtin - Requests pass phrase via stdin/stdout. User will be
provided the ssl_cert_name and be prompted for the pass phrase. Useful for debugging.
exec: - Executes program /path/to/program and passes args, if
specified, to the program and reads the output from stdout for the pass phrase. If args are provided then the entire exec: string must be quoted with “” (see examples). Arguments with white space are supported by single quoting (‘). The intent is that this program runs a security check to ensure that the system is not compromised by an attacker before providing the pass phrase.
Certificate Selection

Traffic Server attempts two certificate selections during SSL connection setup. An initial selection is made when a TCP connection is accepted. This selection examines the IP address and port that the client is connecting to and chooses the best certificate from the those that have a dest_ip specification. If no matching certificates are found, a default certificate is chosen. The final certificate selection is made during the SSL handshake. At this point, the client may use Server Name Indication to request a specific hostname. Traffic Server will use this request to select a certificate with a matching subject or subject alternative name. Failing that, a wildcard certificate match is attempted. If no match can be made, the initial certificate selection remains in force.

In all cases, Traffic Server attempts to select the most specific match. An address specification that contains a port number will take precedence over a specification that does not contain a port number. A specific certificate subject will take precedence over a wildcard certificate.

Examples

The following example configures Traffic Server to use the SSL certificate server.pem for all requests to the IP address 111.11.11.1 and the SSL certificate server1.pem for all requests to the IP address 11.1.1.1. Connections from all other IP addresses are terminated with the default.pem certificate. Since the private key is included in the certificate files, no private key name is specified.

dest_ip=111.11.11.1 ssl_cert_name=server.pem
dest_ip=11.1.1.1 ssl_cert_name=server1.pem
dest_ip=* ssl_cert_name=default.pem

The following example configures Traffic Server to use the SSL certificate server.pem and the private key serverKey.pem for all requests to port 8443 on IP address 111.11.11.1. The general.pem certificate is used for server name matches.

dest_ip=111.11.11.1:8443 ssl_cert_name=server.pem ssl_key_name=serverKey.pem ssl_cert_name=general.pem

The following example configures Traffic Server to use the SSL certificate server.pem for all requests to the IP address 111.11.11.1. Session tickets are enabled with a persistent ticket key.

dest_ip=111.11.11.1 ssl_cert_name=server.pem ssl_ticket_enabled=1 ticket_key_name=ticket.key

The following example configures Traffic Server to use the SSL certificate server.pem and disable session tickets for all requests to the IP address 111.11.11.1.

dest_ip=111.11.11.1 ssl_cert_name=server.pem ssl_ticket_enabled=0

The following examples configure Traffic Server to use the SSL certificate server.pem which includes an encrypted private key. The external program /usr/bin/mypass will be called on startup with one parameter (foo) in the first example, and with two parameters (foo) and (ba r) in the second example, the program (mypass) will return the pass phrase to decrypt the keys.

ssl_cert_name=server1.pem ssl_key_dialog="exec:/usr/bin/mypass foo"
ssl_cert_name=server2.pem ssl_key_dialog="exec:/usr/bin/mypass foo 'ba r'"

storage.config

The storage.config file (by default, located in /opt/trafficserver/etc/trafficserver/) lists all the files, directories, and/or hard disk partitions that make up the Traffic Server cache. After you modify the storage.config file, you must restart Traffic Server.

Format

The format of the storage.config file is:

pathname size volume=volume_number

where pathname is the name of a partition, directory or file, size is the size of the named partition, directory or file (in bytes), and volume is the volume number that is used in volume.config and hosting.config. You must specify a size for directories or files; size is optional for raw partitions. volume is optional.

You can use any partition of any size. For best performance:

  • Use raw disk partitions.
  • For each disk, make all partitions the same size.
  • For each node, use the same number of partitions on all disks.
  • Group similar kinds of storage into different volumes. For example split out SSD’s or RAM drives into their own volume.

Specify pathnames according to your operating system requirements. See the following examples. In the storage.config file, a formatted or raw disk must be at least 128 MB.

When using raw disk or partitions, you should make sure the Traffic Server user used by the Traffic Server process has read and write privileges on the raw disk device or partition. One good practice is to make sure the device file is set with ‘g+rw’ and the Traffic Server user is in the group which owns the device file. However, some operating systems have stronger requirements - see the following examples for more information.

As with standard records.config integers, human readable prefixes are also supported. They include

  • K Kilobytes (1024 bytes)
  • M Megabytes (1024^2 or 1,048,576 bytes)
  • G Gigabytes (1024^3 or 1,073,741,824 bytes)
  • T Terabytes (1024^4 or 1,099,511,627,776 bytes)
Examples

The following basic example shows 128 MB of cache storage in the /big_dir directory:

/big_dir 134217728

You can use the . symbol for the current directory. Here is an example for 64 MB of cache storage in the current directory:

. 134217728

As an alternative, using the human readable prefixes, you can express a 64GB cache file with:

/really_big_dir 64G

注解

When using on-filesystem cache disk storage, you can only have one such directory specified. This will be address in a future version.

Solaris Example

The following example is for the Solaris operating system:

/dev/rdsk/c0t0d0s5
/dev/rdsk/c0t0d1s5

注解

Size is optional. If not specified, the entire partition is used.

Linux Example

The following example will use an entire raw disk in the Linux operating system:

/dev/sde volume=1
/dev/sdf volume=2

In order to make sure traffic_server will have access to this disk you can use udev(7) to persistently set the right permissions. The following rules are targeted for an Ubuntu system, and stored in /etc/udev/rules.d/51-cache-disk.rules:

# Assign /dev/sde and /dev/sdf to the tserver group
# make the assignment final, no later changes allowed to the group!
SUBSYSTEM=="block", KERNEL=="sd[ef]", GROUP:="tserver"

In order to apply these settings, trigger a reload with udevadm(8)::

udevadm trigger --subsystem-match=block
FreeBSD Example

Starting with 5.1 FreeBSD dropped support for explicit raw devices. All devices on FreeBSD can be accessed raw now.

The following example will use an entire raw disk in the FreeBSD operating system:

/dev/ada1
/dev/ada2

In order to make sure traffic_server will have access to this disk you can use devfs(8) to persistently set the right permissions. The following rules are stored in devfs.conf(5):

# Assign /dev/ada1 and /dev/ada2 to the tserver user
own    ada[12]  tserver:tserver

update.config

The update.config file controls how Traffic Server performs a scheduled update of specific local cache content. The file contains a list of URLs specifying objects that you want to schedule for update.

A scheduled update performs a local HTTP GET on the objects at the specific time or interval. You can control the following parameters for each specified object:

  • The URL
  • URL-specific request headers, which overrides the default
  • The update time and interval
  • The recursion depth

After you modify the update.config file, run the traffic_line -x command to apply changes. When you apply changes to one node in a cluster, Traffic Server automatically applies the changes to all other nodes in the cluster.

Supported Tag/Attribute Pairs

Scheduled update supports the following tag/attribute pairs when performing recursive URL updates:

  • <a href=" ">
  • <img src=" ">
  • <img href=" ">
  • <body background=" ">
  • <frame src=" ">
  • <iframe src=" ">
  • <fig src=" ">
  • <overlay src=" ">
  • <applet code=" ">
  • <script src=" ">
  • <embed src=" ">
  • <bgsound src=" ">
  • <area href=" ">
  • <base href=" ">
  • <meta content=" ">

Scheduled update is designed to operate on URL sets consisting of hundreds of input URLs (expanded to thousands when recursive URLs are included); it is not intended to operate on extremely large URL sets, such as those used by Internet crawlers.

Format

Each line in the update.config file uses the following format:

URL\request_headers\offset_hour\interval\recursion_depth\

The following list describes each field.

URL
HTTP-based URLs.
request_headers
Optional. A list of headers, separated by semicolons, passed in each GET request. You can define any request header that conforms to the HTTP specification; the default is no request header.
offset_hour
The base hour used to derive the update periods. The range is 00-23 hours.
interval
The interval (in seconds) at which updates should occur, starting at the offset hour.
recursion_depth
The depth to which referenced URLs are recursively updated, starting at the given URL. This field applies only to HTTP.
Examples

An example HTTP scheduled update is provided below:

http://www.company.com\User-Agent: noname user agent\13\3600\5\

The example specifies the URL and request headers, an offset hour of 13 (1 pm), an interval of one hour, and a recursion depth of 5. This would result in updates at 13:00, 14:00, 15:00, and so on. To schedule an update that occurs only once a day, use an interval value 86400 (i.e., 24 hours x 60 minutes x 60 seconds = 86400).

Specifying URL Regular Expressions (url_regex)

This section describes how to specify a url_regex. Entries of type url_regex within the configuration files use regular expressions to perform a match.

The following list provides examples to show how to create a valid url_regex.

x
Matches the character x
.
Match any character
^
Specifies beginning of line
$
Specifies end of line
[xyz]
A character class. In this case, the pattern matches either x, y, orz
[abj-oZ]
A character class with a range. This pattern matches a, b, any letter from j through o, or Z
[^A-Z]
A negated character class. For example, this pattern matches any character except those in the class.
r*
Zero or more r, where r is any regular expression.
r+
One or more r, where r is any regular expression.
r?
Zero or one r, where r is any regular expression.
r{2,5}
From two to five r, where r is any regular expression.
r{2,}
Two or more r, where r is any regular expression.
r{4}
Exactly four r, where r is any regular expression.
"[xyz]\"images"
The literal string [xyz]"images"
\X
If X is a, b, f, n, r, t, or v, then the ANSI-C interpretation of \x; otherwise, a literal X. This is used to escape operators such as *
\0
A NULL character
\123
The character with octal value 123
\x2a
The character with hexadecimal value 2a
(r)
Matches an r, where r is any regular expression. You can use parentheses to override precedence.
rs
The regular expression r, followed by the regular expression s
r|s
Either an r or an s
#<n>#
Inserts an end node, which causes regular expression matching to stop when reached. The value n is returned.

You can specify dest_domain=mydomain.com to match any host in mydomain.com. Likewise, you can specify dest_domain=. to match any request.

volume.config

The volume.config file enables you to manage your cache space more efficiently and restrict disk usage by creating cache volumes of different sizes for specific protocols. You can further configure these volumes to store data from certain origin servers and/or domains in the hosting.config file.

重要

The volume configuration must be the same on all nodes in a cluster. You must stop Traffic Server before you change the cache volume size and protocol assignment. For step-by-step instructions about partitioning the cache, refer to Partitioning the Cache.

Format

For each volume you want to create, enter a line with the following format:

volume=volume_number  scheme=protocol_type  size=volume_size

where volume_number is a number between 1 and 255 (the maximum number of volumes is 255) and protocol_type is http. Traffic Server supports http for HTTP volume types; volume_size is the amount of cache space allocated to the volume. This value can be either a percentage of the total cache space or an absolute value. The absolute value must be a multiple of 128 MB, where 128 MB is the smallest value. If you specify a percentage, then the size is rounded down to the closest multiple of 128 MB.

Each volume is striped across several disks to achieve parallel I/O. For example: if there are four disks, then a 1-GB volume will have 256 MB on each disk (assuming each disk has enough free space available). If you do not allocate all the disk space in the cache, then the extra disk space is not used. You can use the extra space later to create new volumes without deleting and clearing the existing volumes.

Examples

The following example partitions the cache evenly between HTTP and HTTPS requests:

volume=1 scheme=http size=50%
volume=2 scheme=https size=50%

Command Reference

traffic_cop

Description

traffic_cop is a watchdog program that is responsible for starting traffic_manager and traffic_server and monitoring them for responsiveness. If either of these processes are determined to be unresponsive, traffic_cop will kill and restart them.

On Linux, traffic_cop will also monitor available memory and swap space, restarting the watched processes if the available memory falls below a minimum threshold. The memory thresholds can be configured with the proxy.config.cop.linux_min_swapfree_kb and proxy.config.cop.linux_min_memfree_kb variables.

The following options are available:

-d, --debug

Emit debugging messages.

-o, --stdout

traffic_cop ordinarily logs to syslog, however for debugging purposes, this option causes it to print messages to standard output instead.

-s, --stop

Kill children using SIGSTOP instead of SIGKILL. This option is primarily for debugging.

-V, --version

Print version information and exit.

See also

syslog(1), traffic_manager(8), traffic_server(8)

traffic_line

Synopsis

traffic_line [options]

Description

traffic_line is used to execute individual Traffic Server commands and to script multiple commands in a shell.

Options
-B, --bounce_cluster

Bounce all Traffic Server nodes in the cluster. Bouncing Traffic Server shuts down and immediately restarts Traffic Server, node-by-node.

-b, --bounce_local

Bounce Traffic Server on the local node. Bouncing Traffic Server shuts down and immediately restarts the Traffic Server node.

-C, --clear_cluster

Clears accumulated statistics on all nodes in the cluster.

-c, --clear_node

Clears accumulated statistics on the local node.

-h, --help

Print usage information and exit.

-L, --restart_local

Restart the traffic_manager and traffic_server processes on the local node.

-M, --restart_cluster

Restart the traffic_manager process and the traffic_server process on all the nodes in a cluster.

-m REGEX, --match_var REGEX

Display the current values of all performance statistics or configuration variables whose names match the given regular expression.

-r VAR, --read_var VAR

Display specific performance statistics or a current configuration setting.

-s VAR, --set_var VAR

Set the configuration variable named VAR. The value of the configuration variable is given by the traffic_line -v option. Refer to the records.config documentation for a list of the configuration variables you can specify.

-S, --shutdown

Shut down Traffic Server on the local node.

-U, --startup

Start Traffic Server on the local node.

-v VALUE, --value VALUE

Specify the value to set when setting a configuration variable.

-V, --version

Print version information and exit.

-x, --reread_config

Initiate a Traffic Server configuration file reread. Use this command to update the running configuration after any configuration file modification.

-Z, --zero_cluster

Reset performance statistics to zero across the cluster.

-z, --zero_node

Reset performance statistics to zero on the local node.

--offline PATH

Mark a cache storage device as offline. The storage is identified by a path which must match exactly a path specified in storage.config. This removes the storage from the cache and redirects requests that would have used this storage to other storage. This has exactly the same effect as a disk failure for that storage. This does not persist across restarts of the traffic_server process.

--alarms

List all alarm events that have not been acknowledged (cleared).

--clear_alarms [all | #event | name]

Clear (acknowledge) an alarm event. The arguments are “all” for all current alarms, a specific alarm number (e.g. ‘‘1’‘), or an alarm string identifier (e.g. ‘’MGMT_ALARM_PROXY_CONFIG_ERROR’‘).

--status

Show the current proxy server status, indicating if we’re running or not.

Performance Statistics
proxy.process.ssl.user_agent_other_errors
Total number of other ssl client connection errors (counts ssl errors that are not captured in other user agent stats below)
proxy.process.ssl.user_agent_expired_cert
Total number of ssl client connection failures where the cert was expired.
proxy.process.ssl.user_agent_revoked_cert
Total number of ssl client connection failures where the cert was revoked.
proxy.process.ssl.user_agent_unknown_cert
Total number of ssl client connection failures related to the cert, but specific error was unknown.
proxy.process.ssl.user_agent_cert_verify_failed
Total number of ssl client connection failures where cert verification failed.
proxy.process.ssl.user_agent_bad_cert
Total number of ssl client connection failures where the cert is bad.
proxy.process.ssl.user_agent_decryption_failed
Total number of ssl client connection decryption failures (during negotiation).
proxy.process.ssl.user_agent_wrong_version
Total number of ssl client connections that provided an invalid protocol version.
proxy.process.ssl.user_agent_unknown_ca
Total number of ssl client connection that failed due to unknown ca.
proxy.process.ssl.origin_server_other_errors
Total number of other ssl origin server connection errors (counts ssl errors that are not captured in other origin server stats below).
proxy.process.ssl.origin_server_expired_cert
Total number of ssl origin server connection failures where the cert was expired.
proxy.process.ssl.origin_server_revoked_cert
Total number of ssl origin server connection failures where the cert was revoked.
proxy.process.ssl.origin_server_unknown_cert
Total number of ssl origin server connection failures related to the cert where specific error was unknown.
proxy.process.ssl.origin_server_cert_verify_failed
Total number of ssl origin server connection failures where cert verification failed.
proxy.process.ssl.origin_server_bad_cert
Total number of ssl origin server connection failures where the cert is bad.
proxy.process.ssl.origin_server_decryption_failed
Total number of ssl origin server connection decryption failures (during negotiation).
proxy.process.ssl.origin_server_wrong_version
Total number of ssl origin server connections that provided an invalid protocol version.
proxy.process.ssl.origin_server_unknown_ca
Total number of ssl origin server connection that failed due to unknown ca.
proxy.process.ssl.user_agent_sessions
Total number of ssl/tls sessions created.
proxy.process.ssl.user_agent_session_hit
Total number of session hits. A previous session was reused which resulted in an abbreviated ssl client negotiation.
proxy.process.ssl.user_agent_session_miss
Total number of session misses. The ssl client provided a session id that was not found in cache and, therefore, could not be used.
proxy.process.ssl.user_agent_session_timeout
Total number of session timeouts. The ssl client provided a session, but it could not be used because it was past the session timeout.
proxy.process.ssl.cipher.user_agent.{CIPHERNAME}

Total number of ssl client connections that used cipherName. The list of cipher statistics is dynamic and depends upon the installed ciphers and the proxy.config.ssl.server.cipher_suite configuration. The set of cipher statistics can be discovered with traffic_line -m. For example:

$ traffic_line -m proxy.process.ssl.cipher.user_agent.
proxy.process.ssl.cipher.user_agent.ECDHE-RSA-AES256-GCM-SHA384 0
proxy.process.ssl.cipher.user_agent.ECDHE-ECDSA-AES256-GCM-SHA384 0
proxy.process.ssl.cipher.user_agent.ECDHE-RSA-AES256-SHA384 0
proxy.process.ssl.cipher.user_agent.ECDHE-ECDSA-AES256-SHA384 0
...
Examples

Configure Traffic Server to log in Squid format:

$ traffic_line -s proxy.config.log.squid_log_enabled -v 1
$ traffic_line -s proxy.config.log.squid_log_is_ascii -v 1
$ traffic_line -x
See also

records.config(5), storage.config(5)

traffic_logcat

Synopsis

traffic_logcat [-o output-file | -a] [-CEhSVw2] [input-file ...]

Description

To analyse a binary log file using standard tools, you must first convert it to ASCII. traffic_logcat does exactly that.

Options
-o PATH, --output_file PATH

Specifies where the command output is directed.

-a, --auto_filename

Automatically generates the output filename based on the input filename. If the input is from stdin, then this option is ignored. For example:

traffic_logcat -a squid-1.blog squid-2.blog squid-3.blog

generates:

squid-1.log squid-2.log squid-3.log
-f, --follow

Follows the file, like tail(1) -f

-C, --clf

Attempts to transform the input to Netscape Common format, if possible.

-E, --elf

Attempts to transform the input to Netscape Extended format, if possible.

-S, --squid

Attempts to transform the input to Squid format, if possible.

-2, --elf2

Attempt to transform the input to Netscape Extended-2 format, if possible.

-T, --debug_tags
-w, --overwrite_output
-h, --help

Print usage information and exit.

-V, --version

Print version information and exit.

注解

Use only one of the following options at any given time: -S, -C, -E, or -2.

If no input files are specified, then traffic_logcat reads from the standard input (stdin). If you do not specify an output file, then traffic_logcat writes to the standard output (stdout).

For example, to convert a binary log file to an ASCII file, you can use the traffic_logcat command with either of the following options below:

traffic_logcat binary_file > ascii_file
traffic_logcat -o ascii_file binary_file

The binary log file is not modified by this command.

See Also

tail(1)

traffic_logstats

Description
-f FILE, --log_file FILE
-o LIST, --origin_list LIST
-O FILE, --origin_file FILE
-M COUNT, --max_origins COUNT
-u COUNT, --urls COUNT
-U COUNT, --show_urls COUNT
--A, --as_object
-i, --incremental
-S FILE, --statetag FILE
-t, --tail
-s, --summary
-j, --json
-c, --cgi
-m, --min_hits
-a, --max_age
-l COUNT, --line_len COUNT
-T TAGS, --debug_tags TAGS
-h, --help

Print usage information and exit.

-V, --version

Print version information and exit.

traffic_manager

Description
proxyOff
-nosyslog
-aconfPort PORT
-clusterMCPort PORT
-groupAddr ADDRESS
-clusterRSPort PORT
-debug TAGS
-action TAGS
-path FILE
-recordsConf FILE
-tsArgs ARGUMENTS
-proxyPort PORT
-proxyBackDoor PORT
-version
Environment
MGMT_ACONF_PORT
MGMT_CLUSTER_MC_PORT
MGMT_CLUSTER_RS_PORT
MGMT_GROUP_ADDR

traffic_server

Description
-n COUNT, --net_threads COUNT
-Z COUNT, --cluster_threads COUNT
-U COUNT, --udp_threads COUNT
-a, --accepts_thread
-b, --accept_till_done
-p PORT, --httpport PORT
-P PORT, --cluster_port PORT
-o LEVEL, --dprintf_level LEVEL
-R LEVEL, --regression LEVEL
-r TEST, --regression_rest TEST
-T TAGS, --debug_tags TAGS
-B TAGS, --action_tags TAGS
-i COUNT, --interval COUNT
-M, --remote_management
-C CMD, --command CMD
-k, --clear_hostdb
-K, --clear_cache
-c CORE, --read_core CORE
--accept_mss MSS
-t MSECS, --poll_timeout MSECS
-h, --help

Print usage information and exit.

-V, --version

Print version information and exit.

Environment
PROXY_REMOTE_MGMT
PROXY_AUTO_EXIT

traffic_shell

Description
-V, --version

Print version information and exit.

traffic_top

Description
-s COUNT

tspush

Description
-f FILE, --file FILE
-u URL, --url URL
-v, --verbose
-h, --help

Print usage information and exit.

tsxs

Description
-q VAR, --query VAR
-I PATH
-L PATH
-l LIB
-o FILE
-i
-c FILE [FILE ...]
-C FILE [FILE ...]
-v, --verbose
-h, --help

Print usage information and exit.

Plugin Reference

Overview

One of the key features of Apache Traffic Server is modularity. Features that aren’t needed in the core simply aren’t there. This is a good thing, because it guarantees that our core can remain fast by concentrating on the things that we always provide: Caching and proxying.

All other things can be moved into plugins, by opening up a consistent C API, everyone can implement their own functionality, without having to touch the core.

Stable plugins

Plugins that are considered stable are installed by default in Apache Traffic Server releases.

CacheURL Plugin

This plugin allows you to change the key that is used for caching a request by using any portion of the url via regex. It is designed so that multiple requests that have different URLs but the same content (for example, site mirrors) need be cached only once.

Installation

This plugin is only built if the configure option

--enable-experimental-plugins

is given at build time.

Configuration

Create a cacheurl.config file in the plugin directory with the url regex patterns to match.

url_pattern   cache_key_replacement

The url_pattern is a regular expression (pcre). The replacement can contain $1, $2 and so on, which will be replaced with the appropriate matching group from the pattern.

Add the plugin to your plugin.config file:

cacheurl.so

Start traffic server. Any rewritten URLs will be written to cacheurl.log in the log directory by default.

Examples
  1. To make files from s1.example.com, s2.example.com and s3.example.com all be cached with the same key. Adding a unique suffix (TSINTERNAL in this example) to the cache key guarantees that it won’t clash with a real URL should s.example.com exist.

    http://s[123].example.com/(.*)  http://s.example.com.TSINTERNAL/$1

  2. Cache based on only some parts of a query string (e.g. ignore session information). This plucks out the id and format query string variables and only considers those when making the cache key.

    http://www.example.com/video\?.*?\&?(id=[0-9a-f]*).*?\&(format=[a-z]*) http://video-srv.example.com.ATSINTERNAL/$1&$2

  3. Completely ignore a query string for a specific page

    http://www.example.com/some/page.html(?:\?|$) http://www.example.com/some/page.html

More docs

There are some docs on cacheurl in Chinese, please find them in the following:

https://blog.zymlinux.net/index.php/archives/195

conf_remap Plugin

The conf_remap plugin allows you to override configuration directives dependent on actual remapping rules. The plugin is built and installed as part of the normal Apache Traffic Server installation process.

The conf_remap plugin accepts configuration directives in the arguments list or in a separate configuration file. In both cases, only string and integer directives are supported.

When using a separate configuration file, the standard records.config syntax is used, for example:

map http://cdn.example.com/ http://some-server.example.com \
  @plugin=conf_remap.so @pparam=/etc/trafficserver/cdn.conf

where cdn.conf contains:

CONFIG proxy.config.url_remap.pristine_host_hdr INT 1

When using inline arguments, the conf_remap plugin accepts a key=value syntax, where the KEY is the name of the configuration directive and VALUE is the desired value, for example:

map http://cdn.example.com/ http://some-server.example.com \
  @plugin=conf_remap.so @pparam=proxy.config.url_remap.pristine_host_hdr=1

Doing this, you will override your global default configuration on a per mapping rule. For more details on the APIs, functionality, and a complete list of all overridable configurations, see TSHttpOverridableConfig.

gzip / deflate Plugin

This plugin gzips or deflates responses, whichever is applicable. It can compress origin respones as well as cached responses. The plugin is built and installed as part of the normal Apache Traffic Server installation process.

Installation

Add the following line to plugin.config:

gzip.so

In this case, the plugin will use the default behaviour:

  • Enable caching
  • Compress text/* for every origin
  • Don’t hide accept encoding from origin servers (for an offloading reverse proxy)
  • No urls are disallowed from compression
Configuration

Alternatively, a configuration can also be specified:

gzip.so <path-to-plugin>/sample.gzip.config

After modifying plugin.cofnig, restart traffic server (sudo traffic_line -L) the configuration is re-read when a management update is given (sudo traffic_line -x)

Options

Flags and options are:

enabled: (true or false) Enable or disable compression for a host.

remove-accept-encoding: (true or false) Sets whether the plugin should hide the accept encoding from origin servers:

  • To ease the load on the origins.
  • For when the proxy parses responses, and the resulting compression/decompression is wasteful.

cache: (true or false) When set, the plugin stores the uncompressed and compressed response as alternates.

compressible-content-type: Wildcard pattern for matching compressible content types.

disallow: Wildcard pattern for disabling compression on urls.

Options can be set globally or on a per-site basis, as such:

# Set some global options first
cache true
enabled true
remove-accept-encoding false
compressible-content-type text/*

# Now set a configuration for www.example.com
[www.example.com]
cache false
remove-accept-encoding true
disallow /notthis/*.js

See example.gzip.config for example configurations.

Header Rewrite Plugin

This is a plugin for Apache Traffic Server that allows you to modify various headers based on defined rules (operations) on a request or response. Currently, only one operation is supported.

Using the plugin

This plugin can be used as both a global plugin, enabled in plugin.config:

header_rewrite.so config_file_1.conf config_file_2.conf ...

These are global rules, which would apply to all requests. Another option is to use per remap rules in remap.config:

map http://a http://b @plugin=header_rewrite.so @pparam=rules1.conf ...

In the second example, hooks which are not to be executed during the remap phase (the default) causes a transaction hook to be instantiated and used at a later time. This allows you to setup e.g. a rule that gets executed during the origin response header parsing, using READ_RESPONSE_HDR_HOOK.

Configuration filenames without an absolute paths are searched for in the default configuration directory. This is typically where your main configuration files are, e.g. /usr/local/etc/trafficserver.

Operators

The following operators are available:

rm-header header-name                 [operator_flags]
add-header header <value>             [operator_flags]
set-header header <value>             [operator_flags]
set-status <status-code>              [operator_flags]
set-destination [qual] <value>        [operator_flags]
set-redirect <value>                  [operator_flags]
set-timeout-out <value>               [operator_flags]
set-status-reason <value>             [operator_flags]
set-config overridable-config <value> [operator_flags]
counter counter-name                  [operator_flags]
no-op                                 [operator_flags]

Where qual is one of the support URL qualifiers:

HOST
PORT
PATH
QUERY

For example (as a remap rule):

cond %{HEADER:X-Mobile} = "foo"
set-destination HOST foo.mobile.bar.com [L]
Operator flags

The operator flags are optional, and must not contain whitespaces inside the brackets. Currently, only one flag is supported:

[L]   Last rule, do not continue
Variable expansion

Currently only limited variable expansion is supported in add-header. Supported substitutions include:

%<proto>      Protocol
%<port>       Port
%<chi>        Client IP
%<cqhl>       Client request length
%<cqhm>       Client HTTP method
%<cquup>      Client unmapped URI
Conditions

The conditions are used as qualifiers: The operators specified will only be evaluated if the condition(s) are met:

cond %{STATUS} operand                        [condition_flags]
cond %{RANDOM:nn} operand                     [condition_flags]
cond %{ACCESS:file}                           [condition_flags]
cond %{TRUE}                                  [condition_flags]
cond %{FALSE}                                 [condition_flags]
cond %{HEADER:header-name} operand            [condition_flags]
cond %{COOKIE:cookie-name} operand            [condition_flags]
cond %{CLIENT-HEADER:header-name} operand     [condition_flags]
cond %{PROTOCOL} operand                      [condition_flags]
cond %{PORT} operand                          [condition_flags]
cond %{HOST} operand                          [condition_flags]
cond %{TOHOST} operand                        [condition_flags]
cond %{FROMHOST} operand                      [condition_flags]
cond %{PATH} operand                          [condition_flags]
cond %{PARAMS} operand                        [condition_flags]
cond %{QUERY} operand                         [condition_flags]

The difference between HEADER and CLIENT-HEADER is that HEADER adapts to the hook it’s running in, whereas CLIENT-HEADER always applies to the client request header. The %{TRUE} condition is also the default condition if no other conditions are specified.

These conditions have to be first in a ruleset, and you can only have one in each rule. This implies that a new hook condition starts a new rule as well.:

cond %{READ_RESPONSE_HDR_HOOK}   (this is the default hook)
cond %{READ_REQUEST_HDR_HOOK}
cond %{READ_REQUEST_PRE_REMAP_HOOK}
cond %{SEND_REQUEST_HDR_HOOK}
cond %{SEND_RESPONSE_HDR_HOOK}

For remap.config plugin instanations, the default hook is named REMAP_PSEUDO_HOOK. This can be useful if you are mixing other hooks in a configuration, but being the default it is also optional.

Condition flags

The condition flags are optional, and you can combine more than one into a comma separated list of flags. Note that whitespaces are not allowed inside the brackets:

[NC]  Not case sensitive condition (when applicable) [NOT IMPLEMENTED!]
[AND] AND with next condition (default)
[OR]  OR with next condition
[NOT] Invert this condition
Operands to conditions
/string/  # regular expression
<string   # lexically lower
>string   # lexically greater
=string   # lexically equal

The absence of a “matcher” means value exists).

Values

Setting e.g. a header with a value can take the following formats:

  • Any of the cond definitions, that extracts a value from the request
  • $N 0 <= N <= 9, as grouped in a regular expression
  • string (which can contain the above)
  • null
Examples
cond %{HEADER:X-Y-Foobar}
cond %{COOKIE:X-DC}  =DC1
add-header X-Y-Fiefum %{HEADER:X-Y-Foobar}
add-header X-Forwarded-For %<chi>
rm-header X-Y-Foobar
rm-header Set-Cookie
counter plugin.header_rewrite.x-y-foobar-dc1
cond %{HEADER:X-Y-Foobar} "Some string" [AND,NC]
Regex Remap Plugin

This allows you to configure mapping rules based on regular expressions. This is similar to what you can accomplish using mod_rewrite in Apache httpd, but obviously not as flexible or sophisticated (yet).

To use this plugin, configure a remap.config rule like

map http://a.com http://b.com @plugin=regex_remap.so @pparam=maps.reg

The file name parameter is always required. Unless an absolute path is specified, the file name is assumed to be a path relative to the Traffic Server configuration directory.

The regular expressions listed in the configuration file are evaluated sequentially. When a regular expression is positively matched against a request URL, evaluation is stopped and the rewrite rule is applied. If none of the regular expressions are a match, the default destination URL is applied (http://b.com in the example above).

An optional argument (@pparam) with the string “profile” will enable profiling of this regex remap rule, e.g.

... @pparam=maps.reg @pparam=profile

Profiling is very low overhead, and the information is dumped to traffic.out, located in the log directory. This information is useful to optimize the order of your regular expression, such that the most common matches appears early in the file. In order to force a profile dump, you can do

$ sudo touch remap.config
$ sudo traffic_line -x

By default, only the path and query string of the URL are provided for the regular expressions to match. The following optional parameters can be used to modify the plugin instance behavior

@pparam=[no-]method              [default: off]
@pparam=[no-]query-string        [default: on]
@pparam=[no-]matrix-parameters   [default: off]

If you wish to match on the HTTP method used (e.g. “GET”), you must use the option @pparam=method. e.g.

... @pparam=maps.reg @pparam=method

With this enabled, the string that you will need to match will look like

GET/path?query=bar

The methods are always all upper-case, and always followed by one single space. There is no space between the method and the rest of the URL (or URI path).

By default, the query string is part of the string that is matched again, to turn this off use the option ‘no-query-string’, e.g.

... @pparam=maps.reg @pparam=no-query-string

Finally, you can also include the matrix parameters in the string, using the option ‘matrix-parameters’, e.g.

... @pparam=maps.reg @pparam=matrix-parameters

A typical regex would look like

^/(ogre.*)/more     http://www.ogre.com/$h/$0/$1

The regular expression must not contain any white spaces!

When the regular expression is matched, only the URL path + query string is matched (without any of the optional configuration options). The path will always start with a “/”. Various substitution strings are allowed on the right hand side during evaluation

$0     - The entire matched string
$1-9   - Regular expression groups ($1 first group etc.)
$h     - The original host header from the request
$f     - The host as used in the "from" portion of the remap rule
$t     - The host as used in the "to" portion of the remap rule
$p     - The original port number
$s     - The scheme (e.g. http) of the request
$P     - The entire path of the request
$q     - The query part of the request
$r     - The path parameters of the request (not implemented yet)
$c     - The cookie string from the request
$i     - The client IP for this request

注解

The $0 substitution expands to the characters that were matched by the regular expression, not to the entire string that the regular expression was matched against.

You can also provide options, similar to how you configure your remap.config. The following options are available

@status=<nnn>               - Force the response code to <nnn>
@active_timeout=<nnn>       - Active timeout (in ms)
@no_activity_timeout=<nnn>  - No activity timeout (in ms)
@connect_timeout=<nnn>      - Connect timeouts (in ms)
@dns_timeout=<nnn>          - Connect timeouts (in ms)

@overridable-config=<value> - see :ref:`ts-overridable-config`

@caseless                   - Make regular expressions case insensitive
@lowercase_substitutions    - Turn on (enable) lower case substitutions

This can be useful to force a particular response for some URLs, e.g.

^/(ogre.*)/bad      http://www.examle.com/  @status=404

Or, to force a 302 redirect

^/oldurl/(.*)$      http://news.example.com/new/$1 @status=302

Setting the status to 301 or 302 will force the new URL to be used as a redirect (Location:).

Stats over HTTP Plugin

This plugin implements an HTTP interface to all Traffic Server statistics. The metrics returned are in a JSON format, for easy processing. This plugin is now part of the standard ATS build process, and should be available after install.

To enable this plugin, add to the plugin.conf file:

stats_over_http.so

After starting Traffic Server, the JSON metrics are now available on the default URL:

http://host:port/_stats

where host and port is the hostname/IP and port number of the server. You can optionally modify the path to use, and this is highly recommended in a public facing server. For example:

stats_over_http.so 81c075bc0cca1435ea899ba4ad72766b

and the URL would then be e.g.:

https://host:port/81c075bc0cca1435ea899ba4ad72766b

This is weak security at best, since the secret could possibly leak if you are careless and send it over clear text.

Experimental plugins

Plugins that are considered experimental are located in the plugins/experimental directory of the Apache Traffic Server source tree. Exmperimental plugins can be compiled by passing the –enable-experimental-plugins option to configure:

$ autoconf -i
$ ./configure --enable-experimental-plugins
$ make
AuthProxy Plugin

There are many ways of authorizing an HTTP request. Often, this requires making IPC calls to some internal infrastructure. AuthProxy is a plugin that takes care of the Traffic Server end of authorizing a request and delegates the authorization decision to an external HTTP service.

This plugin can be used as either a global plugin or a remap plugin.

Note that Traffic Server optimizes latency by skipping the DNS lookup state if a document is found in the cache. This will have the effect of serving the document without consulting the AuthProxy plugin. you can disable this behavior by setting proxy.config.http.doc_in_cache_skip_dns to 0 in records.config.

Plugin Options
--auth-transform=TYPE
 

This option specifies how to route the incoming request to the authorization service. The transform type may be head or redirect.

If the transform type is head, then the incoming request is transformed to a HEAD request and is sent to the same destination. If the response is 200 OK, the incoming request is allowed to proceed.

If the transform type is redirect then the incoming request is sent to the authorization service designated by the –auth-host and –auth-port parameters. If the response is 200 OK, the incoming request is allowed to proceed.

When the authorization service responds with a status other than 200 OK, that response is returned to the client as the response to the incoming request. This allows mechanisms such as HTTP basic authentication to work correctly. Note that the body of the authorization service response is not returned to the client.

--auth-host=HOST
 The name or address of the authorization host. This is only used by the redirect transform.
--auth-port=PORT
 The TCP port of the authorization host. This is only used by the redirect transform.
--force-cacheability
 If this options is set, the plugin will allow Traffic Server to cache the result of authorized requests. In the normal case, requests with authorization headers are nor cacheable, but this flag allows that by setting the proxy.config.http.cache.ignore_authentication option on the request.
Examples

In this example, the authentication is performed by converting the incoming HTTP request to a HEAD request and sending that to the origin server origin.internal.com:

map http://cache.example.com http://origin.internal.com/ \
  @plugin=authproxy.so @pparam=--auth-transform=head

In this example, the request is directed to a local authentication server that authorizes the request based on internal policy rules:

map http://cache.example.com http://origin.internal.com/ \
  @plugin=authproxy.so @pparam=--auth-transform=redirect @pparam=--auth-host=127.0.0.1 @pparam=--auth-port=9000
Balancer Plugin

The balancer balances requests across multiple origin servers. To use this plugin, configure it in a remap.config rule, specifying a balancing policy and a set of origin servers. For example:

map http://foo.com http://foo.com \
   @plugin=balancer.so @pparam=--policy=hash,url @pparam=one.bar.com @pparam=two.bar.com

The replacement URL in the mapping rule is not used. The argument to the --policy option is a comma-separated list of keywords. The first keyword is the name of a balancing policy. The subsequent keywords are used to refine the requested policy.

Hash Balancing Policy

The hash balancing policy performs a consistent hash across the set of origins. This minimizes the number of hash entries that must be moved when the set of origin servers changes. An optional list of hash fields follows the hash keyword. Each specified hash field is hashed to select an outbound origin server.

The following fields can be supplied to the hash:

key
The request cache key. Note that the cache key will only be set if you have already chained a plugin that sets a custom cache key.
url
The request URL. This is the default hash field that is used if no other fields are specified.
srcaddr
The source IP address of the request.
Round Robin Balancing Policy

The roundrobin balancing policy simply allocates requests to origin servers in order. Over time, the number of requests received by each origin should be approximately the same.

Health Checking

The balancer plugin does not check the health of the origin servers, however the plugin is fully reloadable so health checking is usualy simple to implement. Most production environments already have mechanisms to check service health. It is recommended that you write a simple script to monitor this information and rewrite remap.config when appropriate. Running traffic_line -x will reload the balancer plugin with the new set of origin servers.

Buffer Upload Plugin

The Buffer Upload plugin offers the following features

Installation

Configuration can be explicitly specified as a parameter in plugin.config

buffer_upload.so /FOOBAR/upload.conf
Memory buffering (buffer the entire POST data in IOBuffer before connecting to OS)

Memory buffer size is configured with “mem_buffer_size” in config file. Default and minimum value is 32K. You can increase it in the config file. If the size of a request is larger than the “mem_buffer_size” value specifiied in the config file, then the upload proxy feature will be disabled for this particular request

Disk buffering (buffer the entire POST data on disk before connecting to OS)

1. Disk async IO is used. AIO api call only involves certain amount of threads. The number of threads is configurable in plugin’s config file (default is 4)

2. Directories and files are generated on disk . Base directory is /FOOBAR/var/buffer_upload_tmp/ (configurable in config file). Number of subdirectories is 64 (configurable in config file). Filename are randomly generated. Files will be removed when the entire data have been sent out to OS . At startup time, dangling files are removed (left on disk due to transaction interruption or traffic server crash)

  1. Default chunk size when reading from disk is 16K, configurable in config file
Trigger POST buffering on certain URLs
  1. Certain URLs will be provided in a plain text file (one URL each line)
  2. Specify filename in config file by “url_list_file”
  3. max length of each URL is 4096 (configurable in config file)
  4. use exact match, don’t support regex for now
Other Features

1. Default buffering mode is disk aio buffering mode. To turn off disk buffering, add a “use_disk_buffer 0” line in config file

  1. All request headers inlcuding cookies plus the entire POST data will be buffered (either in memory or on disk)
Configuration File

sample config file

use_disk_buffer 1
convert_url 1
chunk_size 1024
url_list_file /tmp/url_list.conf
max_url_length 10000
base_dir /tmp/test1
subdir_num 100
thread_num 10
mem_buffer_size 40000
Combohandler Plugin

This plugin provides an intelligent way to combine multiple URLs into a single URL, and have Apache Traffic Server combine the components into one response. This is useful for example to create URLs that combine multiple CSS or Javascript files into one.

Installation

This plugin is only built if the configure option

--enable-experimental-plugins

is given at build time. Note that this plugin is built and installed in combination with the ESI module, since they share common code.

Configuration

The arguments in the plugin.config line in order represent

  1. The path that should triggers combo handler (defaults to “admin/v1/combo”)
  2. The name of the key used for signature verification (disabled by default)

A “-” can be supplied as a value for any of these arguments to request default value be applied.

Also, just like the original combohandler, this plugin generates URLs of the form http://localhost/<dir>/<file-path>. <dir> here defaults to l unless specified by the file path in the query parameter using a colon. For example:

http://combo.com/admin/v1/combo?filepath1&dir1:filepath2&filepath3

Will result in these three pages being fetched:

http://localhost/l/filepath1
http://localhost/dir1/filepath2
http://localhost/l/filepath3

Remap rules have to be specified to map the above URLs to desired content servers.

The plugin also supports a prefix parameter. Common parts of successive file paths can be extracted and specified separately using a ‘p’ query parameter. Successive file path parameters are appended to this prefix to create complete file paths. The prefix will remain active until changed or cleared (set to an empty string). For example, the query

"/file1&p=/path1/&file2&file3&p=&/file4&p=/dir:path2/&file5&file6"

results in these file paths being “reconstructed”:

/file1
/path1/file2
/path1/file3
/file4
/dir:path2/file5
/dir:path2/file6
ESI Plugin (undocumented)

This plugin implements the ESI specification.

GeoIP ACLs Plugin

This is a simple ATS plugin for denying (or allowing) requests based on the source IP geo-location. Currently only the Maxmind APIs are supported, but we’d be happy to other other (open) APIs if you let us know. This plugin comes with the standard distribution of Apache Traffic Server, and should be installed as part of the normal build process.

Configuration

Once installed, there are three primary use cases, which we will discuss in details. Note that in all configurations, the first plugin parameter must specify what the matches should be applied to. Currently, only one rule set is supported, for Country ISO codes. This is specified with a parameter of

@pparam=country

Future additions to this plugin could include other regions, such as city, state, continent etc.

The three typical use cases are as follows:

  1. Per remap configurations, applicable to the entire remap rule. This is useful when you can partition your content so that entire prefix paths should be filtered. For example, lets assume that http://example.com/music is restricted to US customers only, and everything else is world wide accessible. In remap.config, you would have something like

    map http://example.com/music http://music.example.com \
      @plugin=geoip_acl.so @pparam=country @pparam=allow @pparam=US
    map http://example.com http://other.example.com
  2. If you can not partition the data with a path prefix, you can specify a separate regex mapping filter. The remap.config file might then look like

    map http://example.com http://music.example.com \
      @plugin=geoip_acl.so @pparam=country \
      @pparam=regex::/etc/music.regex

where music.regex is a format with PCRE (perl compatible) regular expressions, and unique rules for match. E.g.:

.*\.mp3  allow  US
.*\.ogg  deny   US

Note that the default in the case of no matches on the regular expressions is to “allow” the request. This can be overriden, see next use case.

  1. You can also combine 1) and 2), and provide defaults in the remap.config configuration, which then applies for the cases where no regular expressions matches at all. This would be useful to override the default which is to allow all requests that don’t match. For example

    map http://example.com http://music.example.com \
      @plugin=geoip_acl.so @pparam=country @pparam=allow @pparam= US
      @pparam=regex::/etc/music.regex

This tells the plugin that in the situation where there is no matching regular expression, only allow requests originating from the US.

Finally, there’s one additional parameter option that can be used

@pparam=html::/some/path.html

This will override the default reponse body for the denied responses with a custom piece of HTML. This can be useful to explain to your users why they are getting denied access to a particular piece of content. This configuration can be used with any of the use cases described above.

HIPES plugin

This is a remap plugin used in the HIPES system.

Configuration
urlp:<name>
Default: url Name of the query parameter for the service URL
path:<path>
Default: / Path to use for the service URL
ssl
Default: no Use SSL when connecting to the service
service
Service server, host[:port]
server
Default: hipes.yimg.com Name of HIPES server, host[:port]
active_timeout
The active connection timeout in ms
no_activity_timeout
The no activity timeout in ms
connect_timeout
The connect timeout in ms
dns_timeout
The DNS timeout

The timeout options override the server defaults (from `records.config), and only apply to the connection to the specific “service” host.

Notes on HIPES

HTTP Pipes (aka HIPES and pronounced “Hippies”) allows data services to be pipelined together, as illustrated by the example below.

Example
  1. ATS is run on port 80 and apache HTTP web server is run on port 8080 on localhost (127.0.0.1)

  2. The HIPES plugin is used in remap.config

    map http://127.0.0.1/svc_case http://nosuchhost @plugin=hipes.so @pparam=service:127.0.0.1:8080 @pparam=path:svc_case.php @pparam=server:127.0.0.1
    map http://127.0.0.1/svc_reverse http://nosuchhost @plugin=hipes.so @pparam=service:127.0.0.1:8080 @pparam=path:svc_reverse.php @pparam=server:127.0.0.1
    map http://127.0.0.1/test.txt http://127.0.0.1:8080/test.txt
  3. The plugin remaps the incoming URL such as

    http://127.0.0.1/svc_reverse/svc_case;case=u/test.txt

to the following

http://127.0.0.1:8080/svc_reverse?url=http%3A%2F%2F127.0.0.1%2Fsvc_case%3Bcase%3Du%2Ftest.txt
  1. The service svc_reverse.php fetches the url from the ATS again and the plugin remaps the URL

    http://127.0.0.1/svc_case;case=u/test.txt

to this URL

http://127.0.0.1:8080/svc_case.php?case=u&url=http%3A%2F%2F127.0.0.1%2Ftest.txt

5. In this example, the service svc_case.php fetches and transforms the response of http://127.0.0.1/test.txt (which ATS proxies the request to a local file) to upper case. And subsequently the service svc_reverse.php receives the response and reverse the order before the response is sent back to the client by ATS.

Notes on reducing traffic

There can be significant overhead using HIPES because the data can traverse through ATS many times. Caching can be important to reduce traffic to services/through ATS and can be achieved via a proper Cache-Control header returned by the services. Another way to reduce traffic through ATS is to have ATS to return 302 redirects to url for the requests made by service, instead of proxying the requests to that url. However, the service must then be able to follow the redirect. The down side is that we cannot use ATS to cache intermediate results. Below is an example of using redirect.

Modification to above example to reduce traffic using redirect

1. The service svc_reverse.php is modified to add a header of X-HIPES-Redirect: 2 to the request made against url.

  1. HIPES plugin will instruct ATS to return a redirect response to this url

    http://127.0.0.1:8080/svc_case.php?case=u&url=http%3A%2F%2F127.0.0.1%2Ftest.txt

for the following request

http://127.0.0.1/svc_case;case=u/test.txt

3. The service svc_reverse.php is also modified to follow the redirect. Thus the response of the service of svc_case.php will not pass through ATS and will pass to svc_reverse.php service instead.

MySQL Remap Plugin

This is a basic plugin for doing dynamic “remaps” from a database. It essentially rewrites the incoming request’s Host header / origin server connection to one retrieved from a database.

The generic proxying setup is the following:

UA ----> Traffic Server ----> Origin Server

Without the plugin a request like:

GET /path/to/something HTTP/1.1
Host: original.host.com

Ends up requesting http://original.host.com/path/to/something

With this plugin enabled, you can easily change that to anywhere you desire. Imagine the many possibilities....

We have benchmarked the plugin with ab at about 9200 requests/sec (1.7k object) on a commodity hardware with a local setup of both, MySQL and Traffic Server local. Real performance is likely to be substantially higher, up to the MySQL’s max queries / second.

Installation

This plugin is only built if the configure option

--enable-experimental-plugins

is given at build time.

Configuration

Import the default schema to a database you create:

mysql -u root -p -e "CREATE DATABASE mysql_remap;"   # create a new database
mysql -u root -p mysql_remap < schema/import.sql     # import the provided schema

insert some interesting values in mysql_remap.hostname & mysql_remap.map

Traffic Server plugin configuration is done inside a global configuration file: /etc/trafficserver/plugin.config:

mysql_remap.so /etc/trafficserver/mysql_remap.ini

The INI file should contain the following values:

[mysql_remap]
mysql_host     = localhost   #default
mysql_port     = 3306        #default
mysql_username = remap_user
mysql_password =
mysql_database = mysql_remap #default

To debug errors, start trafficserver manually using:

traffic_server -T "mysql_remap"

And resolve any errors or warnings displayed.

AWS S3 Authentication plugin

This is a plugin for Apache Traffic Server that provides support for the Amazon S3 authentication features. This is useful if you for example want to use S3 as your origin server, yet want to avoid direct user access to the content.

Using the plugin

There are three configuration options for this plugin:

--access_key    <key>
--secret_key    <key>
--virtual_host
--config        <config file>

Using the first two in a remap rule would be e.g.:

...  @plugin=s3_auth @pparam=--access_key @pparam=my-key \
                     @pparam=--secret_key @pparam=my-secret \
                     @pparam=--virtual_host

Alternatively, you can store the access key and secret in an external configuration file, and point the remap rule(s) to it:

... @plugin=s3_auth @pparam=–config @pparam=s3.config

Where s3.config would look like:

# AWS S3 authentication
    access_key=my-key
    secret_key=my-secret
    virtual_host=yes

For more details on the S3 auth, see:

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
ToDo

This is a pretty barebone start for the S3 services, it is missing a number of features:

Contributions to any of these would be appreciated.

Stale While Revalidate Plugin (undocumented)

refresh content asynchronously while serving stale data

ts-lua Plugin

Embed the Power of Lua into TrafficServer.

Status

This module is being tested under our production environment.

Version

ts-lua has not been released yet.

Synopsis

test_hdr.lua

function send_response()
    ts.client_response.header['Rhost'] = ts.ctx['rhost']
    return 0
end


function do_remap()
    local req_host = ts.client_request.header.Host

    if req_host == nil then
        return 0
    end

    ts.ctx['rhost'] = string.reverse(req_host)

    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)

    return 0
end

test_transform.lua

function upper_transform(data, eos)
    if eos == 1 then
        return string.upper(data)..'S.H.E.\n', eos
    else
        return string.upper(data), eos
    end
end

function send_response()
    ts.client_response.header['SHE'] = ts.ctx['tb']['she']
    return 0
end


function do_remap()
    local req_host = ts.client_request.header.Host

    if req_host == nil then
        return 0
    end

    ts.ctx['tb'] = {}
    ts.ctx['tb']['she'] = 'wo ai yu ye hua'

    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
    ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)

    ts.http.resp_cache_transformed(0)
    ts.http.resp_cache_untransformed(1)
    return 0
end

test_cache_lookup.lua

function send_response()
    ts.client_response.header['Rhost'] = ts.ctx['rhost']
    ts.client_response.header['CStatus'] = ts.ctx['cstatus']
end


function cache_lookup()
    local cache_status = ts.http.get_cache_lookup_status()
    ts.ctx['cstatus'] = cache_status
end


function do_remap()
    local req_host = ts.client_request.header.Host

    if req_host == nil then
        return 0
    end

    ts.ctx['rhost'] = string.reverse(req_host)

    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
    ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)

    return 0
end

test_ret_403.lua

function send_response()
    ts.client_response.header['Now'] = ts.now()
    return 0
end


function do_remap()

    local uri = ts.client_request.get_uri()

    pos, len = string.find(uri, '/css/')
    if pos ~= nil then
        ts.http.set_resp(403, "Document access failed :)\n")
        return 0
    end

    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)

    return 0
end

sethost.lua

HOSTNAME = ''

function __init__(argtb)

    if (#argtb) < 1 then
        print(argtb[0], 'hostname parameter required!!')
        return -1
    end

    HOSTNAME = argtb[1]
end

function do_remap()
    local req_host = ts.client_request.header.Host

    if req_host == nil then
        return 0
    end

    ts.client_request.header['Host'] = HOSTNAME

    return 0
end

test_intercept.lua

require 'os'

function send_data()
    local nt = os.time()..' Zheng.\n'
    local resp =  'HTTP/1.1 200 OK\r\n' ..
        'Server: ATS/3.2.0\r\n' ..
        'Content-Type: text/plain\r\n' ..
        'Content-Length: ' .. string.len(nt) .. '\r\n' ..
        'Last-Modified: ' .. os.date("%a, %d %b %Y %H:%M:%S GMT", os.time()) .. '\r\n' ..
        'Connection: keep-alive\r\n' ..
        'Cache-Control: max-age=7200\r\n' ..
        'Accept-Ranges: bytes\r\n\r\n' ..
        nt

    ts.sleep(1)
    return resp
end

function do_remap()
    ts.http.intercept(send_data)
    return 0
end

test_server_intercept.lua

require 'os'

function send_data()
    local nt = os.time()..'\n'
    local resp =  'HTTP/1.1 200 OK\r\n' ..
        'Server: ATS/3.2.0\r\n' ..
        'Content-Type: text/plain\r\n' ..
        'Content-Length: ' .. string.len(nt) .. '\r\n' ..
        'Last-Modified: ' .. os.date("%a, %d %b %Y %H:%M:%S GMT", os.time()) .. '\r\n' ..
        'Connection: keep-alive\r\n' ..
        'Cache-Control: max-age=30\r\n' ..
        'Accept-Ranges: bytes\r\n\r\n' ..
        nt
    return resp
end

function do_remap()
    ts.http.server_intercept(send_data)
    return 0
end
Description

This module embeds Lua, via the standard Lua 5.1 interpreter, into Apache Traffic Server. This module acts as remap plugin of Traffic Server, so we should realize ‘do_remap’ function in each lua script. We can write this in remap.config::

map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/usr/lib64/trafficserver/plugins/libtslua.so @pparam=/etc/trafficserver/script/test_hdr.lua

Sometimes we want to receive parameters and process them in the script, we should realize ‘__init__’ function in the lua script(sethost.lua is a reference), and we can write this in remap.config::

map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/usr/lib64/trafficserver/plugins/libtslua.so @pparam=/etc/trafficserver/script/sethost.lua @pparam=img03.tbcdn.cn
TS API for Lua
Introduction

The API is exposed to Lua in the form of one standard packages ts. This package is in the default global scope and is always available within lua script.

ts.now

syntax: val = ts.now()

context: global

description: This function returns the time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds.

Here is an example::

function send_response()
    ts.client_response.header['Now'] = ts.now()
    return 0
end
ts.debug

syntax: ts.debug(MESSAGE)

context: global

description: Log the MESSAGE to traffic.out if debug is enabled.

Here is an example::

function do_remap()
   ts.debug('I am in do_remap now.')
   return 0
end

The debug tag is ts_lua and we should write this in records.config::

CONFIG proxy.config.diags.debug.tags STRING ts_lua
ts.hook

syntax: ts.hook(HOOK_POINT, FUNCTION)

context: do_remap or later

description: Hooks are points in http transaction processing where we can step in and do some work. FUNCTION will be called when the http transaction steps in to HOOK_POINT.

Here is an example::

function send_response()
    s.client_response.header['SHE'] = 'belief'
end

function do_remap()
    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
end
Hook point constants

context: do_remap or later

TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE TS_LUA_HOOK_SEND_REQUEST_HDR TS_LUA_HOOK_READ_RESPONSE_HDR TS_LUA_HOOK_SEND_RESPONSE_HDR TS_LUA_REQUEST_TRANSFORM TS_LUA_RESPONSE_TRANSFORM

These constants are usually used in ts.hook method call.

ts.ctx

syntax: ts.ctx[KEY]

context: do_remap or later

description: This table can be used to store per-request Lua context data and has a life time identical to the current request.

Here is an example::

function send_response()
    ts.client_response.header['RR'] = ts.ctx['rhost']
    return 0
end

function do_remap()
    local req_host = ts.client_request.header.Host
    ts.ctx['rhost'] = string.reverse(req_host)
    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
    return 0
end
ts.http.get_cache_lookup_status

syntax: ts.http.get_cache_lookup_status()

context: function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point

description: This function can be used to get cache lookup status.

Here is an example::

function send_response()
    ts.client_response.header['CStatus'] = ts.ctx['cstatus']
end

function cache_lookup()
    local cache_status = ts.http.get_cache_lookup_status()
    if cache_status == TS_LUA_CACHE_LOOKUP_HIT_FRESH:
        ts.ctx['cstatus'] = 'hit'
    else
        ts.ctx['cstatus'] = 'not hit'
    end
end

function do_remap()
    ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
    return 0
end
Http cache lookup status constants

context: global

TS_LUA_CACHE_LOOKUP_MISS (0) TS_LUA_CACHE_LOOKUP_HIT_STALE (1) TS_LUA_CACHE_LOOKUP_HIT_FRESH (2) TS_LUA_CACHE_LOOKUP_SKIPPED (3)
ts.http.set_cache_url

syntax: ts.http.set_cache_url(KEY_URL)

context: do_remap

description: This function can be used to modify the cache key for the request.

Here is an example::

function do_remap()
    ts.http.set_cache_url('http://127.0.0.1:8080/abc/')
    return 0
end
ts.http.resp_cache_transformed

syntax: ts.http.resp_cache_transformed(BOOL)

context: do_remap or later

description: This function can be used to tell trafficserver whether to cache the transformed data.

Here is an example::

function upper_transform(data, eos)
    if eos == 1 then
        return string.upper(data)..'S.H.E.\n', eos
    else
        return string.upper(data), eos
    end
end

function do_remap()
    ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
    ts.http.resp_cache_transformed(0)
    ts.http.resp_cache_untransformed(1)
    return 0
end

This function is usually called after we hook TS_LUA_RESPONSE_TRANSFORM.

ts.http.resp_cache_untransformed

syntax: ts.http.resp_cache_untransformed(BOOL)

context: do_remap or later

description: This function can be used to tell trafficserver whether to cache the untransformed data.

Here is an example::

function upper_transform(data, eos)
    if eos == 1 then
        return string.upper(data)..'S.H.E.\n', eos
    else
        return string.upper(data), eos
    end
end

function do_remap()
    ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
    ts.http.resp_cache_transformed(0)
    ts.http.resp_cache_untransformed(1)
    return 0
end

This function is usually called after we hook TS_LUA_RESPONSE_TRANSFORM.

ts.client_request.client_addr.get_addr

syntax: ts.client_request.client_addr.get_addr()

context: do_remap or later

description: This function can be used to get socket address of the client.

Here is an example::

function do_remap
    ip, port, family = ts.client_request.client_addr.get_addr()
    return 0
end

The ts.client_request.client_addr.get_addr function returns three values, ip is a string, port and family is number.

ts.client_request.get_method

syntax: ts.client_request.get_method()

context: do_remap or later

description: This function can be used to retrieve the current request’s request method name. String like “GET” or “POST” is returned.

ts.client_request.set_method

syntax: ts.client_request.set_method(METHOD_NAME)

context: do_remap

description: This function can be used to override the current request’s request method with METHOD_NAME.

ts.client_request.get_url

syntax: ts.client_request.get_url()

context: do_remap or later

description: This function can be used to retrieve the whole request’s url.

ts.client_request.get_uri

syntax: ts.client_request.get_uri()

context: do_remap or later

description: This function can be used to retrieve the request’s path.

ts.client_request.set_uri

syntax: ts.client_request.set_uri(PATH)

context: do_remap

description: This function can be used to override the request’s path.

ts.client_request.get_uri_args

syntax: ts.client_request.get_uri_args()

context: do_remap or later

description: This function can be used to retrieve the request’s query string.

ts.client_request.set_uri_args

syntax: ts.client_request.set_uri_args(QUERY_STRING)

context: do_remap

description: This function can be used to override the request’s query string.

ts.client_request.header.HEADER

syntax: ts.client_request.header.HEADER = VALUE

syntax: ts.client_request.header[HEADER] = VALUE

syntax: VALUE = ts.client_request.header.HEADER

context: do_remap or later

description: Set, add to, clear or get the current request’s HEADER.

Here is an example::

function do_remap()
    local req_host = ts.client_request.header.Host
    ts.client_request.header['Host'] = 'a.tbcdn.cn'
end
TODO
Short Term
  • document configuration
  • non-blocking I/O operation
  • ts.fetch
Long Term
  • ts.regex
XDebug Plugin

The XDebug plugin allows HTTP clients to debug the operation of the Traffic Server cache using the X-Debug header. The plugin is triggered by the presence of the X-Debug header in the client request. The contents of this header should be the names of the debug headers that are desired in the response. The XDebug plugin will remove the X-Debug header from the client request and inject the desired headers into the client response.

XDebug is a global plugin. It is installed by adding it to the plugin.config file.

Debugging Headers

The XDebug plugin is able to generate the following debugging headers:

Via
If the Via header is requested, the XDebug plugin sets the proxy.config.http.insert_response_via_str configuration variable to 3 for the request.
X-Cache-Key
The X-Cache-Key contains the URL that identifies the HTTP object in the Traffic Server cache. This header is particularly useful if a custom cache key is being used.

API Reference

TSAPI

Synopsis
#include <ts/ts.h>
#include <ts/remap.h>
Description

The Apache Traffic Server API enables you to create plugins, using the C programming language, that customize the behavior of your Traffic Server installation.

Traffic Server enables sophisticated caching and processing of web-related traffic, such as DNS and HTTP requests and responses. Traffic Server itself consists of an event-driven loop that can be simplified as follows:

for (;;) {
    event = get_next_event();
    handle_event (event);
}

You compile your plugin source code to create a shared library that Traffic Server loads when it is started. Your plugin contains callback functions that are registered for specific Traffic Server events. When Traffic Server needs to process an event, it invokes any and all call-back functions you’ve registered for that event type.

Possible uses for plugins include the following:

  • HTTP processing plugins can filter, blacklist, authorize users or transform content.
  • Protocol plugins can enable Traffic Server to proxy-cache new protocol content.
  • A blacklisting plugin denies attempts to access web sites that are off-limits.
  • Append transform plugins add data to HTTP response content.
  • An image conversion plugin transforms JPEG images to GIF images.
  • Compression plugins send response content to a compression server that compresses the data (alternatively, a compression library local to the Traffic Server host machine could do the compression).
  • Authorization plugins check a user’s permissions to access particular web sites. The plugin could consult a local authorization program or send queries to an authorization server.
  • A plugin that gathers client information from request headers and enters this information in a database.
  • A protocol plugin listen for specific protocol requests on a designated port and then uses Traffic Server’s proxy server and cache to serve client requests.
Naming conventions

The Traffic Server API adheres to the following naming conventions:

  • The TS prefix is used for all function and variable names defined in the Traffic Server API. For example, TS_EVENT_NONE, TSMutex, and TSContCreate().
  • Enumerated values are always written in all uppercase letters. For example, TS_EVENT_NONE and TS_VC_CLOSE_ABORT.
  • Constant values are all uppercase; enumerated values can be seen as a subset of constants. For example, TS_URL_SCHEME_FILE and TS_MIME_FIELD_ACCEPT.
  • The names of defined types are mixed-case. For example, TSHttpSsn and TSHttpTxn(). TSDebug()
  • Function names are mixed-case. For example, TSUrlCreate() and TSContDestroy().
  • Function names use the following subject-verb naming style: TS-<subject>-<verb>, where <subject> goes from general to specific. This makes it easier to determine what a function does by reading its name. For example, the function to retrieve the password field (the specific subject) from a URL (the general subject) is TSUrlPasswordGet().
  • Common verbs like Create, Destroy, Get, Set, Copy, Find, Retrieve, Insert, Remove, and Delete are used only when appropriate.
Plugin loading and configuration

When Traffic Server is first started, it consults the plugin.config file to determine the names of all shared plugin libraries that need to be loaded. The plugin.config file also defines arguments that are to be passed to each plugin’s initialization function, TSPluginInit(). The records.config file defines the path to each plugin shared library.

The sample plugin.config file below contains a comment line, a blank line, and two plugin configurations:

# This is a comment line.
my-plugin.so www.junk.com www.trash.com www.garbage.com
some-plugin.so arg1 arg2 $proxy.config.http.cache.on

Each plugin configuration in the plugin.config file resembles a UNIX or DOS shell command; each line in plugin.config cannot exceed 1023 characters.

The first plugin configuration is for a plugin named my-plugin.so. It contains three arguments that are to be passed to that plugin’s initialization routine. The second configuration is for a plugin named some-plugin.so; it contains three arguments. The last argument, $proxy.config.http.cache.on, is actually a configuration variable. Traffic Server will look up the specified configuration variable and substitute its value.

Plugins are loaded and initialized by Traffic Server in the order they appear in the plugin.config file.

Plugin initialization

Each plugin must define an initialization function named TSPluginInit() that Traffic Server invokes when the plugin is loaded. TSPluginInit() is commonly used to read configuration information and register hooks for event notification.

Files

{CONFIG_DIR}/plugin.config, {CONFIG_DIR}/records.config

See also

TSPluginInit(3ts)

TSDebug

Synopsis

#include <ts/ts.h>

void TSDebug(const char * tag, const char * format, ...)
void TSError(const char * tag, const char * format, ...)
int TSIsDebugTagSet(const char * tag)
void TSDebugSpecific(int debug_flag, const char * tag, const char * format, ...)
void TSHttpTxnDebugSet(TSHttpTxn txnp, int on)
void TSHttpSsnDebugSet(TSHttpSsn ssn, int on)
int TSHttpTxnDebugGet(TSHttpTxn txnp)
int TSHttpSsnDebugGet(TSHttpSsn ssn)
const char* TSHttpServerStateNameLookup(TSServerState state)
const char* TSHttpHookNameLookup(TSHttpHookID hook)
const char* TSHttpEventNameLookup(TSEvent event)
void TSAssert(expression)
void TSReleaseAssert(expression)
Description

TSError() is similar to printf() except that instead of writing the output to the C standard output, it writes output to the Traffic Server error log.

TSDebug() is the same as TSError() except that it only logs the debug message if the given debug tag is enabled. It writes output to the Traffic Server debug log.

TSIsDebugTagSet() returns non-zero if the given debug tag is enabled.

In debug mode, TSAssert Traffic Server to prints the file name, line number and expression, and then aborts. In release mode, the expression is not removed but the effects of printing an error message and aborting are. TSReleaseAssert prints an error message and aborts in both release and debug mode.

TSDebugSpecific() emits a debug line even if the debug tag is turned off, as long as debug flag is enabled. This can be used in conjunction with TSHttpTxnDebugSet(), TSHttpSsnDebugSet(), TSHttpTxnDebugGet() and TSHttpSsnDebugGet() to enable debugging on specific session and transaction objects.

TSHttpServerStateNameLookup(), TSHttpHookNameLookup() and TSHttpEventNameLookup() converts the respective internal state to a string representation. This can be useful in debugging (TSDebug()), logging and other types notifications.

Examples

This example uses TSDebugSpecific() to log a message when a specific debugging flag is enabled:

#include <ts/ts.h>

// Produce information about a hook receiving an event
TSDebug(PLUGIN_NAME, "Entering hook=%s, event=%s",
        TSHttpHookNameLookup(hook), TSHttpEventNameLookup(event));

// Emit debug message if "tag" is enabled or the txn debug
// flag is set.
TSDebugSpecifc(TSHttpTxnDebugGet(txn), "tag" ,
        "Hello World from transaction %p", txn);
See also

TSAPI(3ts), printf(3)

TSHttpHookAdd

Synopsis

#include <ts/ts.h>

void TSHttpHookAdd(TSHttpHookID id, TSCont contp)
void TSHttpSsnHookAdd(TSHttpSsn ssnp, TSHttpHookID id, TSCont contp)
void TSHttpTxnHookAdd(TSHttpTxn txnp, TSHttpHookID id, TSCont contp)
Description

Hooks are points in Apache Traffic Server transaction HTTP processing where plugins can step in and do some work. Registering a plugin function for callback amounts to adding the function to a hook. You can register your plugin to be called back for every single transaction, or for specific transactions only.

HTTP transaction hooks are set on a global basis using the function TSHttpHookAdd(). This means that the continuation specified as the parameter to TSHttpHookAdd() is called for every transaction. TSHttpHookAdd() is typically called from TSPluginInit() or TSRemapInit().

TSHttpSsnHookAdd() adds contp to the end of the list of HTTP session hooks specified by id. This means that contp is called back for every transaction within the session, at the point specified by the hook ID. Since contp is added to a session, it is not possible to call TSHttpSsnHookAdd() from the plugin initialization routine; the plugin needs a handle to an HTTP session.

TSHttpTxnHookAdd() adds contp to the end of the list of HTTP transaction hooks specified by id. Since contp is added to a transaction, it is not possible to call TSHttpTxnHookAdd() from the plugin initialization routine but only when the plugin has a handle to an HTTP transaction.

Return values

None. Adding hooks is always successful.

Examples

The following example demonstrates how to add global, session and transaction hooks:

#include <ts/ts.h>

static int
handler(TSCont contp, TSEvent event, void *edata)
{
    TSHttpSsn ssnp;
    TSHttpTxn txnp;

    switch (event){
    case TS_EVENT_HTTP_SSN_START:
        ssnp = (TSHttpSsn) edata;
        // Add a session hook ...
        TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_START_HOOK, contp);
        TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE);
        return 0;
    case TS_EVENT_HTTP_TXN_START:
        txnp = (TSHttpTxn) edata;
        // Add a transaction hook ...
        TSHttpTxnHookAdd(ssnp, TS_HTTP_READ_REQUEST_HDR_HOOK, contp);
        TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
        return 0;
    default:
         break;
    }

    return 0;
}

void
TSPluginInit (int argc, const char *argv[])
{
    TSCont contp;
    contp = TSContCreate(handler, NULL);
    TSHttpHookAdd(TS_HTTP_SSN_START_HOOK, contp);
}
See also

TSAPI(3ts), TSContCreate(3ts), TSLifecycleHookAdd(3ts)

TSHttpParserCreate

Synopsis

#include <ts/ts.h>

TSHttpParser TSHttpParserCreate(void)
void TSHttpParserClear(TSHttpParser parser)
void TSHttpParserDestroy(TSHttpParser parser)
TSParseResult TSHttpHdrParseReq(TSHttpParser parser, TSMBuffer bufp, TSMLoc offset, const char ** start, const char * end)
TSParseResult TSHttpHdrParseResp(TSHttpParser parser, TSMBuffer bufp, TSMLoc offset, const char ** start, const char * end)
Description

TSHttpParserCreate() creates an HTTP parser object. The parser’s data structure contains information about the header being parsed. A single HTTP parser can be used multiple times, though not simultaneously. Before being used again, the parser must be cleared by calling TSHttpParserClear().

TSHttpHdrParseReq() parses an HTTP request header. The HTTP header offset must already be created, and must reside inside the marshal buffer bufp. The start argument points to the current position of the string buffer being parsed and the end argument points to one byte after the end of the buffer to be parsed. On return, start is modified to point past the last character parsed.

It is possible to parse an HTTP request header a single byte at a time using repeated calls to TSHttpHdrParseReq(). As long as an error does not occur, the TSHttpHdrParseReq() function will consume that single byte and ask for more. TSHttpHdrParseReq() should be called after TS_HTTP_READ_REQUEST_HDR_HOOK.

TSHttpHdrParseResp() operates in the same manner as TSHttpHdrParseReq() except it parses an HTTP response header. It should be called after TS_HTTP_READ_RESPONSE_HDR_HOOK.

TSHttpParserClear() clears the specified HTTP parser so it may be used again.

TSHttpParserDestroy() destroys the TSHttpParser object pointed to by parser. The parser pointer must not be NULL.

Return values

TSHttpHdrParseReq() and TSHttpHdrParseResp() both return a TSParseResult value. TS_PARSE_ERROR is returned on error, TS_PARSE_CONT is returned if parsing of the header stopped because the end of the buffer was reached, and TS_PARSE_DONE or TS_PARSE_OK when a \r\n\r\n pattern is encountered, indicating the end of the header.

Bugs

The distinction between the TS_PARSE_DONE and TS_PARSE_OK results is not well-defined. Plugins should expect both status codes and treat them equivalently.

See also

TSAPI(3ts)

TSHttpTxnMilestoneGet

Synopsis

#include <ts/ts.h>

TSReturnCode TSHttpTxnMilestoneGet(TSHttpTxn txnp, TSMilestonesType milestone, TSHRTime* time)
Description

TSHttpTxnMilestoneGet() will fetch a specific milestone timer value for the transaction txnp. These timers are calculated during the lifetime of a transaction and are measured in nanoseconds from the beginning of the transaction. time is used a pointer to storage to update if the call is successful.

TSMilestonesType
Value Milestone
TS_MILESTONE_UA_BEGIN The client connection is accepted.
TS_MILESTONE_UA_READ_HEADER_DONE The request header from the client has been read and parsed.
TS_MILESTONE_UA_BEGIN_WRITE The response header write to the client starts.
TS_MILESTONE_UA_CLOSE Last I/O activity on the client socket, or connection abort.
TS_MILESTONE_SERVER_FIRST_CONNECT First time origin server connect attempted or shared shared session attached.
TS_MILESTONE_SERVER_CONNECT Most recent time origin server connect attempted or shared session attached.
TS_MILESTONE_SERVER_CONNECT_END More recent time a connection attempt was resolved.
TS_MILESTONE_SERVER_BEGIN_WRITE First byte is written to the origin server connection.
TS_MILESTONE_SERVER_FIRST_READ First byte is read from connection to origin server.
TS_MILESTONE_SERVER_READ_HEADER_DONE Origin server response has been read and parsed.
TS_MILESTONE_SERVER_CLOSE Last I/O activity on origin server connection.
TS_MILESTONE_CACHE_OPEN_READ_BEGIN Initiate read of the cache.
TS_MILESTONE_CACHE_OPEN_READ_END Initial cache read has resolved.
TS_MILESTONE_CACHE_OPEN_WRITE_BEGIN Start open for cache write.
TS_MILESTONE_CACHE_OPEN_WRITE_END Cache has been opened for write.
TS_MILESTONE_DNS_LOOKUP_BEGIN Initiate host resolution in HostDB
TS_MILESTONE_DNS_LOOKUP_END Host resolution resolves.
TS_MILESTONE_SM_START Transaction state machine is initialized.
TS_MILESTONE_SM_FINISH Transaction has finished, state machine final logging has started.
  • The server connect times predate the transmission of the SYN packet. That is, before a connection to the origin server is completed.
  • A connection attempt is resolved when no more connection related activity remains to be done, and the connection is either established or has failed.
  • TS_MILESTONE_UA_CLOSE and TS_MILESTONE_SERVER_CLOSE are updated continuously during the life of the transaction, every time there is I/O activity. The updating stops when the corresponding connection is closed, leaving the last I/O time as the final value.
  • The cache OPEN milestones time only the initial setup, the “open”, not the full read or write.
Return values

TS_SUCCESS if successful and time was updated, otherwise TS_ERROR.

See also

TSAPI(3ts)

TSIOBufferCreate

Synopsis

#include <ts/ts.h>

TSIOBuffer TSIOBufferCreate(void)
TSIOBuffer TSIOBufferSizedCreate(TSIOBufferSizeIndex index)
void TSIOBufferDestroy(TSIOBuffer bufp)
int64_t TSIOBufferWrite(TSIOBuffer bufp, const void * buf, int64_t length)
void TSIOBufferProduce(TSIOBuffer bufp, int64_t nbytes)
int64_t TSIOBufferWaterMarkGet(TSIOBuffer bufp)
void TSIOBufferWaterMarkSet(TSIOBuffer bufp, int64_t water_mark)
Description

The TSIOBuffer data structure is the building block of the TSVConn abstraction. An IO buffer is composed of a list of buffer blocks which are reference counted so that they can reside in multiple buffers at the same time. This makes it extremely efficient to copy data from one IO buffer to another using TSIOBufferCopy() since Traffic Server only needs to copy pointers and adjust reference counts appropriately and not actually copy any data; however applications should still strive to ensure data blocks are a reasonable size.

The IO buffer abstraction provides for a single writer and multiple readers. In order for the readers to have no knowledge of each other, they manipulate IO buffers through the TSIOBufferReader data structure. Since only a single writer is allowed, there is no corresponding TSIOBufferWriter data structure. The writer simply modifies the IO buffer directly.

TSIOBufferCreate() creates an empty TSIOBuffer.

TSIOBufferSizedCreate() creates an empty TSIOBuffer with an initial capacity of index bytes.

TSIOBufferDestroy() destroys the IO buffer bufp. Since multiple IO buffers can share data, this does not necessarily free all of the data associated with the IO buffer but simply decrements the appropriate reference counts.

TSIOBufferWrite() appends length bytes from the buffer buf to the IO buffer bufp and returns the number of bytes successfully written into the IO buffer.

TSIOBufferProduce() makes nbytes of data available for reading in the IO buffer bufp. A common pattern for writing to an IO buffer is to copy data into a buffer block and then call INKIOBufferProduce to make the new data visible to any readers.

The watermark of an TSIOBuffer is the minimum number of bytes of data that have to be in the buffer before calling back any continuation that has initiated a read operation on this buffer. As a writer feeds data into the TSIOBuffer, no readers are called back until the amount of data reaches the watermark. Setting a watermark can improve performance because it avoids frequent callbacks to read small amounts of data. TSIOBufferWaterMarkGet() gets the current watermark for the IO buffer bufp.

TSIOBufferWaterMarkSet() gets the current watermark for the IO buffer bufp to water_mark bytes.

See also

TSAPI(3ts), TSIOBufferReaderAlloc(3ts)

TSInstallDirGet

Synopsis

#include <ts/ts.h>

const char * TSInstallDirGet(void)
const char * TSConfigDirGet(void)
const char * TSPluginDirGet(void)
Description

TSInstallDirGet() returns the path to the root of the Traffic Server installation. TSConfigDirGet() and TSPluginDirGet() return the complete, absolute path to the configuration directory and the plugin installation directory respectively.

Return values

These functions all return a NUL-terminated string that must not be modified or freed.

Examples

To load a file that is located in the Traffic Server configuration directory:

#include <ts/ts.h>
#include <stdio.h>

char * path;
asprintf(&path, "%s/example.conf", TSConfigDirGet());
See also

TSAPI(3ts)

TSMBufferCreate

Synopsis

#include <ts/ts.h>

TSMBuffer TSMBufferCreate(void)
TSReturnCode TSMBufferDestroy(TSMBuffer bufp)
TSReturnCode TSHandleMLocRelease(TSMBuffer bufp, TSMLoc parent, TSMLoc mloc)
Description

The marshal buffer or TSMBuffer is a heap data structure that stores parsed URLs, MIME headers and HTTP headers. You can allocate new objects out of marshal buffers, and change the values within the marshal buffer. Whenever you manipulate an object, you require the handle to the object (TSMLoc) and the marshal buffer containing the object (TSMBuffer).

Any marshal buffer fetched by TSHttpTxn*Get() will be used by other parts of the system. Be careful not to destroy these shared, transaction marshal buffers.

TSMBufferCreate() creates a new marshal buffer and initializes the reference count. TSMBufferDestroy() Ignores the reference count and destroys the marshal buffer bufp. The internal data buffer associated with the marshal buffer is also destroyed if the marshal buffer allocated it.

TSHandleMLocRelease() Releases the TSMLoc mloc created from the TSMLoc parent. If a TSMLoc is obtained from a transaction, it does not have a parent TSMLoc. Use the the constant TS_NULL_MLOC as its parent.

Return values

TSMBufferDestroy() and TSHandleMLocRelease() return TS_SUCCESS on success, or TS_ERROR on failure. TSMBufferCreate() returns the new TSMBuffer.

Examples
#include <ts/ts.h>

static void
copyResponseMimeHdr (TSCont pCont, TSHttpTxn pTxn)
{
    TSMBuffer respHdrBuf, tmpBuf;
    TSMLoc respHttpHdrLoc, tmpMimeHdrLoc;

    if (!TSHttpTxnClientRespGet(pTxn, &respHdrBuf, &respHttpHdrLoc)) {
        TSError("couldn't retrieve client response header0);
        TSHandleMLocRelease(respHdrBuf, TS_NULL_MLOC, respHttpHdrLoc);
        goto done;
    }

    tmpBuf = TSMBufferCreate();
    tmpMimeHdrLoc = TSMimeHdrCreate(tmpBuf);
    TSMimeHdrCopy(tmpBuf, tmpMimeHdrLoc, respHdrBuf, respHttpHdrLoc);
    TSHandleMLocRelease(tmpBuf, TS_NULL_MLOC, tmpMimeHdrLoc);
    TSHandleMLocRelease(respHdrBuf, TS_NULL_MLOC, respHttpHdrLoc);
    TSMBufferDestroy(tmpBuf);

done:
    TSHttpTxnReenable(pTxn, TS_EVENT_HTTP_CONTINUE);
}
See also

TSAPI(3ts)

TSMimeHdrFieldValueStringGet

Synopsis

#include <ts/ts.h>

const char* TSMimeHdrFieldValueStringGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int* value_len_ptr)
int TSMimeHdrFieldValueIntGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
int64_t TSMimeHdrFieldValueInt64Get(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
unsigned int TSMimeHdrFieldValueUintGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
time_t TSMimeHdrFieldValueDateGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
Description

MIME headers and fields can be components of request headers, response headers, or standalone headers created within a Traffic Server plugin. The functions here are all used to access header values of specific types, but it is up to the caller to know if a header has appropriate semantics for the API used. For all but TSMimeHdrFieldValueStringGet(), an appropriate data conversion algorithm is applied to the header field string.

All the APIs take a TSMBuffer marshal buffer argument, and a TSMLoc argument indicating the location of the HTTP headers. The required field argument is the locator of a specific header value, as returned by an accessor function such as TSMimeHdrFieldFind().

Within the header field, comma-separated values can be retrieved with an index (idx) ranging from 0 to the maximum number of fields for this value; this maximum is retrieved using TSMimeHdrFieldValuesCount(). An idx value of -1 has the semantics of retrieving the entire header value, regardless of how many comma-separated values there are. If a header is not comma-separated, an idx of 0 or -1 are the same, but the latter is preferred.

TSMimeHdrFieldValueStringGet() returns a pointer to the header value, and populated value_len_ptr with the length of the value in bytes. The returned header value is not NUL-terminated.

Return values

All functions returns the header value with a type matching the respective function name. Using TSMimeHdrFieldValueDateGet() on a header which does not have date-time semantics always returns 0.

Examples

This examples show how to retrieve and copy a specific header.

#include <string.h>
#include <ts/ts.h>

int
get_content_type(TSHttpTxn txnp, char* buf, size_t buf_size)
{
  TSMBuffer bufp;
  TSMLoc hdrs;
  TSMLoc ctype_field;
  int len = -1;

  if (TS_SUCCESS == TSHttpTxnServerRespGet(txnp, &bufp, &hdrs)) {
    ctype_field = TSMimeHdrFieldFind(bufp, hdrs, TS_MIME_FIELD_CONTENT_TYPE, TS_MIME_LEN_CONTENT_TYPE);

    if (TS_NULL_MLOC != ctype_field) {
      const char* str = TSMimeHdrFieldValueStringGet(bufp, hdrs, ctype_field, -1, &len);

      if (len > buf_size)
        len = buf_size;
      memcpy(buf, str, len);
      TSHandleMLocRelease(bufp, hdrs, ctype_field);
    }
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdrs);
  }

  return len;
}
See also

TSAPI(3ts), TSMBufferCreate(3ts), TSMimeHdrFieldValuesCount(3ts)

TSPluginInit

Synopsis

#include <ts/ts.h>

void TSPluginInit(int argc, const char* argv[])
TSReturnCode TSPluginRegister(TSSDKVersion sdk_version, TSPluginRegistrationInfo* plugin_info)
Description

TSPluginInit() must be defined by all plugins. Traffic Server calls this initialization routine when it loads the plugin and sets argc and argv appropriately based on the values in plugin.config. argc is a count of the number of arguments in the argument vector, argv. The count is at least one because the first argument in the argument vector is the plugins name, which must exist in order for the plugin to be loaded. argv is the vector of arguments. The number of arguments in the vector is argc, and argv[0] always contains the name of the plugin shared library. TSPluginRegister() registers the appropriate SDK version for your plugin. Use this function to make sure that the version of Traffic Server on which your plugin is running supports the plugin.

Return values

TSPluginRegister() returns TS_ERROR if the plugin registration failed.

Examples
#include <ts/ts.h>

void
TSPluginInit (int argc, const char *argv[])
{
    TSPluginRegistrationInfo info;
    info.plugin_name = "hello-world";
    info.vendor_name = "MyCompany";
    info.support_email = "ts-api-support@MyCompany.com";

    if (TSPluginRegister(TS_SDK_VERSION_3_0 , &info) != TS_SUCCESS) {
        TSError("Plugin registration failed. 0);
    }
}
See also

TSAPI(3ts), TSInstallDirGet(3ts)

TSRemapInit

Synopsis

#include <ts/ts.h> #include <ts/remap.h>

TSReturnCode TSRemapInit(TSRemapInterface * api_info, char* errbuf, int errbuf_size)
void TSRemapDone(void)
TSRemapStatus TSRemapDoRemap(void * ih, TSHttpTxn rh, TSRemapRequestInfo * rri)
TSReturnCode TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errbuf_size)
void TSRemapDeleteInstance(void *)
void TSRemapOSResponse(void * ih, TSHttpTxn rh, int os_response_type)
Description

The Traffic Server remap interface provides a simplified mechanism for plugins to manipulate HTTP transactions. A remap plugin is not global; it is configured on a per-remap rule basis, which enables you to customize how URLs are redirected based on individual rules in the remap.config file. Writing a remap plugin consists of implementing one or more of the remap entry points and configuring the remap.config configuration file to route the transaction through your plugin. Multiple remap plugins can be specified for a single remap rule, resulting in a remap plugin chain where each plugin is given an opportunity to examine the HTTP transaction.

TSRemapInit() is a required entry point. This function will be called once when Traffic Server loads the plugin. If the optional TSRemapDone() entry point is available, Traffic Server will call then when unloading the remap plugin.

A remap plugin may be invoked for different remap rules. Traffic Server will call the entry point each time a plugin is specified in a remap rule. When a remap plugin instance is no longer required, Traffic Server will call TSRemapDeleteInstance().

TSRemapDoRemap() is called for each HTTP transaction. This is a mandatory entry point. In this function, the remap plugin may examine and modify the HTTP transaction.

Return values

TSRemapInit() and TSRemapNewInstance() should return TS_SUCCESS on success, and TS_ERROR otherwise. A return value of TS_ERROR is unrecoverable.

TSRemapDoRemap() returns a status code that indicates whether the HTTP transaction has been modified and whether Traffic Server should continue to evaluate the chain of remap plugins. If the transaction was modified, the plugin should return TSREMAP_DID_REMAP or TSREMAP_DID_REMAP_STOP; otherwise it should return TSREMAP_NO_REMAP or TSREMAP_NO_REMAP_STOP. If Traffic Server should not send the transaction to subsequent plugins in the remap chain, return TSREMAP_NO_REMAP_STOP or TSREMAP_DID_REMAP_STOP. Returning TSREMAP_ERROR causes Traffic Server to stop evaluating the remap chain and respond with an error.

See also

TSAPI(3ts)

TSTrafficServerVersionGet

Synopsis

#include <ts/ts.h>

const char * TSTrafficServerVersionGet(void)
int TSTrafficServerVersionGetMajor(void)
int TSTrafficServerVersionGetMinor(void)
int TSTrafficServerVersionGetPatch(void)
Description

TSTrafficServerVersionGet() returns a pointer to a string of characters that indicates the Traffic Server release version. This string must not be modified.

The other APIs return an integer version number.

Example
#include <stdio.h>
#include <ts/ts.h>

int
check_ts_version()
{
    const char *ts_version = TSTrafficServerVersionGet();
    int result = 0;

    if (ts_version) {
        int major_ts_version = 0;
        int minor_ts_version = 0;
        int patch_ts_version = 0;

        if (sscanf(ts_version, "%d.%d.%d", &major_ts_version,
                &minor_ts_version, &patch_ts_version) != 3) {
            return 0;
        }

        /* We need at least Traffic Server 3.0 */
        if (major_ts_version >= 3) {
            result = 1;
        }
    }

    return result;
}

void
TSPluginInit (int argc, const char *argv[])
{
    TSPluginRegistrationInfo info;
    info.plugin_name = "hello-world";
    info.vendor_name = "MyCompany";
    info.support_email = "ts-api-support@MyCompany.com";

    if (TSPluginRegister(TS_SDK_VERSION_3_0 , &info) != TS_SUCCESS) {
        TSError("Plugin registration failed. 0);
    }

    if (!check_ts_version()) {
        TSError("Plugin requires Traffic Server 3.0 or later0);
        return;
    }

    TSDebug("debug-hello", "Hello World!0);
}
See also

TSAPI(3ts)

TSUrlCreate

Synopsis

#include <ts/ts.h>

TSReturnCode TSUrlCreate(TSMBuffer bufp, TSMLoc* locp)
TSReturnCode TSUrlClone(TSMBuffer dest_bufp, TSMBuffer src_bufp, TSMLoc src_url, TSMLoc* locp)
TSReturnCode TSUrlCopy(TSMBuffer dest_bufp, TSMLoc dest_url, TSMBuffer src_bufp, TSMLoc src_url)
TSParseResult TSUrlParse(TSMBuffer bufp, TSMLoc offset, const char ** start, const char* end)
Description

The URL data structure is a parsed version of a standard internet URL. The Traffic Server URL API provides access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs, and retrieve or modify parts of URLs, such as their host, port or scheme information.

TSUrlCreate() creates a new URL within the marshal buffer bufp. Release the resulting handle with a call to TSHandleMLocRelease().

TSUrlClone() copies the contents of the URL at location src_url within the marshal buffer src_bufp to a location within the marshal buffer dest_bufp. Release the returned handle with a call to TSHandleMLocRelease().

TSUrlCopy() copies the contents of the URL at location src_url within the marshal buffer src_bufp to the location dest_url within the marshal buffer dest_bufp. TSUrlCopy() works correctly even if src_bufp and dest_bufp point to different marshal buffers. It is important for the destination URL (its marshal buffer and TSMLoc) to have been created before copying into it.

TSUrlParse() parses a URL. The start pointer is both an input and an output parameter and marks the start of the URL to be parsed. After a successful parse, the start pointer equals the end pointer. The end pointer must be one byte after the last character you want to parse. The URL parsing routine assumes that everything between start and end is part of the URL. It is up to higher level parsing routines, such as TSHttpHdrParseReq(), to determine the actual end of the URL.

Return values

The TSUrlParse() function returns a TSParseResult, where TS_PARSE_ERROR indicates an error. Success is indicated by one of TS_PARSE_DONE, TS_PARSE_OK or TS_PARSE_CONT. The other APIs all return a TSReturnCode, indicating success (TS_SUCCESS) or failure (TS_ERROR) of the operation.

See also

TSAPI(3ts), TSMBufferCreate(3ts), TSUrlHostGet(3ts), TSUrlHostSet(3ts), TSUrlStringGet(3ts), TSUrlPercentEncode(3ts)

TSUrlHostGet

Synopsis

#include <ts/ts.h>

const char* TSUrlHostGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlSchemeGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlUserGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlPasswordGet(TSMBuffer bufp, TSMLoc offset, int* length)
int TSUrlPortGet(TSMBuffer bufp, TSMLoc offset)
const char* TSUrlPathGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlHttpQueryGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlHttpParamsGet(TSMBuffer bufp, TSMLoc offset, int* length)
const char* TSUrlHttpFragmentGet(TSMBuffer bufp, TSMLoc offset, int* length)
Description

The URL data structure is a parsed version of a standard internet URL. The Traffic Server URL API provides access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs, and retrieve or modify parts of URLs, such as their host, port or scheme information.

TSUrlSchemeGet(), TSUrlUserGet(), TSUrlPasswordGet(), TSUrlHostGet(), TSUrlHttpParamsGet(), TSUrlHttpQueryGet() and TSUrlHttpFragmentGet() each retrieve an internal pointer to the specified portion of the URL from the marshall buffer bufp. The length of the returned string is placed in length and a pointer to the URL portion is returned.

TSUrlPortGet() retrieves the port number portion of the URL located at offset within the marshal buffer bufp. If there is no explicit port number in the URL, a canonicalized valued is returned based on the URL scheme.

Return values

All APIs except TSUrlPortGet() returns a string, which is not guaranteed to be NULL terminated. You must therefore always use the length value to determine the actual length of the returned string.

TSUrlPortGet() simply returns the port number as an integer, possibly canonicalized with 80 for HTTP and 443 for HTTPS schemes. If there is neither port nor scheme information available in the URL, 0 is returned.

See also

TSAPI(3ts), TSUrlCreate(3ts), TSUrlHostSet(3ts), TSUrlStringGet(3ts), TSUrlPercentEncode(3ts)

TSUrlHostSet

Synopsis

#include <ts/ts.h>

TSReturnCode TSUrlHostSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlSchemeSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlUserSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlPasswordSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlPortSet(TSMBuffer bufp, TSMLoc offset, int port)
TSReturnCode TSUrlPathSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlHttpQuerySet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlHttpParamsSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
TSReturnCode TSUrlHttpFragmentSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length)
Description

The URL data structure is a parsed version of a standard internet URL. The Traffic Server URL API provides access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs, and retrieve or modify parts of URLs, such as their host, port or scheme information.

TSUrlSchemeSet(), TSUrlUserSet(), TSUrlPasswordSet(), TSUrlHostSet(), TSUrlHttpParamsSet(), TSUrlHttpQuerySet() and TSUrlHttpFragmentSet() each set the specified portion of the URL located at offset within the marshal buffer bufp to the string value. If length is -1 then these functions assume that value is NULL-terminated. Otherwise, the length of the string value is taken to be the value of length. These functions copy the string to within bufp, so it can be subsequently modified or deleted.

TSUrlPortSet() sets the port number portion of the URL located at offset within the marshal buffer bufp to the value port. Normal canonicalization based on the URL scheme still applies.

Return values

All these APIs returns a TSReturnCode, indicating success (TS_SUCCESS) or failure (TS_ERROR) of the operation.

See also

TSAPI(3ts), TSUrlCreate(3ts), TSUrlHostGet(3ts), TSUrlStringGet(3ts), TSUrlPercentEncode(3ts)

TSUrlPercentEncode

Synopsis

#include <ts/ts.h>

TSReturnCode TSUrlPercentEncode(TSMBuffer bufp, TSMLoc offset, char* dst, size_t dst_size, size_t* length, const unsigned char* map)
TSReturnCode TSStringPercentEncode(const char* str, int str_len, char* dst, size_t dst_size, size_t* length, const unsigned char* map)
TSReturnCode TSStringPercentDecode(const char* str, size_t str_len, char* dst, size_t dst_size, size_t* length)
Description

The URL data structure is a parsed version of a standard internet URL. The Traffic Server URL API provides access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs, and retrieve or modify parts of URLs, such as their host, port or scheme information.

TSUrlPercentEncode() performs percent-encoding of the URL object, storing the new string in the dst buffer. The length parameter will be set to the new (encoded) string length, or 0 if the encoding failed. TSStringPercentEncode() is similar but operates on a string. If the optional map parameter is provided (not NULL) , it should be a map of characters to encode.

TSStringPercentDecode() perform percent-decoding of the string in the str buffer, writing to the dst buffer. The source and destination can be the same, in which case they overwrite. The decoded string is always guaranteed to be no longer than the source string.

Return values

All these APIs returns a TSReturnCode, indicating success (TS_SUCCESS) or failure (TS_ERROR) of the operation.

See also

TSAPI(3ts), TSUrlCreate(3ts), TSUrlHostGet(3ts), TSUrlHostSet(3ts), TSUrlStringGet(3ts)

TSUrlStringGet

Synopsis

#include <ts/ts.h>

char* TSUrlStringGet(TSMBuffer bufp, TSMLoc offset, int* length)
int TSUrlLengthGet(TSMBuffer bufp, TSMLoc offset)
void TSUrlPrint(TSMBuffer bufp, TSMLoc offset, TSIOBuffer iobufp)
Description

The URL data structure is a parsed version of a standard internet URL. The Traffic Server URL API provides access to URL data stored in marshal buffers. The URL functions can create, copy, retrieve or delete entire URLs, and retrieve or modify parts of URLs, such as their host, port or scheme information.

TSUrlStringGet() constructs a string representation of the URL located at offset within the marshal buffer bufp. TSUrlStringGet() stores the length of the allocated string in the parameter length. This is the same length that TSUrlLengthGet() returns. The returned string is allocated by a call to TSmalloc() and must be freed by a call to TSfree(). If length is NULL then no attempt is made to de-reference it.

TSUrlLengthGet() calculates the length of the URL located at offset within the marshal buffer bufp as if it were returned as a string. This length will be the same as the length returned by TSUrlStringGet().

TSUrlPrint() formats a URL stored in an TSMBuffer to an TSIOBuffer.

See also

TSAPI(3ts), TSmalloc(3ts), TSUrlCreate(3ts), TSUrlHostGet(3ts), TSUrlHostSet(3ts), TSUrlPercentEncode(3ts)

TSLifecycleHookAdd

Synopsis

#include <ts/ts.h>

void TSLifecycleHookAdd(TSLifecycleHookID id, TSCont contp)
Description

TSLifecycleHookAdd() adds contp to the list of lifecycle hooks specified by id. Lifecycle hooks are based on the Traffic Server process, not on any specific transaction or session. These will typically be called only once during the execution of the Traffic Server process and therefore should be added in TSPluginInit() (which could itself be considered a lifecyle hook). Unlike other hooks, lifecycle hooks may not have a well defined ordering and use of them should not assume that one of the hooks is always called before another unless specifically mentioned.

TS_LIFECYCLE_PORTS_INITIALIZED_HOOK

Called after the proxy server port data structures have been initialized but before connections are accepted on those ports. The sockets corresponding to the ports may or may not be open depending on how the traffic_server process was invoked. Other API functions that depend on server ports should be called from this hook and not TSPluginInit().

Invoked with the event TS_EVENT_LIFECYCLE_PORTS_INITIALIZED and NULL data.

TS_LIFECYCLE_PORTS_READY_HOOK

Called after enabling connections on the proxy server ports. Because Traffic Server is threaded this may or may not be called before any connections are accepted. The hook code may assume that any connection to Traffic Server started after this hook is called will be accepted by Traffic Server, making this a convenient place to signal external processes of that.

Invoked with the event TS_EVENT_LIFECYCLE_PORTS_READY and NULL data.

TS_LIFECYCLE_CACHE_READY_HOOK

Called after Traffic Server cache initialization has finished.

Invoked with the event TS_EVENT_LIFECYCLE_CACHE_READY and NULL data.

Ordering

TS_LIFECYCLE_PORTS_INITIALIZED_HOOK will always be called before TS_LIFECYCLE_PORTS_READY_HOOK.

Examples

The following example demonstrates how to correctly use TSNetAcceptNamedProtocol(), which requires the proxy ports to be initialized and therefore does not work if called from TSPluginInit() directly.

#include <ts/ts.h>

#define SSL_PROTOCOL_NAME "whatever"

static int
ssl_proto_handler(TSCont contp, TSEvent event, void* data)
{
   /// Do named protocol handling.
}

static int
local_ssl_init(TSCont contp, TSEvent event, void *edata)
{
   if (TS_EVENT_LIFECYCLE_PORTS_INITIALIZED == event) { // just to be safe.
      TSNetAcceptNamedProtocol(
         TSContCreate(ssl_proto_handler, TSMutexCreate()),
         SSL_PROTOCOL_NAME
      );
   }
   return 0;
}

void
TSPluginInit (int argc, const char *argv[])
{
   TSLifecycleHookAdd(TS_LIFECYCLE_PORTS_INITIALIZED_HOOK, TSContCreate(local_ssl_init, NULL));
}
History

Lifecycle hooks were introduced to solve process initialization ordering issues (TS-1487). Different API calls required different modules of Traffic Server to be initialized for the call to work, but others did not work that late in initialization, which was problematic because all of them could effectively only be called from TSPluginInit() . The solution was to move TSPluginInit() as early as possible in the process initialization and provide hooks for API calls that needed to be invoked later which served essentially as additional pluging initialization points.

See also

TSAPI(3ts), TSContCreate(3ts)

TSHttpOverridableConfig

Synopsis

#include <ts/ts.h>

TSOverridableConfigKey
TSReturnCode TSHttpTxnConfigIntSet(TSHttpTxn txnp, TSOverridableConfigKey key, TSMgmtInt value)
TSReturnCode TSHttpTxnConfigIntGet(TSHttpTxn txnp, TSOverridableConfigKey key, TSMgmtInt* value)
TSReturnCode TSHttpTxnConfigFloatSet(TSHttpTxn txnp, TSOverridableConfigKey key, TSMgmtFloat value)
TSReturnCode TSHttpTxnConfigFloatGet(TSHttpTxn txnp, TSOverridableConfigKey key, TSMgmtFloat* value)
TSReturnCode TSHttpTxnConfigStringSet(TSHttpTxn txnp, TSOverridableConfigKey key, const char* value, int length)
TSReturnCode TSHttpTxnConfigStringGet(TSHttpTxn txnp, TSOverridableConfigKey key, const char** value, int* length)
TSReturnCode TSHttpTxnConfigFind(const char* name, int length, TSOverridableConfigKey* key, TSRecordDataType* type)
Description

Some of the values that are set in records.config can be changed for a specific transaction. It is important to note that these functions change the configuration values stored for the transation, which is not quite the same as changing the actual operating values of the transaction. The critical effect is the value must be changed before it is used by the transaction - after that, changes will not have any effect.

All of the ...Get functions store the internal value in the storage indicated by the value argument. For strings length* will receive the length of the string.

The values are identified by the enumeration TSOverridableConfigKey. String values can be used indirectly by first passing them to TSHttpTxnConfigFind() which, if the string matches an overridable value, return the key and data type.

Configurations

The following configurations (from records.config) are overridable:

proxy.config.url_remap.pristine_host_hdr
proxy.config.http.chunking_enabled
proxy.config.http.negative_caching_enabled
proxy.config.http.negative_caching_lifetime
proxy.config.http.cache.when_to_revalidate
proxy.config.http.keep_alive_enabled_in
proxy.config.http.keep_alive_enabled_out
proxy.config.http.keep_alive_post_out
proxy.config.http.share_server_sessions
proxy.config.net.sock_recv_buffer_size_out
proxy.config.net.sock_send_buffer_size_out
proxy.config.net.sock_option_flag_out
proxy.config.http.forward.proxy_auth_to_parent
proxy.config.http.anonymize_remove_from
proxy.config.http.anonymize_remove_referer
proxy.config.http.anonymize_remove_user_agent
proxy.config.http.anonymize_remove_cookie
proxy.config.http.anonymize_remove_client_ip
proxy.config.http.anonymize_insert_client_ip
proxy.config.http.response_server_enabled
proxy.config.http.insert_squid_x_forwarded_for
proxy.config.http.server_tcp_init_cwnd
proxy.config.http.send_http11_requests
proxy.config.http.cache.http
proxy.config.http.cache.cluster_cache_local
proxy.config.http.cache.ignore_client_no_cache
proxy.config.http.cache.ignore_client_cc_max_age
proxy.config.http.cache.ims_on_client_no_cache
proxy.config.http.cache.ignore_server_no_cache
proxy.config.http.cache.cache_responses_to_cookies
proxy.config.http.cache.ignore_authentication
proxy.config.http.cache.cache_urls_that_look_dynamic
proxy.config.http.cache.required_headers
proxy.config.http.insert_request_via_str
proxy.config.http.insert_response_via_str
proxy.config.http.cache.heuristic_min_lifetime
proxy.config.http.cache.heuristic_max_lifetime
proxy.config.http.cache.guaranteed_min_lifetime
proxy.config.http.cache.guaranteed_max_lifetime
proxy.config.http.cache.max_stale_age
proxy.config.http.keep_alive_no_activity_timeout_in
proxy.config.http.keep_alive_no_activity_timeout_out
proxy.config.http.transaction_no_activity_timeout_in
proxy.config.http.transaction_no_activity_timeout_out
proxy.config.http.transaction_active_timeout_out
proxy.config.http.origin_max_connections
proxy.config.http.connect_attempts_max_retries
proxy.config.http.connect_attempts_max_retries_dead_server
proxy.config.http.connect_attempts_rr_retries
proxy.config.http.connect_attempts_timeout
proxy.config.http.post_connect_attempts_timeout
proxy.config.http.down_server.cache_time
proxy.config.http.down_server.abort_threshold
proxy.config.http.cache.fuzz.time
proxy.config.http.cache.fuzz.min_time
proxy.config.http.doc_in_cache_skip_dns
proxy.config.http.background_fill_active_timeout
proxy.config.http.response_server_str
proxy.config.http.cache.heuristic_lm_factor
proxy.config.http.cache.fuzz.probability
proxy.config.http.background_fill_completed_threshold
proxy.config.net.sock_packet_mark_out
proxy.config.net.sock_packet_tos_out
proxy.config.http.insert_age_in_response
proxy.config.http.chunking.size
proxy.config.http.flow_control.enabled
proxy.config.http.flow_control.low_water
proxy.config.http.flow_control.high_water
proxy.config.http.cache.range.lookup
proxy.config.http.normalize_ae_gzip
proxy.config.http.default_buffer_size
proxy.config.http.default_buffer_water_mark
proxy.config.http.request_header_max_size
proxy.config.http.response_header_max_size
proxy.config.http.negative_revalidating_enabled
proxy.config.http.negative_revalidating_lifetime
proxy.config.http.accept_encoding_filter_enabled
Examples

Enable transaction buffer control with a high water mark of 262144 and a low water mark of 65536.

int callback(TSCont contp, TSEvent event, void* data)
{
   TSHttpTxn txnp = static_cast<TSHttpTxn>(data);
   TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED, 1);
   TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK, 262144);
   TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_FLOW_CONTROL_LOWER_WATER_MARK, 65536);
   return 0;
}
See also

TSAPI(3ts)

TSmalloc

Synopsis

#include <ts/ts.h>

void * TSmalloc(size_t size, const char * path)
void * TSrealloc(void * ptr, size_t size, const char * path)
char * TSstrdup(const char * str)
char * TSstrndup(const char * str, size_t size)
size_t TSstrlcpy(char * dst, const char * src, size_t size)
size_t TSstrlcat(char * dst, const char * src, size_t size)
void TSfree(void * ptr)
Description

Traffic Server provides a number of routines for allocating and freeing memory. These routines correspond to similar routines in the C library. For example, TSrealloc() behaves like the C library routine realloc(). There are two reasons to use the routines provided by Traffic Server. The first is portability. The Traffic Server API routines behave the same on all of Traffic Servers supported platforms. For example, realloc() does not accept an argument of NULL on some platforms. The second reason is that the Traffic Server routines actually track the memory allocations by file and line number. This tracking is very efficient, is always turned on, and is useful for tracking down memory leaks.

TSmalloc() returns a pointer to size bytes of memory allocated from the heap. Traffic Server uses TSmalloc() internally for memory allocations. Always use TSfree() to release memory allocated by TSmalloc(); do not use free().

TSstrdup() returns a pointer to a new string that is a duplicate of the string pointed to by str. The memory for the new string is allocated using TSmalloc() and should be freed by a call to TSfree(). TSstrndup() returns a pointer to a new string that is a duplicate of the string pointed to by str and size bytes long. The new string will be NUL-terminated. This API is very useful for transforming non NUL-terminated string values returned by APIs such as TSMimeHdrFieldValueStringGet() into NUL-terminated string values. The memory for the new string is allocated using TSmalloc() and should be freed by a call to TSfree().

TSstrlcpy() copies up to size - 1 characters from the NUL-terminated string src to dst, NUL-terminating the result.

TSstrlcat() appends the NUL-terminated string src to the end of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-terminating the result.

TSfree() releases the memory allocated by TSmalloc() or TSrealloc(). If ptr is NULL, TSfree() does no operation.

See also

TSAPI(3ts)

TSAPI Types

Synopsis
#include <ts/ts.h>
#include <ts/remap.h>
Description

The Apache Traffic Server API provides large number of types. Many of them are specific to a particular API function or function group, but others are used more widely. Those are described on this page.

TSCont

An opaque type that represents a Traffic Server continuation.

TSHttpHookID

An enumeration that identifies a specific type of hook for HTTP transactions.

TSHttpSsn

An opaque type that represents a Traffic Server session.

TSHRTime

“High Resolution Time”

A 64 bit time value, measured in nanoseconds.

TSHttpTxn

An opaque type that represents a Traffic Server HTTP transaction.

TSLifecycleHookID

An enumeration that identifies a life cycle hook.

TSReturnCode

An indicator of the results of an API call. A value of TS_SUCCESS means the call was successful. Any other value indicates a failure and is specific to the API call.

TSRecordDataType

An enumeration that specifies the type of a value in an internal data structure that is accessible via the API.

TSMgmtInt

The type used internally for an integer. This corresponds to the value TS_RECORDDATATYPE_INT for TSRecordDataType.

TSMgmtFloat

The type used internally for a floating point value. This corresponds to the value TS_RECORDDATATYPE_FLOAT for TSRecordDataType.

Architecture and Hacking

Introduction

The original architectural documents for Traffic Server were lost in the transition to an open source project. The documents in this section are provisional and were written based on the existing code. The purpose is to have a high level description of aspects of Traffic Server to better inform ongoing work.

In the final section on “hacking” we try to document our approaches to understanding and modifying the source.

Contents:

Apache Traffic Server Cache

Contents:

Cache Architecture
Introduction

In addition to an HTTP proxy, Apache Traffic Server is also an HTTP cache. Traffic Server can cache any octet stream although it currently supports only those octet streams delivered by the HTTP protocol. When such a stream is cached (along with the HTTP protocol headers) it is termed an object in the cache. Each object is identified by a globally unique value called a cache key.

The purpose of this document is to describe the basic structure and implementation details of the Traffic Server cache. Configuration of the cache will be discussed only to the extent needed to understand the internal mechanisms. This document will be useful primarily to Traffic Server developers working on the Traffic Server codebase or plugins for Traffic Server. It is assumed the reader is already familiar with the Administrators’ Guide and specifically with HTTP Proxy Caching and Configuring the Cache along with the associated configuration files and values.

Unfortunately the internal terminology is not particularly consistent so this document will frequently use terms in different ways than they are used in the code in an attempt to create some consistency.

Cache Layout

The following sections describe how persistent cache data is structured. Traffic Server treats its persisent storage an undifferentiated collection of bytes, assuming no other structure to it. In particular it does not use the file system of the host operating system. If a file is used it is used only to mark out the set of bytes to be used.

Cache storage

The raw storage for the Traffic Server cache is configured in storage.config. Each line in the file defines a cache span which is treated as a uniform persistent store.

_images/cache-spans.png

Two cache spans

This storage organized in to a set of cache volumes which are defined in volume.config for the purposes of the administrator. These are the units that used for all other administator level configuration.

Cache volumes can be defined by a percentage of the total storage or an absolute amount of storage. By default each cache volume is spread across all of the cache spans for robustness. The intersection of a cache volume and a cache span is a cache stripe. Each cache span is divided in to cache stripes and each cache volume is a collection of those stripes.

If the cache volumes for the example cache spans were defined as

_images/ats-cache-volume-definition.png

then the actual layout would look like

_images/cache-span-layout.png

Cache stripes are the fundamental unit of cache for the implementation. A cached object is stored entirely in a single stripe, and therefore in a single cache span - objects are never split across cache spans or volumes. Objects are assigned to a stripe (and hence to a cache volume) automatically based on a hash of the URI used to retrieve the object from the origin server. It is possible to configure this to a limited extent in hosting.config which supports content from specific host or domain to be stored on specific cache volumes. In addition, as of version 4.0.1 it is possible to control which cache spans (and hence, which cache stripes) are contained in a specific cache volume.

The layout and structure of the cache spans, the cache volumes, and the cache stripes that compose them are derived entirely from the storage.config and cache.config and is recomputed from scratch when the traffic_server is started. Therefore any change to those files can (and almost always will) invalidate the existing cache in its entirety.

Stripe Structure

Traffic Server treats the storage associated with a cache stripe as an undifferentiated span of bytes. Internally each stripe is treated almost entirely independently. The data structures described in this section are duplicated for each stripe. Internally the term “volume” is used for these stripes and implemented primarily in Vol. What a user thinks of as a volume (what this document calls a “cache volume”) is represented by CacheVol.

注解

Stripe assignment must be done before working with an object because the directory is local to the stripe. Any cached objects for which the stripe assignment is changed are effectively lost as their directory data will not be found in the new stripe.

Cache Directory

Content in a stripe is tracked via a directory. We call each element of the directory a “directory entry” and each is represented by Dir. Each entry refers to a chunk of contiguous storage in the cache. These are referred to variously as “fragments”, “segments”, “docs” / “documents”, and a few other things. This document will use the term “fragment” as that is the most common reference in the code. The term “Doc” (for Doc) will be used to refer to the header data for a fragment. Overall the directory is treated as a hash with the cache ID as the key. See directory probing for how the cache ID is used to locate a directory entry. The cache ID is in turn computed from a cache key which by default is the URL of the content.

The directory is used as a memory resident structure which means a directory entry is as small as possible (currently 10 bytes). This forces some compromises on the data that can be stored there. On the other hand this means that most cache misses do not require disk I/O which has a large performance benefit.

An additional point is the directory is always fully sized. Once a stripe is initialized the directory size is fixed and never changed. This size is related (roughly linearly) to the size of the stripe. It is for this reason the memory footprint of Traffic Server depends strongly on the size of the disk cache. Because the directory size does not change, neither does this memory requirement so Traffic Server does not consume more memory as more content is stored in the cache. If there is enough memory to run Traffic Server with an empty cache there is enough to run it with a full cache.

_images/cache-directory-structure.png

Each entry stores an offset in the stripe and a size. The size stored in the directory entry is an approximate size which is at least as big as the actual data in the fragment. Exact size data is stored in the fragment header on disk.

注解

Data in HTTP headers cannot be examined without disk I/O. This includes the original URL for the object. The cache key is not stored explicitly and therefore cannot be reliably retrieved.

The directory is a hash table that uses chaining for collision resolution. Because each entry is small they are used directly as the list header of the hash bucket.

Chaining is implemented by imposing grouping structures on the entries in a directory. The first level grouping is a directory bucket. This is a fixed number (currently 4 - defined as DIR_DEPTH) of entries. This serves to define the basic hash buckets with the first entry in each cache bucket serving as the root of the hash bucket.

注解

The term “bucket” is used in the code to mean both the conceptual bucket for hashing and for a structural grouping mechanism in the directory and so these will be qualified as needed to distinguish them. The unqualified term “bucket” is almost always used to mean the structural grouping in the directory.

Directory buckets are grouped in to segments. All segments in a stripe have the same number of buckets. The number of segments in a stripe is chosen so that each segment has as many buckets as possible without exceeding 65535 (216-1) entries in a segment.

_images/dir-segment-bucket.png

Each directory entry has a previous and next index value which is used to link entries in the same segment. Because no segment has more than 65535 entries 16 bits suffices for storing the index values. The stripe header contains an array of entry indices which are used as the roots of entry free lists, one for each segment. Active entries are stored via the bucket structure. When a stripe is initialized the first entry in each bucket is zeroed (marked unused) and all other entries are put in the corresponding segment free list in the stripe header. This means the first entry of each directory bucket is used as the root of a hash bucket and is therefore marked unused rather than being put a free list. The other entries in the directory bucket are preferentially preferred for adding to the corresponding hash bucket but this is not required. The segment free lists are initialized such that the extra bucket entries are added in order - all the seconds, then the thirds, then the fourths. Because the free lists are FIFOs this means extra entries will be selected from the fourth entries across all the buckets first, then the thirds, etc. When allocating a new directory entry in a bucket the entries are searched from first to last, which maximizes bucket locality (that is, cache IDs that map to the same hash bucket will also tend to use the same directory bucket).

_images/dir-bucket-assign.png

Entries are removed from the free list when used and returned when no longer in use. When a fragment needs to be put in to the directory the cache ID is used to locate a hash bucket (which also determines the segment and directory bucket). If the first entry in the directory bucket is marked unused, it is used. If not then the other entries in the bucket are searched and if any are on the free list, that entry is used. If none are available then the first entry on the segment free list is used. This entry is attached to the hash bucket via the same next and previous indices used for the free list so that it can be found when doing a lookup of a cache ID.

Storage Layout

The storage layout is the stripe metadata followed by cached content. The metadata consists of three parts - the stripe header, the directory, and the stripe footer. The metadata is stored twice. The header and the footer are instances of VolHeaderFooter. This is a stub structure which can have a trailing variable sized array. This array is used as the segment free list roots in the directory. Each contains the segment index of the first element of the free list for the segment. The footer is a copy of the header without the segment free lists. This makes the size of the header dependent on the directory but not that of the footer.

_images/cache-stripe-layout.png

Each stripe has several values that describe its basic layout.

skip
The start of stripe data. This represents either space reserved at the start of a physical device to avoid problems with the host operating system, or an offset representing use of space in the cache span by other stripes.
start
The offset for the start of the content, after the stripe metadata.
length
Total number of bytes in the stripe. Vol::len.
data length
Total number of blocks in the stripe available for content storage. Vol::data_blocks.

注解

Great care must be taken with sizes and lengths in the cache code because there are at least three different metrics (bytes, cache blocks, store blocks) used in various places.

The total size of the directory (the number of entries) is computed by taking the size of the stripe and dividing by the average object size. The directory always consumes this amount of memory which has the effect that if cache size is increased so is the memory requirement for Traffic Server. The average object size defaults to 8000 bytes but can be configured using proxy.config.cache.min_average_object_size. Increasing the average object size will reduce the memory footprint of the directory at the expense of reducing the number of distinct objects that can be stored in the cache [1].

The content area stores the actual objects and is used as a circular buffer where new objects overwrite the least recently cached objects. The location in a stripe where new cache data is written is called the write cursor. This means that objects can be de facto evicted from cache even if they have not expired if the data is overwritten by the write cursor. If an object is overwritten this is not detected at that time and the directory is not updated. Instead it will be noted if the object is accessed in the future and the disk read of the fragment fails.

_images/ats-cache-write-cursor.png

The write cursor and documents in the cache.

注解

Cache data on disk is never updated.

This is a key thing to keep in mind. What appear to be updates (such as doing a refresh on stale content and getting back a 304) are actually new copies of data being written at the write cursor. The originals are left as “dead” space which will be consumed when the write cursor arrives at that disk location. Once the stripe directory is updated (in memory!) the original fragment in the cache is effectively destroyed. This is the general space management techinque used in other cases as well. If an object needs to removed from cache, only the directory needs to be changed. No other work (and particularly no disk I/O) needs to be done.

Object Structure

Objects are stored as two types of data, metadata and content data. Metadata is all the data about the object and the content and includes the HTTP headers. The content data is the content of the object, the octet stream delivered to the client as the object.

Objects are rooted in a Doc structure stored in the cache. Doc serves as the header data for a fragment and is contained at the start of every fragment. The first fragment for an object is termed the “first Doc” and always contains the object metadata. Any operation on the object will read this fragment first. The fragment is located by converting the cache key for the object to a cache ID and then doing a lookup for a directory entry with that key. The directory entry has the offset and approximate size of the first fragment which is then read from the disk. This fragment will contain the request header and response along with overall object properties (such as content length).

Traffic Server supports varying content for objects. These are called alternates. All metadata for all alternates is stored in the first fragment including the set of alternates and the HTTP headers for them. This enables alternate selection to be done after the first Doc is read from disk. An object that has more than one alternate will have the alternate content stored separately from the first fragment. For objects with only one alternate the content may or may not be in the same (first) fragment as the metadata. Each separate alternate content is allocated a directory entry and the key for that entry is stored in the first fragment metadata.

Prior to version 4.0.1 the header data was stored in the CacheHTTPInfoVector class which was marshaled to a variable length area of the on disk image, followed by information about additional fragments if needed to store the object.

_images/cache-doc-layout-3-2-0.png

Doc layout 3.2.0

This had the problem that with only one fragment table it could not be reliable for objects with more than one alternate [2]. Therefore the fragment data was moved from being a separate variable length section of the metadata to being directly incorporated in to the CacheHTTPInfoVector, yielding a layout of the following form.

_images/cache-doc-layout-4-0-1.png

Doc layout 4.0.1

Each element in the vector contains for each alternate, in addition to the HTTP headers and the fragment table (if any), a cache key. This cache key identifies a directory entry that is referred to as the “earliest Doc”. This is the location where the content for the alternate begins.

When the object is first cached, it will have a single alternate and that will be stored (if not too large) in first Doc. This is termed a resident alternate in the code. This can only happen on the initial store of the object. If the metadata is updated (such as a 304 response to an If-Modified-Since request) then unless the object is small, the object data will be left in the original fragment and a new fragment written as the first fragment, making the alternate non-resident. “Small” is defined as a length smaller than proxy.config.cache.alt_rewrite_max_size.

注解

The CacheHTTPInfoVector is stored only in the first Doc. Subsequent Doc instances for the object, including the earliest Doc, should have an hlen of zero and if not, it is ignored.

Large objects are split in to multiple fragments when written to the cache. This is indicated by a total document length that is longer than the content in first Doc or an earliest Doc. In such a case a fragment offset table is stored. This contains the byte offset in the object content of the first byte of content data for each fragment past the first (as the offset for the first is always zero). This allows range requests to be serviced much more efficiently for large objects, as intermediate fragments that do not contain data in the range can be skipped. The last fragment in the sequence is detected by the fragment size and offset reaching the end of the total size of the object, there is no explicit end mark. Each fragment is computationally chained from the previous in that the cache key for fragment N is computed by:

key_for_N_plus_one = next_key(key_for_N);

where next_key is a global function that deterministically computes a new cache key from an existing cache key.

Objects with multiple fragments are laid out such that the data fragments (including the earliest Doc) are written first and the first Doc is written last. When read from disk, both the first and earliest Doc are validated (tested to ensure that they haven’t been overwritten by the write cursor) to verify that the entire document is present on disk (as they bookend the other fragments - the write cursor cannot overwrite them without overwriting at leastone of the verified Doc instances). Note that while the fragments of a single object are ordered they are not necessarily contiguous as data from different objects are interleaved as the data arrives in Traffic Server.

_images/cache-multi-fragment.png

Multi-alternate and multi-fragment object storage

Documents which are “pinned” into the cache must not be overwritten so they are “evacuated” from in front of the write cursor. Each fragment is read and rewritten. There is a special lookup mechanism for objects that are being evacuated so that they can be found in memory rather than the potentially unreliable disk regions. The cache scans ahead of the write cursor to discover pinned objects as there is a dead zone immediately before the write cursor from which data cannot be evacuated. Evacuated data is read from disk and placed in the write queue and written as its turn comes up.

It appears that objects can only be pinned via the cache.config file and if the proxy.config.cache.permit.pinning is set to non-zero (it is zero by default). Objects which are in use when the write cursor is near use the same underlying evacuation mechanism but are handled automatically and not via the explicit pinned bit in Dir.

[1]It could, under certain circumstances, be accurate for none of the alternates.
Additional Notes

Some general observations on the data structures.

Cyclone buffer

Because the cache is a cyclone cache objects are not preserved for an indefinite time. Even if the object is not stale it can be overwritten as the cache cycles through its volume. Marking an object as pinned preserves the object through the passage of the write cursor but this is done by copying the object across the gap, in effect re-storing it in the cache. Pinning large objects or a large number objects can lead to a excessive disk activity. The original purpose of pinning seems to have been for small, frequently used objects explicitly marked by the administrator.

This means the purpose of expiration data on objects is simply to prevent them from being served to clients. They are not in the standard sense deleted or cleaned up. The space can’t be immediately reclaimed in any event because writing only happens at the write cursor. Deleting an object consists only of removing the directory entries in the volume directory which suffices to (eventually) free the space and render the document inaccessible.

Historically the cache is designed this way because web content was relatively small and not particularly consistent. The design also provides high performance and low consistency requirements. There are no fragmentation issues for the storage, and both cache misses and object deletions require no disk I/O. It does not deal particularly well with long term storage of large objects. See the Volume Tagging appendix for details on some work in this area.

Disk Failure

The cache is designed to be relatively resistant to disk failures. Because each storage unit in each volume is mostly independent the loss of a disk simply means that the corresponding Vol instances (one per cache volume that uses the storage unit) becomes unusable. The primary issue is updating the volume assignment table to both preserve assignments for objects on still operational volumes while distributing the assignments from the failed disk to those operational volumes. This mostly done in:

AIO_Callback_handler::handle_disk_failure

Restoring a disk to active duty is quite a bit more difficult task. Changing the volume assignment of a cache key renders any currently cached data inaccessible. This is obviouly not a problem when a disk has failed, but is a bit trickier to decide which cached objects are to be de facto evicted if a new storage unit is added to a running system. The mechanism for this, if any, is still under investigation.

Implementation Details
Stripe Directory

The in memory volume directory entries are defined as described below.

class Dir

Defined in P_CacheDir.h.

Name Type Use
offset unsigned int:24 Offset of first byte of metadata (volume relative)
big unsigned in:2 Size multiplier
size unsigned int:6 Size
tag unsigned int:12 Partial key (fast collision check)
phase unsigned int:1 Unknown
head unsigned int:1 Flag: first fragment in an object
pinned unsigned int:1 Flag: document is pinned
token unsigned int:1 Flag: Unknown
next unsigned int:16 Segment local index of next entry.
offset_high inku16 High order offset bits

The stripe directory is an array of Dir instances. Each entry refers to a span in the volume which contains a cached object. Because every object in the cache has at least one directory entry this data has been made as small as possible.

The offset value is the starting byte of the object in the volume. It is 40 bits long split between the offset (lower 24 bits) and offset_high (upper 16 bits) members. Note that since there is a directory for every storage unit in a cache volume, this is the offset in to the slice of a storage unit attached to that volume.

The size and big values are used to calculate the approximate size of the fragment which contains the object. This value is used as the number of bytes to read from storage at the offset value. The exact size is contained in the object metadata in Doc which is consulted once the read has completed. For this reason the approximate size needs to be at least as large as the actual size but can be larger, at the cost of reading the extraneous bytes.

The computation of the approximate size of the fragment is defined as:

( *size* + 1 ) * 2 ^ ( ``CACHE_BLOCK_SHIFT`` + 3 * *big* )

where CACHE_BLOCK_SHIFT is the bit width of the size of a basic cache block (9, corresponding to a sector size of 512). Therefore the value with current defines is:

( *size* + 1 ) * 2 ^ (9 + 3 * *big*)

Because big is 2 bits the values for the multiplier of size are

big Multiplier Maximum Size
0 512 (2^9) 32768 (2^15)
1 4096 (2^12) 262144 (2^18)
2 32768 (2^15) 2097152 (2^21)
3 262144 (2^18) 16777216 (2^24)

Note also that size is effectively offset by one, so a value of 0 indicates a single unit of the multiplier.

The target fragment size can set with the records.config value

proxy.config.cache.target_fragment_size

This value should be chosen so that it is a multiple of a cache entry multiplier. It is not necessary to make it a power of 2 [3]. Larger fragments increase I/O efficiency but lead to more wasted space. The default size (1M, 2^20) is a reasonable choice in most circumstances altough in very specific cases there can be benefit from tuning this parameter. Traffic Server imposes an internal maximum of a 4194232 bytes which is 4M (2^22) less the size of a struct Doc. In practice then the largest reasonable target fragment size is 4M - 262144 = 3932160.

When a fragment is stored to disk the size data in the cache index entry is set to the finest granularity permitted by the size of the fragment. To determine this consult the cache entry multipler table, find the smallest maximum size that is at least as large as the fragment. That will indicate the value of big selected and therefore the granularity of the approximate size. That represents the largest possible amount of wasted disk I/O when the fragment is read from disk.

The set of index entries for a volume are grouped in to segments. The number of segments for an index is selected so that there are as few segments as possible such that no segment has more than 2^16 entries. Intra-segment references can therefore use a 16 bit value to refer to any other entry in the segment.

Index entries in a segment are grouped buckets each of DIR_DEPTH (currently 4) entries. These are handled in the standard hash table way, giving somewhat less than 2^14 buckets per segment.

[2]The comment in records.config is simply wrong.
Directory Probing

Directory probing is locating a specific directory entry in the stripe directory based on a cache ID. This is handled primarily by the function dir_probe(). This is passed the cache ID (key), a stripe (d), and a last collision (last_collision). The last of these is an in and out parameter, updated as useful during the probe.

Given an ID, the top half (64 bits) is used as a segment index, taken modulo the number of segments in the directory. The bottom half is used as a bucket index, taken modulo the number of buckets per segment. The last_collision value is used to mark the last matching entry returned by dir_probe.

After computing the appropriate bucket, the entries in that bucket are searched to find a match. In this case a match is detected by comparison of the bottom 12 bits of the cache ID (the cache tag). The search starts at the base entry for the bucket and then proceeds via the linked list of entries from that first entry. If a tag match is found and there is no collision then that entry is returned and last_collision is updated to that entry. If collision is set, then if it isn’t the current match the search continues down the linked list, otherwise collision is cleared and the search continues. The effect of this is that matches are skipped until the last returned match (last_collision) is found, after which the next match (if any) is returned. If the search falls off the end of the linked list then a miss result is returned (if no last collision), otherwise the probe is restarted after clearing the collision on the presumption that the entry for the collision has been removed from the bucket. This can lead to repeats among the returned values but guarantees that no valid entry will be skipped.

Last collision can therefore be used to restart a probe at a later time. This is important because the match returned may not be the actual object - although the hashing of the cache ID to a bucket and the tag matching is unlikely to create false positives, that is possible. When a fragment is read the full cache ID is available and checked and if wrong, that read can be discarded and the next possible match from the directory found because the cache virtual connection tracks the last collision value.

Cache Operations

Cache activity starts after the HTTP request header has been parsed and remapped. Tunneled transactions do not interact with the cache because the headers are never parsed.

To understand the logic we must introduce the term “cache valid” which means something that is directly related to an object that is valid to be put in the cache (e.g. a DELETE which refers to a URL that is cache valid but cannot be cached itself). This is important because Traffic Server computes cache validity several times during a transaction and only performs cache operations for cache valid results. The criteria used changes during the course of the transaction as well. This is done to avoid the cost of cache activity for objects that cannot be in the cache.

The three basic cache operations are lookup, read, and write. We will take deleting entries as a special case of writing where only the volume directory is updated.

After the client request header is parsed and is determined to be potentially cacheable, a cache lookup is done. If successful a cache read is attempted. If either the lookup or the read fails and the content is considered cacheable then a cache write is attempted.

Cacheability

The first thing done with a request with respect to cache is to determine whether it is potentially a valid object for the cache. After initial parsing and remapping this check is done primarily to detect a negative result because if so all further cache processing is skipped – it will not be put in to the cache nor will a cache lookup be done. There are a number of prerequisites along with configuration options to change them. Additional cacheability checks are done later in the process when more is known about the transaction (such as plugin operations and the origin server response). Those checks are described as appropriate in the sections on the relevant operations.

The set of things which can affect cacheability are

The initial internal checks, along with their records.config overrides[#]_, are done in:

HttpTransact::is_request_cache_lookupable

The checks that are done are

Cacheable Method

The request must be one of GET, HEAD, POST, DELETE, PUT.

See HttpTransact::is_method_cache_lookupable().

Dynamic URL

Traffic Server tries to avoid caching dynamic content because it’s dynamic. A URL is considered dynamic if it

  • is not HTTP or HTTPS
  • has query parameters
  • ends in asp
  • has cgi in the path

This check can be disabled by setting a non-zero value for:

proxy.config.http.cache.cache_urls_that_look_dynamic

In addition if a TTL is set for rule that matches in cache.config then this check is not done.

Range Request
Cache valid only if proxy.config.http.cache.range.lookup in records.config is non-zero. This does not mean the range request can be cached, only that it might be satisfiable from the cache.

A plugin can call TSHttpTxnReqCacheableSet() to force the request to be viewed as cache valid.

[3]The code appears to check cache.config in this logic by setting the does_config_permit_lookup in the cache_info.directives of the state machine instance but I can find no place where the value is used. The directive does_config_permit_storing is set and later checked so the directive (from the administrator point of view) is effective in preventing caching of the object.
Cache Lookup

If the initial request is not determined to be cache invalid then a lookup is done. Cache lookup determines if an object is in the cache and if so, where it is located. In some cases the lookup proceeds to read the first Doc from disk to verify the object is still present in the cache.

There are three basic steps to a cache lookup.

  1. The cache key is computed.

    This is normally computed using the request URL but it can be overridden by a plugin . As far as I can tell the cache index string is not stored anywhere, it presumed computable from the client request header.

  2. The cache stripe is determined (based on the cache key).

    The cache key is used as a hash key in to an array of Vol instances. The construction and arrangement of this array is the essence of how volumes are assigned.

  3. The cache stripe directory is probed using the index key computed from the cache key.

    Various other lookaside directories are checked as well, such as the aggregation buffer.

  4. If the directory entry is found the first Doc is read from disk and checked for validity.

    This is done in CacheVC::openReadStartHead() or CacheVC::openReadStartEarliest() which are tightly coupled methods.

If the lookup succeeds then a more detailed directory entry (struct OpenDir) is created. Note that the directory probe includes a check for an already extant OpenDir which if found is returned without additional work.

Cache Read

Cache read starts after a successful cache lookup. At this point the first Doc has been loaded in to memory and can be consulted for additional information. This will always contain the HTTP headers for all alternates of the object.

At this point an alternate for the object is selected. This is done by comparing the client request to the stored response headers, but it can be controlled by a plugin using TS_HTTP_ALT_SELECT_HOOK.

The content can now be checked to see if it is stale by calculating the “freshness” of the object. This is essential checking how old the object is by looking at the headers and possibly other metadata (note the headers can’t be checked until we’ve selected an alternate).

Most of this work is done in:

HttpTransact::what_is_document_freshness

First the TTL (time to live) value which can be set in cache.config is checked if the request matches the configuration file line. This is done based on when the object was placed in cache, not on any data in the headers.

Next an internal flag (“needs-revalidate-once”) is checked if the cache.config value “revalidate-after” is not set, and if set the object is marked “stale”.

After these checks the object age is calculated by:

HttpTransactHeaders::calculate_document_age

and then any configured fuzzing is applied. The limits to this age based on available data is calculated by:

HttpTransact::calculate_document_freshness_limit

How this age is used is determined by the records.config value:

proxy.config.http.cache.when_to_revalidate

If this is zero then the built caclulations are used which compare the freshness limits with document age, modified by any of the client supplied cache control values max-age, min-fresh, max-stale unless explicitly overridden in cache.config.

If the object is not stale then it is served to the client. If stale the client request may be changed to an If Modified Since request to revalidate.

The request is served using a standard virtual connection tunnel (HttpTunnel) with the CacheVC acting as the producer and the client NetVC acting as the sink. If the request is a range request this can be modified with a transform to select the appropriate parts of the object or, if the request contains a single range, it can use the range acceleration.

Range acceleration is done by consulting a fragment offset table attached to the earliest Doc which contains offsets for all fragments past the first. This allows loading the fragment containing the first requested byte immediately rather than performing reads on the intermediate fragments.

Cache Write

Writing to cache is handled by an instance of the class CacheVC. This is a virtual connection which receives data and writes it to cache, acting as a sink. For a standard transaction data transfers between virtual connections (VConns) are handled by HttpTunnel. Writing to cache is done by attaching a CacheVC instance as a tunnel consumer. It therefore operates in parallel with the virtual connection that transfers data to the client. The data does not flow to the cache and then to the client, it is split and goes both directions in parallel. This avoids any data synchronization issues between the two.

While each CacheVC handles its transactions independently, they do interact at the volume level as each CacheVC makes calls to the volume object to write its data to the volume content. The CacheVC accumulates data internally until either the transaction is complete or the amount of data to write exceeds the target fragment size. In the former case the entire object is submitted to the volume to be written. In the latter case a target fragment size amount of data is submitted and the CacheVC continues to operate on subsequent data. The volume in turn places these write requests in an holding area called the aggregation buffer.

For objects under the target fragment size there is no consideration of order, the object is simply written to the volume content. For larger objects the earliest Doc is written first and the first Doc written last. This provides some detection ability should the object be overwritten. Because of the nature of the write cursor no fragment after the first fragment (in the earliest Doc) can be overwritten without also overwriting that first fragment (since we know at the time the object was finalized in the cache the write cursor was at the position of the first Doc).

注解

It is the responsibility of the CacheVC to not submit writes that exceed the target fragment size.

Update

Cache write also covers the case where an existing object in the cache is modified. This occurs when

  • A conditional request is made to the origin server and a 304 - Not Modified response is received.
  • An alternate of the object is retrieved from an origin server and added to the object.
  • An alternate of the object is removed (e.g., due to a DELETE request).

In every case the metadata for the object must be modified. Because Traffic Server never updates data already in the cache this means the first Doc will be written to the cache again and the volume directory entry updated. Because a client request has already been processed the first Doc has been read from cache and is in memory. The alternate vector is updated as appropriate (an entry added or removed, or changed to contain the new HTTP headers), and then written to disk. It is possible for multiple alternates to be updated by different CacheVC instances at the same time. The only contention is the first Doc, the rest of the data for each alternate is completely independent.

Aggregation Buffer

Disk writes to cache are handled through an aggregation buffer. There is one for each Vol instance. To minimize the number of system calls data is written to disk in units of roughly target fragment size bytes. The algorithm used is simple - data is piled up in the aggregation buffer until no more will fit without going over the target fragment size, at which point the buffer is written to disk and the volume directory entries for objects with data in the buffer are updated with the actual disk locations for those objects (which are determined by the write to disk action). After the buffer is written it is cleared and process repeats. There is a special lookup table for the aggregation buffer so that object lookup can find cache data in that memory.

Because data in the aggregation buffer is visible to other parts of the cache, particularly cache lookup, there is no need to push a partial filled aggregation buffer to disk. In effect any such data is effectively memory cached until enough additional cache content arrives to fill the buffer.

The target fragment size has little effect on small objects because the fragment sized is used only to parcel out disk write operations. For larger objects the effect very significant as it causes those objects to be broken up in to fragments at different locations on in the volume. Each fragment write has its own entry in the volume directory which are computational chained (each cache key is computed from the previous one). If possible a fragment table is accumulated in the earliest Doc which has the offsets of the first byte for each fragment.

Evacuation Mechanics

By default the write cursor will overwrite (de facto evict from cache) objects as it proceeds once it has gone around the cache stripe at least once. In some cases this is not acceptable and the object is evacuated by reading it from the cache and then writing it back to cache which moves the physical storage of the object from in front of the write cursor to behind the write cursor. Objects that are evacuated are handled in this way based on data in stripe data structures (attached to the Vol instance).

Evacuation data structures are defined by dividing up the volume content in to a disjoint and contiguous set of regions of EVACUATION_BUCKET_SIZE bytes. The Vol::evacuate member is an array with an element for each evacuation region. Each element is a doubly linked list of EvacuationBlock instances. Each instance contains a Dir that specifies the fragment to evacuate. It is assumed that an evacuation block is placed in the evacuation bucket (array element) that corresponds to the evacuation region in which the fragment is located although no ordering per bucket is enforced in the linked list (this sorting is handled during evacuation). Objects are evacuated by specifying the first or earliest fragment in the evactuation block. The evactuation operation will then continue the evacuation for subsequent fragments in the object by adding those fragments in evacuation blocks. Note that the actual evacuation of those fragments is delayed until the write cursor reaches the fragments, it is not necessarily done at the time the first / earliest fragment is evacuated.

There are two types of evacuations, reader based and forced. The EvacuationBlock has a reader count to track this. If the reader count is zero, then it is a forced evacuation and the the target, if it exists, will be evacuated when the write cursor gets close. If the reader value is non-zero then it is a count of entities that are currently expecting to be able to read the object. Readers increment the count when they require read access to the object, or create the EvacuationBlock with a count of 1. When a reader is finished with the object it decrements the count and removes the EvacuationBlock if the count goes to zero. If the EvacuationBlock already exists with a count of zero, the count is not modified and the number of readers is not tracked, so the evacuation is valid as long as the object exists.

Evacuation is driven by cache writes, essentially in Vol::aggWrite. This method processes the pending cache virtual connections that are trying to write to the stripe. Some of these may be evacuation virtual connections. If so then the completion callback for that virtual connection is called as the data is put in to the aggregation buffer.

When no more cache virtual connections can be processed (due to an empty queue or the aggregation buffer filling) then Vol::evac_range is called to clear the range to be overwritten plus an additional EVACUATION_SIZE range. The buckets covering that range are checked. If there are any items in the buckets a new cache virtual connection (a “doc evacuator”) is created and used to read the evacuation item closest to the write cursor (i.e. with the smallest offset in the stripe) instead of the aggregation write proceeding. When the read completes it is checked for validity and if valid, the cache virtual connection for it is placed at the front of the write queue for the stripe and the write aggregation resumed.

Before doing a write, the method Vol::evac_range() is called to start an evacuation. If any fragments are found in the buckets in the range the earliest such fragment (smallest offset, closest to the write cursor) is selected and read from disk and the aggregation buffer write is suspended. The read is done via a cache virtual connection which also effectively serves as the read buffer. Once the read is complete, that cache virtual connection instance (the “doc evacuator”) is place at the front of the stripe write queue and written out in turn. Because the fragment data is now in memory it is acceptable to overwrite the disk image.

Note that when normal stripe writing is resumed, this same check is done again, each time evauating (if needed) a fragment and queuing them for writing in turn.

Updates to the directory are done when the write for the evacuated fragment completes. Multi-fragment objects are detected after the read completes for a fragment. If it is not the first fragment then the next fragment is marked for evacuation (which in turn, when it is read, will pull the subsequent fragment). The logic doesn’t seem to check the length and presumes that the end of the alternate is when the next key is not in the directory.

This interacts with the “one at a time” strategy of the aggregation write logic. If a fragment is close to the fragment being evacuated it may end up in the same evacuation bucket. Because the aggregation write checks every time for the “next” fragment to evacuate it will find that next fragment and evacuate it before it is overwritten.

Evacuation Operation

The primary source of fragments to be evacuated are active fragments. That is fragments which are currently open, to be read or written. This is tracked by the reader value in the evacuation blocks noted above.

If object pinning is enabled then a scan is done on a regular basis as the write cursor moves to detected pinned objects and mark them for evacuation.

Fragments can also be evacuated through hit evacuation. This is configured by proxy.config.cache.hit_evacuate_percent and proxy.config.cache.hit_evacuate_size_limit. When a fragment is read it is checked to see if it is close and in front of the write cursor, close being less than the specified percent of the size of the stripe. If set at the default value of 10, then if the fragment is withing 10% of the size of the stripe it is marked for evacuation. This is cleared if the write cursor passes through the fragment while it remains open (as all open objects are evacuated). If when the object is closed the fragment is still marked then it is placed in the appropriate evacuation bucket.

Initialization

Initialization starts with an instance of Store reading the storage configuration file, by default storage.config. For each valid element in the file an instance of Span is created. These are of basically four types,

  • File
  • Directory
  • Disk
  • Raw device

After creating all the Span instances they are grouped by device id to internal linked lists attached to the Store::disk array [4]. Spans that refer to the same directory, disk, or raw device are coalesced in to a single span. Spans that refer to the same file with overlapping offsets are also coalesced [5]. This is all done in ink_cache_init() called during startup.

注解

The span logic is also used by the HostDB and more than one otherwise inexplicable feature is provided by the span logic for that module.

After configuration initialization the cache processor is started by calling CacheProcessor::start(). This does a number of things.

For each valid span, an instance of CacheDisk is created. This class is a continuation and so can be used to perform potentially blocking operations on the span. The primary use of these is to be passed to the AIO threads as the callback when an I/O operation completes. These are then dispatched to AIO threads to perform storage unit initialization. After all of those have completed, the resulting storage is distributed across the volumes in cplist_reconfigure(). The CacheVol instances are created at this time.

Cache stripe assignment setup is done once all stripes have initialized (that is, the stripe header information has been successfully read from disk for all stripes). The assignment information is stored as an array of indices. These are indices in to an array of stripes. Both the assignment and the stripe arrays are stored in an instance of CacheHostRecord. Assignment initialization consists of populating the assignment array which is much larger than the stripe array.

There is an instance of CacheHostRecord for each line in hosting.config and one “generic” record. For the configured instances the set of stripes is determined from the cache volume specified in the line. If no lines are specified all stripes are placed in the generic record, otherwise only those stripes marked as default are placed in the generic record.

注解

If hosting records are specified it is an error to not specify at least one default cache volume.

The assignment table is initialized in build_vol_hash_table() which is called for each CacheHostRecord instance. For each strip in the host record a sequence of pseudo-random numbers is generated, starting with the folded hash of the stripe hash identifier, which is the device path followed by the skip and size values for that stripe, making it unique. This also makes the sequence deterministic for any particular stripe. Each stripe gets one number in its sequence for every VOL_HASH_ALLOC_SIZE (8 MB currently) of storage. These numbers are paired with the stripe index, combined across all stripes, then sorted by the random values. The resulting array is sampled for every slot in the stripe assignment table by dividing the maximum random value by the size of the assignment table and using the value midway between each multiple of the result of the division. The coalesced psuedo-random sequence is scanned for each sample in turn and the first number not greater than the sample is found. The stripe associated with that value is used for that assignment table entry.

While this procedure is determinstic it is sensitive to initial conditions, including the size of each stripe.

Footnotes

[4]Work is under way on extending this to include objects that are in the ram cache.
[5]This linked list is mostly ignored in later processing, causing all but one file or directory storage units on the same device to be ignored. See TS-1869.
[6]It is unclear to me how that can happen, as the offsets are computed later and should all be zero at the time the spans are coalesced, and as far as I can tell the sort / coalesce is only done during initialization.
Cache Data Structures
class OpenDir

An open directory entry. It contains all the information of a Dir plus additional information from the first Doc.

class CacheVC

A virtual connection class which accepts input for writing to cache.

int CacheVC::openReadStartHead(int event, Event* e)

Do the initial read for a cached object.

int CacheVC::openReadStartEarliest(int event, Event* e)

Do the initial read for an alternate of an object.

class HttpTunnel

Data transfer driver. This contains a set of producers. Each producer is connected to one or more consumers. The tunnel handles events and buffers so that data moves from producers to consumers. The data, as much as possible, is kept in reference counted buffers so that copies are done only when the data is modified or for sources (which acquire data from outside Traffic Server) and sinks (which move data to outside Traffic Server).

class CacheControlResult

Holds the data from a line in cache.config.

class CacheHTTPInfoVector

Defined in P_CacheHttp.h. This is an array of HTTPInfo objects and serves as the respository of information about alternates of an object. It is marshaled as part of the metadata for an object in the cache.

class HTTPInfo

Defined in HTTP.h.

This class is a wrapper for HTTPCacheAlt. It provides the external API for accessing data in the wrapped class. It contains only a pointer (possibly NULL) to an instance of the wrapped class.

class CacheHTTPInfo

A typedef for HTTPInfo.

class HTTPCacheAlt

Defined in HTTP.h.

This is the metadata for a single alternate for a cached object. In contains among other data

  • The key for the earliest Doc of the alternate.
  • The request and response headers.
  • The fragment offset table. [1]
  • Timestamps for request and response from origin server.
class EvacuationBlock

Record for evacuation.

class Vol

This represents a storage unit inside a cache volume.

off_t Vol::segments

The number of segments in the volume. This will be roughly the total number of entries divided by the number of entries in a segment. It will be rounded up to cover all entries.

off_t Vol::buckets

The number of buckets in the volume. This will be roughly the number of entries in a segment divided by DIR_DEPTH. For currently defined values this is around 16,384 (2^16 / 4). Buckets are used as the targets of the index hash.

DLL<EvacuationBlock> Vol::evacuate

Array of of EvacuationBlock buckets. This is sized so there is one bucket for every evacuation span.

off_t len

Length of stripe in bytes.

int Vol::evac_range(off_t low, off_t high, int evac_phase)

Start an evacuation if there is any EvacuationBlock in the range from low to high. Return 0 if no evacuation was started, non-zero otherwise.

class CacheVol

A cache volume as described in volume.config.

class Doc

Defined in P_CacheVol.h.

uint32_t Doc::magic

Validity check value. Set to DOC_MAGIC for a valid document.

uint32_t Doc::len

The length of this segment including the header length, fragment table, and this structure.

uint64_t Doc::total_len

Total length of the entire document not including meta data but including headers.

INK_MD5 Doc::first_key

First index key in the document (the index key used to locate this object in the volume index).

INK_MD5 Doc::key

The index key for this fragment. Fragment keys are computationally chained so that the key for the next and previous fragments can be computed from this key.

uint32_t Doc::hlen

Document header (metadata) length. This is not the length of the HTTP headers.

uint8_t Doc::ftype

Fragment type. Currently only CACHE_FRAG_TYPE_HTTP is used. Other types may be used for cache extensions if those are ever used / implemented.

uint24_t Doc::flen

Fragment table length, if any. Only the first Doc in an object should contain a fragment table.

The fragment table is a list of offsets relative to the HTTP content (not counting metadata or HTTP headers). Each offset is the byte offset of the first byte in the fragment. The first element in the table is the second fragment (what would be index 1 for an array). The offset for the first fragment is of course always zero and so not stored. The purpose of this is to enable a fast seek for range requests - given the first Doc the fragment containing the first byte in the range can be computed and loaded directly without further disk access.

Removed as of version 3.3.0.

uint32_t Doc::sync_serial

Unknown.

uint32_t Doc::write_serial

Unknown.

uint32_t pinned

Flag and timer for pinned objects.

uint32_t checksum

Unknown. (A checksum of some sort)

class VolHeaderFooter

Footnotes

[1]Changed in version 3.2.0. This previously resided in the first Doc but that caused different alternates to share the same fragment table.
Cache Internals
int DIR_SIZE_WITH_BLOCK(int big)

A preprocessor macro which computes the maximum size of a fragment based on the value of big. This is computed as if the argument where the value of the big field in a struct Dir.

int DIR_BLOCK_SIZE(int big)

A preprocessor macro which computes the block size multiplier for a struct Dir where big is the big field value.

Cache Tools

Tools and techniques for cache monitoring and inspection.

Topics to be done
  • Resident alternates
  • Object refresh
Cache Consistency

The cache is completely consistent, up to and including kicking the power cord out, if the write buffer on consumer disk drives is disabled. You need to use:

hdparm -W0

The cache validates that all the data for the document is available and will silently mark a partial document as a “miss” on read. There is no “gentle” shutdown for traffic server, you just kill the process, so the “recovery” code (fsck) is run every time traffic server starts up.

On startup the two versions of the index are checked, and the last valid one is read into memory. Then traffic server moves forward from the last snapped write cursor and reads all the fragments written to disk, and updates the directory (as in a log-based file system). It stops reading at the write before the last valid write header it sees (as a write is not necessarily atomic because of sector reordering). Then the new updated index is written to the invalid version (in case of a crash during startup) and the system starts.

Volume Tagging

Currently cache volumes are allocated somewhat arbitrarily from storage elements. This enhancement allows the storage.config file to assign storage units to specific volumes although the volumes must still be listed in volume.config in general and in particular to map domains to specific volumes. A primary use case for this is to be able to map specific types of content to different storage elements. This could to have different storage devices for the content (SSD vs. rotational).

Version Upgrade

It is currently the case that any change to the cache format will clear the cache. This is an issue when upgrading the Traffic Server version and should be kept in mind.

Controlling the cache key

The cache key is by default the URL of the request. There are two possible choices, the original (“pristine”) URL and the remapped URL. Which of these is used is determined by the configuration value proxy.config.url_remap.pristine_host_hdr.

This is an INT value. If set to 0 (disabled) then the remapped URL is used, and if it is not 0 (enabled) then the original URL is used. This setting also controls the value of the HOST header that is placed in the request sent to the origin server, using hostname from the original URL if non-0 and the host name from the remapped URL if 0. It has no other effects.

For caching, this setting is irrelevant if no remapping is done or there is a one to one mapping between the original and remapped URLs.

It becomes significant if multiple original URLs are mapped to the same remapped URL. If pristine headers are enabled requests to different original URLs will be stored as distinct objects in the cache. If disabled the remapped URL will be used and there may be collisions. This is bad if the contents different but quite useful if they are the same (e.g., the original URLs are just aliases for the same underlying server).

This is also an issue if a remapping is changed because it is effectively a time axis version of the previous case. If an original URL is remapped to a different server address then the setting determines if existing cached objects will be served for new requests (enabled) or not (disabled). Similarly if the original URL mapped to a particular URL is changed then cached objects from the initial original URL will be served from the updated original URL if pristine headers is disabled.

These collisions are not of themselves good or bad. An administrator needs to decide which is appropriate for their situation and set the value correspondingly.

If a greater degree of control is desired a plugin must be used to invoke the API call TSCacheUrlSet() to provide a specific cache key. The TSCacheUrlSet() API can be called as early as TS_HTTP_READ_REQUEST_HDR_HOOK, but no later than TS_HTTP_POST_REMAP_HOOK. It can be called only once per transaction; calling it multiple times has no additional effect.

A plugin that changes the cache key must do so consistently for both cache hit and cache miss requests because two different requests that map to the same cache key will be considered equivalent by the cache. Use of the URL directly provides this and so must any substitute. This is entirely the responsibility of the plugin, there is no way for the Traffic Server core to detect such an occurrence.

If TSHttpTxnCacheLookupUrlGet() is called after new cache url set by TSCacheUrlSet(), it should use a URL location created by TSUrlCreate() as its 3rd input parameter instead of getting url_loc from client request.

It is a requirement that the string be syntactically a URL but otherwise it is completely arbitrary and need not have any path. For instance if the company Network Geographics wanted to store certain content under its own cache key, using a document GUID as part of the key, it could use a cache key like

ngeo://W39WaGTPnvg

The scheme ngeo was picked because it is not a valid URL scheme and so will not collide with any valid URL.

This can be useful if the URL encodes both important and unimportant data. Instead of storing potentially identical content under different URLs (because they differ on the unimportant parts) a url containing only the important parts could be created and used.

For example, suppose the URL for Network Geographics content encoded both the document GUID and a referral key.

http://network-geographics-farm-1.com/doc/W39WaGTPnvg.2511635.UQB_zCc8B8H

We don’t want to the same content for every possible referrer. Instead we could use a plugin to convert this to the previous example and requests that differed only in the referrer key would all reference the same cache entry. Note that we would also map

http://network-geographics-farm-56.com/doc/W39WaGTPnvg.2511635.UQB_zCc8B8H

to the same cache key. This can be handy for “sharing” content between servers when that content is identical. Note also the plugin can change the cache key or not depending on any data in the request header, for instance not changing the cache key if the request is not in the doc directory. If distinguishing servers is important that can easily be pulled from the request URL and used in the synthetic cache key. The implementor is free to extract all relevant elements for use in the cache key.

While there is explicit no requirement that the synthetic cache key be based on the HTTP request header, in practice it is generally necessary due to the consistency requirement. Because cache lookup happens before attempting to connect to the origin server no data from the HTTP response header is available, leaving only the request header. The most common case is the one described above where the goal is to elide elements of the URL that do not affect the content to minimize cache footprint and improve cache hit rates.

Tiered Storage Design
Introduction

Tiered storage is an attempt to allow Traffic Server to take advantage of physical storage with different properties. This design concerns only mechanism. Policies to take advantage of these are outside of the scope of this document. Instead we will presume an oracle which implements this policy and describe the queries that must be answered by the oracle and the effects of the answers.

Beyond avoiding question of tier policy the design is also intended to be effectively identical to current operations for the case where there is only one tier.

The most common case for tiers is an ordered list of tiers, where higher tiers are presumed faster but more expensive (or more limited in capacity). This is not required. It might be that different tiers are differentiated by other properties (such as expected persistence). The design here is intended to handle both cases.

The design presumes that if a user has multiple tiers of storage and an ordering for those tiers, they will usually want content stored at one tier level to also be stored at every other lower level as well, so that it does not have to be copied if evicted from a higher tier.

Configuration

Each storage unit in storage.config can be marked with a quality value which is 32 bit number. Storage units that are not marked are all assigned the same value which is guaranteed to be distinct from all explicit values. The quality value is arbitrary from the point of view of this design, serving as a tag rather than a numeric value. The user (via the oracle) can impose what ever additional meaning is useful on this value (rating, bit slicing, etc.). In such cases all volumes should be explicitly assigned a value, as the default / unmarked value is not guaranteed to have any relationship to explicit values. The unmarked value is intended to be useful in situations where the user has no interest in tiered storage and so wants to let Traffic Server automatically handle all volumes as a single tier.

Operations

After a client request is received and processed, volume assignment is done. This would be changed to do volume assignment across all tiers simultaneously. For each tier the oracle would return one of four values along with a volume pointer.

READ
The tier appears to have the object and can serve it.
WRITE
The object is not in this tier and should be written to this tier if possible.
RW
Treat as READ if possible but if the object turns out to not in the cache treat as WRITE.
NO_SALE
Do not interact with this tier for this object.

The volume returned for the tier must be a volume with the corresponding tier quality value. In effect the current style of volume assignment is done for each tier, by assigning one volume out of all of the volumes of the same quality and returning one of RW or WRITE depending on whether the initial volume directory lookup succeeds. Note that as with current volume assignment it is presumed this can be done from in memory structures (no disk I/O required).

If the oracle returns READ or RW for more than one tier, it must also return an ordering for those tiers (it may return an ordering for all tiers, ones that are not readable will be ignored). For each tier, in that order, a read of cache storage is attempted for the object. A successful read locks that tier as the provider of cached content. If no tier has a successful read, or no tier is marked READ or RW then it is a cache miss. Any tier marked RW that fails the read test is demoted to WRITE.

If the object is cached every tier that returns WRITE receives the object to store in the selected volume (this includes RW returns that are demoted to WRITE). This is a cache to cache copy, not from the origin server. In this case tiers marked RW that are not tested for read will not receive any data and will not be further involved in the request processing.

For a cache miss, all tiers marked WRITE will receive data from the origin server connection (if successful).

This means, among other things, that if there is a tier with the object all other tiers that are written will get a local copy of the object, the origin server will not be used. In terms of implementation, currently a cache write to a volume is done via the construction of an instance of CacheVC which recieves the object stream. For tiered storage the same thing is done for each target volume.

For cache volume overrides (e.g. via hosting.config) this same process is used except with only the volumes stripes contained within the specified cache volume.

Copying

It may be necessary to provide a mechanism to copy objects between tiers outside of a client originated transaction. In terms of implementation this is straight forward using HttpTunnel as if in a transaction only using a CacheVC instance for both the producer and consumer. The more difficult question is what event would trigger a possible copy. A signal could be provided whenever a volume directory entry is deleted although it should be noted that the object in question may have already been evicted when this event happens.

Additional Notes

As an example use, it would be possible to have only one cache volume that uses tiered storage for a particular set of domains using volume tagging. hosting.config would be used to direct those domains to the selected cache volume. The oracle would check the URL in parallel and return NO_SALE for the tiers in the target cache volume for other domains. For the other tier (that of the unmarked storage units) the oracle would return RW for the tier in all cases as that tier would not be queried for the target domains.

Ram Cache
New Ram Cache Algorithm (CLFUS)

The new Ram Cache uses ideas from a number of cache replacement policies and algorithms, including LRU, LFU, CLOCK, GDFS and 2Q, called CLFUS (Clocked Least Frequently Used by Size). It avoids any patented algorithms and includes the following features:

  • Balances Recentness, Frequency and Size to maximize hit rate (not byte hit rate).
  • Is Scan Resistant and extracts robust hit rates even when the working set does not fit in the Ram Cache.
  • Supports compression at 3 levels fastlz, gzip(libz), and xz(liblzma). Compression can be moved to another thread.
  • Has very low CPU overhead, only little more than a basic LRU. Rather than using an O(lg n) heap, it uses a probabilistic replacement policy for O(1) cost with low C.
  • Has relatively low memory overhead of approximately 200 bytes per object in memory.

The rational for emphasizing hit rate over byte hit rate is that the overhead of pulling more bytes from secondary storage is low compared to the cost of a request.

The Ram Cache consists of an object hash fronting 2 LRU/CLOCK lists and a “Seen” hash table. The first “Cached” list contains objects in memory while the second contains a “History” of objects which have either recently been in memory or are being considered for keeping in memory. The “Seen” hash table is used to make the algorithm scan resistant.

The list entries record the following information:

  • key - 16 byte unique object identifier
  • auxkeys - 8 bytes worth of version number (in our system the block in the partition). When the version of an object changes old entries are purged from the cache.
  • hits - number of hits within this clock period
  • size - the size of the object in the cache
  • len - the actual length of the object (differs from size because of compression and padding)
  • compressed_len - the compressed length of the object
  • compressed (none, fastlz, libz, liblzma)
  • uncompressible (flag)
  • copy - whether or not this object should be copied in and copied out (e.g. HTTP HDR)
  • LRU link
  • HASH link
  • IOBufferData (smart point to the data buffer)

The interface to the cache is Get and Put operations. Get operations check if an object is in the cache and are called on a read attempt. The Put operation decides whether or not to cache the provided object in memory. It is called after a read from secondary storage.

Seen Hash

The Seen List becomes active after the Cached and History lists become full after a cold start. The purpose is to make the cache scan resistant which means that the cache state must not be effected at all by a long sequence Get and Put operations on objects which are seen only once. This is essential, without it not only would the cache be polluted, but it could lose critical information about the objects that it cares about. It is therefore essential that the Cache and History lists are not effected by Get or Put operations on objects seen the first time. The Seen Hash maintains a set of 16 bit hash tags, and requests which do not hit in the object cache (are in the Cache List or History List) and do not match the hash tag result in the hash tag begin updated but are otherwise ignored. The Seen Hash is sized to approximately the number of objects in the cache in order to match the number that are passed through it with the CLOCK rate of the Cached and History Lists.

Cached List

The Cached list contains objects actually in memory. The basic operation is LRU with new entries inserted into a FIFO (queue) and hits causing objects to be reinserted. The interesting bit comes when an object is being considered for insertion. First we check if the Object Hash to see if the object is in the Cached List or History. Hits result in updating the “hit” field and reinsertion. History hits result in the “hit” field being updated and a comparison to see if this object should be kept in memory. The comparison is against the least recently used members of the Cache List, and is based on a weighted frequency:

CACHE_VALUE = hits / (size + overhead)

A new object must beat enough bytes worth of currently cached objects to cover itself. Each time an object is considered for replacement the CLOCK moves forward. If the History object has a greater value then it is inserted into the Cached List and the replaced objects are removed from memory and their list entries are inserted into the History List. If the History object has a lesser value it is reinserted into the History List. Objects considered for replacement (at least one) but not replaced have their “hits” field set to zero and are reinserted into the Cached List. This is the CLOCK operation on the Cached List.

History List

Each CLOCK the least recently used entry in the History List is dequeued and if the “hits” field is not greater than 1 (it was hit at least once in the History or Cached List) it is deleted, otherwise the “hits” is set to zero and it is requeued on the History List.

Compression/Decompression

Compression is performed by a background operation (currently called as part of Put) which maintains a pointer into the Cached List and runs toward the head compressing entries. Decompression occurs on demand during a Get. In the case of objects tagged “copy” the compressed version is reinserted in the LRU since we need to make a copy anyway. Those not tagged “copy” are inserted uncompressed in the hope that they can be reused in uncompressed form. This is a compile time option and may be something we want to change.

There are 3 algorithms and levels of compression (speed on 1 thread i7 920) :

  • fastlz: 173 MB/sec compression, 442 MB/sec decompression : basically free since disk or network will limit first, ~53% final size
  • libz: 55 MB/sec compression, 234 MB/sec decompression : almost free, particularly decompression, ~37% final size
  • liblzma: 3 MB/sec compression, 50 MB/sec decompression : expensive, ~27% final size

These are ballpark numbers, and your millage will vary enormously. JPEG for example will not compress with any of these. The RamCache does detect compression level and will declare something “incompressible” if it doesn’t get below 90% of the original size. This value is cached so that the RamCache will not attempt to compress it again (at least as long as it is in the history).

Host Resolution
Introduction

The current mechanism for resolving host names to IP addresses for Traffic Server is contained the HostDB and DNS libraries. These take hostnames and provide IP addresses for them.

The current implementation is generally considered inadequate, both from a functionality point of view and difficulty in working with it in other parts of Traffic Server. As Traffic Server is used in more complex situtations this inadequacy presents increasing problems.

Goals

Updating the host name resolution (currently referred to as “HostDB”) has several functions goals

  • Enable additional processing layers to be easily added.
  • Enable plugins to directly access the name resolution logic
  • Enable plugins to provide name resolution
  • Asynchronous (immediate resolve or callback on block)
  • Minimize allocations – in particular no allocations for cached resolutions
  • Simplify interactions with the resolution, particularly with regard to nameservers, origin server failover, and address family handling.

It is also necessary to support a number of specific features that are either currently available or strongly desired.

  • SplitDNS or its equivalent
  • Use of a hosts file (e.g. /etc/hosts)
  • Simultaneous IPv4 and IPv6 queries
  • IP family control
  • Negative caching * Server connection failures * Query failures * Nameserver failures.
  • Address validity time out control
  • Address round robin support
  • SRV record support (weighted records)
  • Nameserver round robin
  • Plugin access to nameserver data (add, remove, enumerate)
  • Plugin provision of resolvers.
  • Hooks for plugin detection / recovery from resolution events.

One issue is persistence of the cached resolutions. This creates problems for the current implementation (because of size limits it imposes on the cached data) but also allows for quicker restarts in a busy environment.

Basics

The basic design is to separate the functionality into chainable layers so that a resolver with the desired attributes can be assembled from those layers. The core interface is that of a lazy iterator. This object returns one of four results when asked for an address

  • An IP address
  • Done(no more addresses are available)
  • Wait(an address may be available in the future)
  • Fail (no address is available and none will be so in the future)

Each layer (except the bottom) uses this API and also provides it. This enables higher level logic such as the state machine to simply use the resolver as a list without having to backtrack states in the case of failures, or have special cases for different resolution sources.

To perform a resolution, a client creates a query object (potentially on the stack), initializes it with the required data (at least the hostname) and then starts the resolution. Methods on the query object allow its state and IP address data to be accessed.

Required Resolvers
Nameserver
A bottom level resolver that directly queries a nameserver for DNS data. This contains much of the functionality currently in the iocore/dns directory.
SplitDNS
A resolver that directs requests to one of several resolvers. To emulate current behavior these would be Nameserver instances.
NameserverGroup
A grouping mechanism for Nameserver instances that provides failover, round robin, and ordering capabilities. It may be reasonable to merge this with the SplitDNS resolver.
HostFile
A resolver that uses a local file to resolve names.
AddressCache
A resolver that also has a cache for resolution results. It requires another resolver instance to perform the actual resolution.
Preloaded
A resolver that can contain one or more explicitly set IP addresses which are returned. When those are exhausted it falls back to another resolver.
Configuration

To configuration the resolution, each resolver would be assigned a tag. It is not, however, sufficient to simply provide the list of resolver tags because some resolvers require additional configuration. Unfortunately this will likely require a separate configuration file outside of records.config, although we would be able to remove splitdns.config. In this case we would need chain start / end markers around a list of resolver tags. Each tag would the be able to take additional resolver configuration data. For instance, for a SplitDNS resolver the nameservers.

Examples

Transparent operations would benefit from the Preloaded resolver. This would be loaded with the origin host address provided by the client connection. This could be done early in processing and then no more logic would be required to skip DNS processing as it would happen without additional action by the state machine. It would handle the problem of de facto denial of service if an origin server becomes unavailable in that configuration, as Preloaded would switch to alternate addresses automatically.

Adding host file access would be easier as well, as it could be done in a much more modular fashion and then added to the stack at configuration time. Whether such addresses were cached would be controlled by chain arrangement rather yet more configuration knobs.

The default configuration would be Preloaded : AddressCache : Nameserver.

In all cases the state machine makes requests against the request object to get IP addresses as needed.

Issues
Request object allocation

The biggest hurdle is being able to unwind a resolver chain when a block is encountered. There are some ways to deal with this.

1) Set a maximum resolver chain length and declare the request instance so that there is storage for state for that many resolvers. If needed and additional value of maximum storage per chain could be set as well. The expected number of elements in a chain is expected to be limited, 10 would likely be a reaosnable limit. If settable at source configuration time this should be sufficient.

2) Embed class allocators in resolver chains and mark the top / outermost / first resolver. The maximum state size for a resolution can be calculated when the chain is created and then the top level resolver can use an allocation pool to efficiently allocate request objects. This has an advantage that with a wrapper class the request object can be passed along cheaply. Whether that’s an advantage in practice is unclear.

Plugin resolvers

If plugins can provide resolvers, how can these can integrated in to existing resolver chains for use by the HTTP SM for instance?

Feedback

It should be possible for a client to provide feedback about addresses (e.g., the origin server at this address is not available). Not all resolvers will handle feedback but some will and that must be possible.

Related to this is that caching resolvers (such as AddressCache) must be able to iterator over all resolved addresses even if their client does not ask for them. In effect they must background fill the address data.

Hacking
Introduction

This is a documentation stub on how to hack Apache Traffic Server. Here we try to document things such as how to write and run unit or regression tests or how to inspect the state of the core with a debugger.

Glossary

alternate
A variant of a cache object. This was originally created to handle the VARY mechanism but has since been used for additional purposes. All alternates of an object must be equivalent in some manner, that is they are alternate forms of the same stream. The most common example is having normal and compressed versions of the stream.
cache fragment
The unit of storage in the cache. All reads from the cache always read exactly one fragment. Fragments may be written in groups, but every write is always an integral number of fragments. Each fragment has a corresponding directory entry which describes its location in the cache storage.
cache ID
A 128 bit value used as a fixed sized identifier for an object in the cache. This is computed from the cache key using the MD5 hashing function.
cache key
A byte sequence that is a globally unique identifier for an object in the cache. By default the URL for the object is used.
cache object
The minimal self contained unit of data in the cache. Cache objects are the stored version of equivalent content streams from an origin server. A single object can have multiple variants called alternates.
cache span
The physical storage described by a single line in storage.config.
cache stripe
A homogenous persistent store for the cache in a single cache span. A stripe always resides entirely on a single physical device and is treated as an undifferentiated span of bytes. This is the smallest independent unit of storage.
cache tag
The bottom few bits (12 currently) of the cache ID. This is used in the cache directory for a preliminary identity check before going to disk.
cache volume
A user defined unit of persistent storage for the cache. Cache volumes are defined in volume.config. A cache volume is by default spread across cache spans to increase robustness. Each section of a cache volume on a specific cache span is a cache stripe.
continuation
A callable object that contains state. These are are mechanism used by Traffic Server to implement callbacks and continued computations. Continued computations are critical to efficient processing of traffic because by avoiding any blocking operations that wait on external events. In any such case a continuation is used so that other processing can continue until the external event occurs. At that point the continuation is invoked to continue the suspended processing. This can be considered similar to co-routines.
directory bucket
A contiguous fixed sized group of directory entries. This is used for hash bucket maintenance optimization.
directory entry
An in memory entry that describes a cache fragment.
directory segment
A contiguous group of buckets. Each cache stripe has a set of segments all of which have the same number of buckets, although the number of buckets per segment can vary between cache stripes. Segments are administrative in purpose to minimize the size of free list and hash bucket pointers.
revalidation
Verifying that a currently cached object is still valid. This is usually done using an If-Modified-Since request which allows the origin server to validate the content without resending the content.
session
A single connection from a client to Traffic Server, covering all requests and responses on that connection. A session starts when the client connection opens, and ends when the connection closes.
storage unit
Obsolete term for cache span.
transaction
A client request and response, either from the origin server or from the cache. A transaction begins when Traffic Server receives a request, and ends when Traffic Server sends the response.
write cursor
The location in a cache stripe where new data is written.

Indices and tables