Polipo is a caching web proxy designed to be used as a personal cache or a cache shared among a few users.
The latest version of Polipo can be found on the Polipo web page.
This manual was written by Juliusz Chroboczek.
The web is a wide-scale decentralised distributed hypertext system, something that's obviously impossible to achieve reliably.
The web is a collection of resources which are identified by
URLs, strings starting with http://
. At any point in
time, a resource has a certain value, which is called an
instance of the resource.
The fundamental protocol of the web is HTTP, a simple request/response protocol. With HTTP, a client can make a request for a resource to a server, and the server replies with an entity, which is an on-the-wire representation of an instance or of a fragment thereof.
A proxy is a program that acts as both a client and a server. It listens for client requests and forwards them to servers, and forwards the servers' replies to clients.
An HTTP proxy can optimise web traffic away by caching server replies, storing them in memory in case they are needed again. If a reply has been cached, a later client request may, under some conditions, be satisfied without going to the source again.
In addition to taking the shortcuts made possible by caching, proxies can improve performance by generating better network traffic than the client applications would do.
Proxies are also useful in ways unrelated to raw performance. A proxy can be used to contact a server that are not visible to the browser, for example because there is a firewall in the way (see Parent proxies), or because the client and the server use different lower layer protocols (for example IPv4 and IPv6). Another common application of proxies is to modify the data sent to servers and returned to clients, for example by censoring headers that expose too much about the client's identity (see Censoring headers) or removing advertisements from the data returned by the server (see Forbidden).
Polipo is a caching HTTP proxy that was originally designed as a personal proxy, i.e. a proxy that is used by a single user or a small group of users.
Most network benchmarks consider throughput, or the average amount of data being pushed around per unit of time. While important for batch applications (for example benchmarks), average throughput is mostly irrelevant when it comes to interactive web usage. What is more important is a transaction's median latency, or whether the data starts to trickle down before the user gets annoyed.
Typical web caches optimise for throughput — for example, by consulting sibling caches before accessing a remote resource. By doing so, they significantly add to the median latency, and therefore to the average user frustration.
Polipo was designed to minimise latency.
The web was developed by people who were interested in text processing rather than in networking and, unsurprisingly enough, the first versions of the HTTP protocol did not make very good use of network resources. The main problem in HTTP/0.9 and early versions of HTTP/1.0 was that a separate TCP connection (“virtual circuit” for them telecom people) was created for every entity transferred.
Opening multiple TCP connections has significant performance implications. Obviously, connection setup and teardown require additional packet exchanges which increase network usage and, more importantly, latency.
Less obviously, TCP is not optimised for that sort of usage. TCP aims to avoid network congestion, a situation in which the network becomes unusable due to overly aggressive traffic patterns. A correct TCP implementation will very carefully probe the network at the beginning of every connection, which means that a TCP connection is very slow during the first couple of kilobytes transferred, and only gets up to speed later. Because most HTTP entities are small (in the 1 to 10 kilobytes range), HTTP/0.9 uses TCP where it is most inefficient.
Later HTTP versions allow the transfer of multiple entities on a single connection. A connection that carries multiple entities is said to be persistent (or sometimes keep-alive). Unfortunately, persistent connections are an optional feature of HTTP, even in version 1.1.
Polipo will attempt to use persistent connections on the server side, and will honour persistent connection requests from clients.
With persistent connections it becomes possible to pipeline or stream requests, i.e. to send multiple requests on a single connection without waiting for the replies to come back. Because this technique gets the requests to the server faster, it reduces latency. Additionally, because multiple requests can often be sent in a single packet, pipelining reduces network traffic.
Pipelining is a fairly common technique1, but it is not supported by HTTP/1.0. HTTP/1.1 makes pipelining support compulsory in every server implementation that can use persistent connections, but there are a number of buggy servers that claim to implement HTTP/1.1 but don't support pipelining.
Polipo carefully probes for pipelining support in a server and uses pipelining if it believes that it is reliable. Polipo also deeply enjoys being pipelined at by a client2.
A major weakness of the HTTP protocol is its inability to share a single connection between multiple simultaneous transactions — to multiplex a number of transactions over a single connection. In HTTP, a client can either request all instances sequentially, which significantly increases latency, or else open multiple concurrent connections, with all the problems that this implies (see Persistent connections).
Poor Man's Multiplexing (PMM) is a technique that simulates multiplexing by requesting an instance in multiple segments; because the segments are fetched in independent transactions, they can be interleaved with requests for other resources.
Obviously, PMM only makes sense in the presence of persistent connections; additionally, it is only effective in the presence of pipelining (see Pipelining).
PMM poses a number of reliability issues. If the resource being fetched is dynamic, it is quite possible that it will change between segments; thus, an implementation making use of PMM needs to be able to switch to full-resource retrieval when it detects a dynamic resource.
Polipo supports PMM, but it is disabled it by default (see PMM).
A partial instance is an instance that is being cached but only part of which is available in the local cache. There are three ways in which partial instances can arise: client applications requesting only part of an instance (Adobe's Acrobat Reader plugin is famous for that), a server dropping a connection mid-transfer (because it is short on resources, or, surprisingly often, because it is buggy), a client dropping a connection (usually because the user pressed stop).
When an instance is requested that is only partially cached, it is possible to request just the missing data by using a feature of HTTP known as a range request. While support for range requests is optional, most servers honour them in case of static data (data that are stored on disk, rather then being generated on the fly e.g. by a CGI script).
Caching partial instances has a number of positive effects. Obviously, it reduces the amount of data transmitted as the available data needn't be fetched again. Because it prevents partial data from being discarded, it makes it reasonable for a proxy to unconditionally abort a download when requested by the user, and therefore reduces network traffic.
Polipo caches arbitrary partial instances in its in-memory cache. It will only store the initial segment of a partial instance (from its beginning up to its first hole) in its on-disk cache, though. In either case, it will attempt to use range requests to fetch the missing data.
The previous sections pretend that there is only one kind of request in HTTP — the ‘GET’ request. In fact, there are some others.
The ‘HEAD’ request method retrieves data about an resource. Polipo does not normally use ‘HEAD’, but will fall back to using it for validation it if finds that a given server fails to cooperate with its standard validation methods (see Cache transparency). Polipo will correctly reply to a client's ‘HEAD’ request.
The ‘POST’ method is used to request that the server should do something rather than merely sending an entity; it is usually used with HTML forms that have an effect3. The ‘PUT’ method is used to replace an resource with a different instance; it is typically used by web publishing applications.
‘POST’ and ‘PUT’ requests are handled by Polipo pretty much like ‘GET’ and ‘HEAD’; however, for various reasons, some precautions must be taken. In particular, any cached data for the resource they refer to must be discarded, and they can never be pipelined.
Finally, HTTP/1.1 includes a convenient backdoor with the ‘CONNECT’ method. For more information, please see Tunnelling connections.
Polipo does not currently handle the more exotic methods such as ‘OPTIONS’ and ‘PROPFIND’.
I started writing Polipo because the weather was bad. But also because I wanted to implement some features that other web proxies don't have.
Harvest, the grandfather of all web caches, has since evolved into Squid.
Squid sports an elegant single-threaded non-blocking architecture and multiplexes multiple clients in a single process. It also features almost complete support for HTTP/1.1, although for some reason it doesn't currently advertise it.
Squid is designed as a large-scale shared proxy running on a dedicated machine, and therefore carries certain design decisions which make it difficult to use as a personal proxy. Because Squid keeps all resource meta-data in memory, it requires a fair amount of RAM in order to manipulate a reasonably sized cache.
Squid doesn't cache partial instances, and has trouble with instances larger than available memory4. If a client connection is interrupted, Squid has to decide whether to continue fetching the resource (and possibly waste bandwidth) or discard what it already has (and possibly waste bandwidth).
Some versions of squid would, under some circumstances, pipeline up to two outgoing requests on a single connection. At the time of writing, this feature appears to have been disabled in the latest version.
Squid's developers have decided to re-write it in C++.
The Apache web server includes a complete HTTP/1.1 proxy.
The Apache web server was designed to maximise ease of programming — a decision which makes Apache immensely popular for deploying web-based applications. Of course, this ease of programming comes at a cost, and Apache is not the most lightweight proxy available.
As cheaper caching proxies are available, Apache is not useful as a standalone proxy. The main application of Apache's proxy is to join multiple web servers' trees into a single hierarchy.
The Apache proxy doesn't cache partial instances and doesn't pipeline multiple outgoing requests.
WWWOFFLE, an elegant personal proxy, is the primary model for Polipo.
WWWOFFLE has more features than can be described here. It will censor banner ads, clean your HTML, decorate it with random colours, schedule fetches for off-peak hours.
Unfortunately, the HTTP traffic that WWWOFFLE generates is disgusting. It will open a connection for every fetch, and forces the client to do the same.
WWWOFFLE only caches complete instances.
I used WWWOFFLE for many years, and frustration with WWWOFFLE's limitations is the main reason why I started Polipo in the first place.
Junkbuster is a simple non-caching web proxy designed to remove banner ads and cookies. It was the main model for WWWOFFLE's (and therefore Polipo's) header and ad-removing features.
Junkbuster's HTTP support is very simple (some would say broken): it doesn't do persistent connections, and it breaks horribly if the client tries pipelining. Junkbuster is no longer being maintained, and has evolved into Privoxy.
Privoxy is the current incarnation of Junkbuster. Privoxy has the ability to randomly modify web pages before sending them to the browser — for example, remove ‘<blink>’ or ‘<img>’ tags.
Just like its parent, Privoxy cannot do persistent connections. Under some circumstances, it will also buffer whole pages before sending them to the client, which significantly adds to its latency. However, this is difficult to avoid given the kinds of rewriting it attempts to perform.
Oops is a caching web proxy that uses one thread (lightweight process) for every connection. This technique does cost additional memory, but allows good concurrency of requests while avoiding the need for complex non-blocking programming. Oops was apparently designed as a wide-scale shared proxy.
Although Oops' programming model makes it easy to implement persistent connections, Oops insists on opening a separate connection to the server for every single resource fetch, which disqualifies it from production usage.
By default, Polipo runs as a normal foreground job in a terminal in which it can log random “How do you do?” messages. With the right configuration options, Polipo can run as a daemon.
Polipo is run with the following command line:
$ polipo [ -h ] [ -v ] [ -x ] [ -c config ] [ var=val... ]
All flags are optional. The flag -h causes Polipo to print a short help message and to quit. The flag -v causes Polipo to list all of its configuration variables and quit. The flag -x causes Polipo to purge its on-disk cache and then quit (see Purging). The flag -c specifies the configuration file to use (by default ~/.polipo or /etc/polipo/config). Finally, Polipo's configuration can be changed on the command line by assigning values to given configuration variables.
There is a number of variables that you can tweak in order to configure Polipo, and they should all be described in this manual (see Variable index). You can display the complete, most up-to-date list of configuration variables by using the -v command line flag or by accessing the “current configuration” page of Polipo's web interface (see Web interface). Configuration variables can be set either on the command line or else in the configuration file given by the -c command-line flag.
Configuration variables are typed, and -v will display their types. The type can be of one of the following:
The configuration file has a very simple syntax. All blank lines are ignored, as are lines starting with a hash sign ‘#’. Other lines must be of the form
var = val
where var is a variable to set and val is the value to set it to.
It is possible to change the configuration of a running polipo by using the local configuration interface (see Web interface).
If the configuration variable daemonise
is set to true, Polipo
will run as a daemon: it will fork and detach from its controlling
terminal (if any). The variable daemonise
defaults to false.
When Polipo is run as a daemon, it can be useful to get it to
atomically write its pid to a file. If the variable
pidFile
is defined, it should be the name of a file where
Polipo will write its pid. If the file already exists when it
is started, Polipo will refuse to run.
When it encounters a difficulty, Polipo will print a friendly message.
The location where these messages go is controlled by the
configuration variables logFile
and logSyslog
.
If logSyslog
is true
, error messages go to the system log
facility given by logFacility
. If logFile
is set, it is
the name of a file where all output will accumulate. If logSyslog
is false
and logFile
is empty, messages go to the error
output of the process (normally the terminal).
The variable logFile
defaults to empty if daemonise
is
false, and to ‘/var/log/polipo’ otherwise.
The variable logSyslog
defaults to false
, and
logFacility
defaults to ‘user’.
The amount of logging is controlled by the variable logLevel
.
Please see the file ‘log.h’ in the Polipo sources for the
possible values of logLevel
.
(Note that if you are using a shared cache, or logging to syslog,
an overly low logLevel
could be a privacy violation.)
Telling your user-agent (web browser) to use Polipo is an operation that depends on the browser. Many user-agents will transparently use Polipo if the environment variable ‘http_proxy’ points at it; e.g.
$ export http_proxy=http://localhost:8123/
Netscape Navigator, Mozilla, Mozilla Firefox, KDE's Konqueror and probably other browsers require that you configure them manually through their Preferences or Configure menu.
If your user-agent sports such options, tell it to use persistent connections when speaking to proxies, to speak HTTP/1.1 and to use HTTP/1.1 pipelining.
Polipo will shut down cleanly if it receives SIGHUP
,
SIGTERM
or SIGINT
signals; this will normally happen
when a Polipo in the foreground receives a ^C
key press, when
your system shuts down, or when you use the kill
command with
no flags. Polipo will then write-out all its in-memory data to disk
and quit.
If Polipo receives the SIGUSR1
signal, it will write out all
the in-memory data to disk (but won't discard them), reopen the log
file, and then reload the forbidden URLs file (see Forbidden).
Finally, if Polipo receives the SIGUSR2
signal, it will write
out all the in-memory data to disk and discard as much of the memory
cache as possible. It will then reopen the log file and reload the
forbidden URLs file.
Polipo includes a local web server, which is accessible on the same port as the one the proxy listens to. Therefore, by default you can access Polipo's local web server as ‘http://localhost:8123/’.
The data for the local web server can be configured by setting
localDocumentRoot
, which defaults to
/usr/share/polipo/www/. Setting this variable to ‘""’
will disable the local server.
Polipo assumes that the local web tree doesn't change behind its back.
If you change any of the local files, you will need to notify Polipo
by sending it a SIGUSR2
signal (see Stopping).
If you use polipo as a publicly accessible web server, you might want
to set the variable disableProxy
, which will prevent it from
acting as a web proxy. (You will also want to set
disableLocalInterface
(see Web interface), and perhaps run
Polipo in a chroot jail.)
The subtree of the local web space rooted at ‘http://localhost:8123/polipo/’ is treated specially: URLs under this root do not correspond to on-disk files, but are generated by Polipo on-the-fly. We call this subtree Polipo's local web interface.
The page ‘http://localhost:8123/polipo/config?’ contains the values of all configuration variables, and allows setting most of them.
The page ‘http://localhost:8123/polipo/status?’ provides a summary status report about the running Polipo, and allows performing a number of actions on the proxy, notably flushing the in-memory cache.
The page ‘http://localhost:8123/polipo/servers?’ contains the list of known servers, and the statistics maintained about them (see Server statistics).
The pages starting with ‘http://localhost:8123/polipo/index?’ contain indices of the disk cache. For example, the following page contains the index of the cached pages from the server of some random company:
http://localhost:8123/polipo/index?http://www.microsoft.com/
The pages starting with
‘http://localhost:8123/polipo/recursive-index?’ contain recursive
indices of various servers. This functionality is disabled by
default, and can be enabled by setting the variable
disableIndexing
.
If you have multiple users, you will probably want to disable the
local interface by setting the variable disableLocalInterface
.
You may also selectively control setting of variables, indexing and
listing known servers by setting the variables
disableConfiguration
, disableIndexing
and
disableServersList
.
There are three fundamental values that control how Polipo speaks to
clients. The variable proxyAddress
, defines the IP address on
which Polipo will listen; by default, its value is the loopback
address "<IP_ADDRESS>"
, meaning that Polipo will listen on the
IPv4 loopback interface (the local host) only. By setting this
variable to a global IP address or to one of the special values
"::"
or "<IP_ADDRESS>"
, it is possible to allow Polipo to
serve remote clients. This is likely to be a security hole unless you
set allowedClients
to a reasonable value (see Access control).
Note that the type of address that you specify for proxyAddress
will determine whether Polipo listens to IPv4 or IPv6. Currently, the
only way to have Polipo listen to both protocols is to specify the
IPv6 unspecified address ("::"
) for proxyAddress
.
The variable proxyPort
, by default 8123, defines the TCP port
on which Polipo will listen.
The variable proxyName
, which defaults to the host name of the
machine on which Polipo is running, defines the name of the
proxy. This can be an arbitrary string that should be unique among
all instances of Polipo that you are running. Polipo uses it in error
messages and optionally for detecting proxy loops (by using the
‘Via’ HTTP header, see Censoring headers).
By making it possible to have Polipo listen on a non-routable address
(for example the loopback address ‘<IP_ADDRESS>’), the variable
proxyAddress
provides a very crude form of access
control: the ability to decide which hosts are allowed to connect.
A finer form of access control can be implemented by specifying
explicitly a number of client addresses or ranges of addresses
(networks) that a client is allowed to connect from. This is done
by setting the variable allowedClients
.
Every entry in allowedClients
can be an IP address, for example
‘<IP_ADDRESS>’ or ‘::1’. It can also be a network
address, i.e. an IP address and the number of bits in the network
prefix, for example ‘<IP_ADDRESS>/24’ or
‘2001:660:116::/48’. Typical uses of ‘allowedClients’
variable include
allowedClients = <IP_ADDRESS>, ::1, <IP_ADDRESS>/24, 2001:660:116::/48
or, for an IPv4-only version of Polipo,
allowedClients = <IP_ADDRESS>, <IP_ADDRESS>/24
A different form of access control can be implemented by requiring
each client to authenticate, i.e. to prove its identity before
connecting. Polipo currently only implements the most insecure form
of authentication, HTTP basic authentication, which sends
usernames and passwords in clear over the network. HTTP basic
authentication is required when the variable authCredentials
is
not null; its value should be of the form ‘username:password’.
Note that both IP-based authentication and HTTP basic authentication are insecure: the former is vulnerable to IP address spoofing, the latter to replay attacks. If you need to access Polipo over the public Internet, the only secure option is to have it listen over the loopback interface only and use an ssh tunnel (see Parent proxies)5.
A server can have multiple addresses, for example if it is multihomed (connected to multiple networks) or if it can speak both IPv4 and IPv6. Polipo will try all of a hosts addresses in turn; once it has found one that works, it will stick to that address until it fails again.
If connecting via IPv6 there is the possibility to use temporary
source addresses to increase privacy (RFC 3041). The variable
useTemporarySourceAddress
controls the use of temporary
addresses for outgoing connections; if set to true
temporary addresses are preferred, if set to false
static addresses
are used and if set to maybe
(the default) the operation
system default is in effect. This setting is not available
on all operation systems.
A TCP service is identified not only by the IP address of the machine it is running on, but also by a small integer, the TCP port it is listening on. Normally, web servers listen on port 80, but it is not uncommon to have them listen on different ports; Polipo's internal web server, for example, listens on port 8123 by default.
The variable allowedPorts
contains the list of ports that
Polipo will accept to connect to on behalf of clients; it defaults to
‘80-100, 1024-65535’. Set this variable to ‘1-65535’ if your
clients (and the web pages they consult!) are fully trusted. (The
variable allowedPorts
is not considered for tunnelled
connections; see Tunnelling connections).
As a number of HTTP servers and CGI scripts serve incorrect HTTP
headers, Polipo uses a lax parser, meaning that incorrect HTTP
headers will be ignored (a warning will be logged by default). If the
variable laxHttpParser
is not set (it is set by default),
Polipo will use a strict parser, and refuse to serve an
instance unless it could parse all the headers.
When the amount of headers exceeds one chunk's worth (see Chunk memory), Polipo will allocate a big buffer in order to store
the headers. The size of big buffers, and therefore the maximum
amount of headers Polipo can parse, is specified by the variable
bigBufferSize
(32kB by default).
Polipo offers the option to censor given HTTP headers in both client requests and server replies. The main application of this feature is to very slightly improve the user's privacy by eliminating cookies and some content-negotiation headers.
It is important to understand that these features merely make it slightly more difficult to gather statistics about the user's behaviour. While they do not actually prevent such statistics from being collected, they might make it less cost-effective to do so.
The general mechanism is controlled by the variable
censoredHeaders
, the value of which is a case-insensitive list
of headers to unconditionally censor. By default, it is empty, but
I recommend that you set it to ‘From, Accept-Language’. Adding
headers such as ‘Set-Cookie’, ‘Set-Cookie2’, ‘Cookie’,
‘Cookie2’ or ‘User-Agent’ to this list will probably break
many web sites.
The case of the ‘Referer’6 header is treated specially because many
sites will refuse to serve pages when it is not provided. If
censorReferer
is false
(the default), ‘Referer’
headers are passed unchanged to the server. If censorReferer
is maybe
, ‘Referer’ headers are passed to the server only
when they refer to the same host as the resource being fetched. If
censorReferer
is true
, all ‘Referer’ headers are
censored. I recommend setting censorReferer
to maybe
.
Another header that can have privacy implications is the ‘Via’
header, which is used to specify the chain of proxies through which
a given request has passed. Polipo will generate ‘Via’ headers
if the variable disableVia
is false
(it is true by
default). If you choose to generate ‘Via’ headers, you may want
to set the proxyName
variable to some innocuous string
(see Client connections).
Recent versions of HTTP include a mechanism known as content negotiation which allows a user-agent and a server to negotiate the best representation (instance) for a given resource. For example, a server that provides both PNG and GIF versions of an image will serve the PNG version to user-agents that support PNG, and the GIF version to Internet Explorer.
Content negotiation requires that a client should send with every single request a number of headers specifying the user's cultural and technical preferences. Most of these headers do not expose sensitive information (who cares whether your browser supports PNG?). The ‘Accept-Language’ header, however, is meant to convey the user's linguistic preferences. In some cases, this information is sufficient to pinpoint with great precision the user's origins and even his political or religious opinions; think, for example, of the implications of sending ‘Accept-Language: yi’ or ‘ar_PS’.
At any rate, ‘Accept-Language’ is not useful. Its design is based on the assumption that language is merely another representation for the same information, and ‘Accept-Language’ simply carries a prioritised list of languages, which is not enough to usefully describe a literate user's preferences. A typical French user, for example, will prefer an English-language original to a French (mis-)translation, while still wanting to see French language texts when they are original. Such a situation cannot be described by the simple-minded ‘Accept-Language’ header.
In an ideal world, all machines would have perfect connectivity to the network at all times and servers would never crash. In the real world, it may be necessary to avoid hitting the network and have Polipo serve stale objects from its cache.
Setting proxyOffline
to true
prevents Polipo from
contacting remote servers, no matter what. This setting is suitable
when you have no network connection whatsoever.
If proxyOffline
is false, Polipo's caching behaviour is
controlled by a number of variables documented in Tweaking validation.
In order to decide when to pipeline requests (see Pipelining) and whether to perform Poor Man's Multiplexing (see Poor Mans Multiplexing), Polipo needs to keep statistics about servers. These include the server's ability to handle persistent connections, the server's ability to handle pipelined requests, the round-trip time to the server, and the server's transfer rate. The statistics are accessible from Polipo's web interface (see Web interface).
The variable ‘serverExpireTime’ (default 1 day) specifies how
long such information remains valid. If a server has not been
accessed for a time interval of at least serverExpireTime
,
information about it will be discarded.
As Polipo will eventually recover from incorrect information about a server, this value can be made fairly large. The reason why it exists at all is to limit the amount of memory used up by information about servers.
The most important piece of information about a server is whether it
supports persistent connections. If this is the case, Polipo will
open at most serverSlots
connections to that server
(serverSlots1
if the server only implements HTTP/1.0), and
attempt to pipeline; if not, Polipo will hit the server harder,
opening up to serverMaxSlots
connections.
Another use of server information is to decide whether to pipeline
additional requests on a connection that already has in-flight
requests. This is controlled by the variable
pipelineAdditionalRequests
; if it is false
, no
additional requests will be pipelined. If it is true
,
additional requests will be pipelined whenever possible. If it is
maybe
(the default), additional requests will only be pipelined
following small requests, where a small request one whose
download is estimated to take no more than smallRequestTime
(default 5s).
Sometimes, a request has been pipelined after a request that prompts a
very large reply from the server; when that happens, the pipeline
needs be broken in order to reduce latency. A reply is large
and will cause a pipeline to be broken if either its size is at least
replyUnpipelineSize
(default one megabyte) or else the server's
transfer rate is known and the body is expected to take at least
replyUnpipelineTime
to download (default 15s).
The variable maxPipelineTrain
defines the maximum number of
requests that will be pipelined in a single write (default 10).
Setting this variable to a very low value might (or might not) fix
interaction with some unreliable servers that the normal heuristics
are unable to detect.
The variable maxSideBuffering
specifies how much data will be
buffered in a PUT or POST request; it defaults to 1500 bytes. Setting
this variable to 0 may cause some media players that abuse the HTTP
protocol to work.
By default, Polipo does not use Poor Man's Multiplexing (see Poor Mans Multiplexing). If the variable pmmSize
is set to a
positive value, Polipo will use PMM when speaking to servers that are
known to support pipelining. It will request resources by segments of
pmmSize
bytes. The first segment requested has a size of
pmmFirstSize
, which defaults to twice pmmSize
.
PMM is an intrinsically unreliable technique. Polipo makes heroic efforts to make it at least usable, requesting that the server disable PMM when not useful (by using the ‘If-Range’ header) and disabling it on its own if a resource turns out to be dynamic. Notwithstanding these precautions, unless the server cooperates7, you will see failures when using PMM, which will usually result in blank pages and broken image icons; hitting Reload on your browser will usually cause Polipo to notice that something went wrong and correct the problem.
The web contains advertisements that a user-agent is supposed to download together with the requested pages. Not only do advertisements pollute the user's brain, pushing them around takes time and uses up network bandwidth.
Many so-called content providers also track user activities by using web bugs, tiny embedded images that cause a server to log where they are requested from. Such images can be detected because they are usually uncacheable (see Cache transparency) and therefore logged by Polipo by default.
Polipo can be configured to prevent certain URLs from reaching the browser, either by returning a forbidden error message to the user, or by redirecting such URLs to some other URL.
The file pointed at by the variable forbiddenFile
(defaults to
~/.polipo-forbidden or /etc/polipo/forbidden, whichever
exists) specifies the set of URLs that should never be fetched. If
forbiddenFile
is a directory, it will be recursively searched
for files with forbidden URLs.
Every line in a file listing forbidden URLs can either be a domain name — a string that doesn't contain any of ‘/’, ‘*’ or ‘\’ —, or a POSIX extended regular expression. Blank lines are ignored, as are those that start with a hash sign ‘#’.
By default, whenever it attempts to fetch a forbidden URL, the browser will receive a 403 forbidden error from Polipo. Some users prefer to have the browser display a different page or an image.
If forbiddenUrl
is not null, it should represent a URL to which
all forbidden URLs will be redirected. The kind of redirection used
is specified by forbiddenRedirectCode
; if this is 302 (the
default) the redirection will be marked as temporary, if 301 it will
be a permanent one.
Polipo can also use an external process (a Squid-style
redirector) to determine which URLs should be redirected. The name
of the redirector binary is determined from the variable
redirector
, and the kind of redirection generated is specified
by redirectorRedirectCode
, which should be 302 (the default) or
301.
For example, to use Adzapper to redirect ads to an innocuous image, just set
redirector = /usr/bin/adzapper
The low-level protocols beneath HTTP identify machines by IP addresses, sequences of four 8-bit integers such as ‘<IP_ADDRESS>’8. HTTP, on the other hand, and most application protocols, manipulate host names, strings such as ‘www.polipo.org’.
The domain name service (DNS) is a distributed database that maps host names to IP addresses. When an application wants to make use of the DNS, it invokes a resolver, a local library or process that contacts remote name servers.
Polipo usually tries to speak the DNS protocol itself rather than
using the system resolver9. Its
precise behaviour is controlled by the value of
dnsUseGethostbyname
. If dnsUseGethostbyname
is
false
, Polipo never uses the system resolver. If it is
reluctantly
(the default), Polipo tries to speak DNS and falls
back to the system resolver if a name server could not be contacted.
If it is happily
, Polipo tries to speak DNS, and falls back to
the system resolver if the host couldn't be found for any reason (this
is not a good idea for shared proxies). Finally, if
dnsUseGethostbyname
is true
, Polipo never tries to speak
DNS itself and uses the system resolver straight away (this is not
recommended).
If the internal DNS support is used, Polipo must be given a recursive
name server to speak to. By default, this information is taken from
the ‘/etc/resolv.conf’ file; however, if you wish to use
a different name server, you may set the variable dnsNameServer
to an IP address10.
When the reply to a DNS request is late to come, Polipo will retry
multiple times using an exponentially increasing timeout. The maximum
timeout used before Polipo gives up is defined by dnsMaxTimeout
(default 60s); the total time before Polipo gives up on a DNS
query will be roughly twice dnsMaxTimeout
.
The variable dnsNegativeTtl
specifies the time during which
negative DNS information (information that a host doesn't
exist) will be cached; this defaults to 120s. Increasing this
value reduces both latency and network traffic but may cause a failed
host not to be noticed when it comes back up.
The variable dnsQueryIPv6
specifies whether to query for IPv4
or IPv6 addresses. If dnsQueryIPv6
is false
, only IPv4
addresses are queried. If dnsQueryIPv6
is reluctantly
,
both types of addresses are queried, but IPv4 addresses are preferred.
If dnsQueryIPv6
is happily
(the default), IPv6 addresses
are preferred. Finally, if dnsQueryIPv6
is true
, only
IPv6 addresses are queried.
If the system resolver is used, the value dnsGethostbynameTtl
specifies the time during which a gethostbyname
reply will be
cached (default 5 minutes).
Polipo will usually fetch instances directly from source servers as this configuration minimises latency. In some cases, however, it may be useful to have Polipo fetch instances from a parent proxy.
Polipo can use two protocols to speak to a parent proxy: HTTP and SOCKS. When configured to use both HTTP and SOCKS proxying, Polipo will contact an HTTP proxy over SOCKS — in other words, SOCKS is considered as being at a lower (sub)layer than HTTP.
The variable parentProxy
specifies the hostname and port number
of an HTTP parent proxy; it should have the form ‘host:port’.
If the parent proxy requires authorisation, the username and password
should be specified in the variable parentAuthCredentials
in
the form ‘username:password’. Only Basic authentication
is supported, which is vulnerable to replay attacks.
The main application of the parent proxy support is to cross
firewalls. Given a machine, say trurl
, with unrestricted
access to the web, the following evades a firewall by using an
encrypted compressed ssh
link:
$ ssh -f -C -L 8124:localhost:8123 trurl polipo $ polipo parentProxy=localhost:8124
The variable socksParentProxy
specifies the hostname and port
number of a SOCKS parent proxy; it should have the form
‘host:port’. The variant of the SOCKS protocol being used is
defined by socksProxyType
, which can be either ‘socks4a’
or ‘socks5’; the latter value specifies “SOCKS5 with
hostnames”, and is the default.
The user name passed to the SOCKS4a proxy is defined by the variable
socksUserName
. This value is currently ignored with a
SOCKS5 proxy.
The main application of the SOCKS support is to use Tor to evade overly restrictive or misconfigured firewalls. Assuming you have a Tor client running on the local host listening on the default port (9050), the following uses Tor for all outgoing HTTP traffic:
$ polipo socksParentProxy=localhost:9050
The main assumption behind the design of the HTTP protocol is that requests are idempotent: since a request can be repeated by a client, a server is allowed to drop a connection at any time. This fact, more than anything else, explains the amazing scalability of the protocol.
This assumption breaks down in the case of POST requests. Indeed, a POST request usually causes some action to be performed (a page to be printed, a significant amount of money to be transferred from your bank account, or, in Florida, a vote to be registered), and such a request should not be repeated.
The only solution to this problem is to reserve HTTP to idempotent activities, and use reliable protocols for action-effecting ones. Notwithstanding that, HTTP/1.1 makes a weak attempt at making POST requests slightly more reliable and efficient than they are in HTTP/1.0.
When speaking to an HTTP/1.1 server, an HTTP client is allowed to request that the server check a priori whether it intends to honour a POST request. This is done by sending an expectation, a specific header with the request, ‘Expect: 100-continue’, and waiting for either an error message or a ‘100 Continue’ reply from the server. If the latter arrives, the client is welcome to send the rest of the POST request11.
Polipo's behaviour w.r.t. client expectations is controlled by the
variable expectContinue
. If this variable is false, Polipo
will never send an expectation to the server; if a client sends an
expectation, Polipo will fail the expectation straight away, causing
the client (if correctly implemented) to retry with no expectation.
If expectContinue
is maybe
(the default), Polipo will
behave in a standards-compliant manner: it will forward expectations
to the server when allowed to do so, and fail client expectations
otherwise. Finally, if expectContinue
is true
, Polipo
will always send expectations when it is reasonable to do so; this
violates the relevant standards and will break some websites, but
might decrease network traffic under some circumstances.
Polipo is an HTTP proxy; it proxies HTTP traffic, and clients using other protocols should either establish a direct connection to the server or use an ad hoc proxy.
In many circumstances, however, it is not possible to establish a direct connection to the server, for example due to mis-configured firewalls or when trying to access the IPv4 Internet from an IPv6-only host. In such situations, it is possible to have Polipo behave as a tunnelling proxy — a proxy that merely forwards traffic between the client and the server without understanding it. Polipo enters tunnel mode when the client requests it by using the HTTP ‘CONNECT’ method.
Most web browsers will use this technique for HTTP over SSL if configured to use Polipo as their `https proxy'. More generally, the author has successfully used it to cross mis-configured firewalls using OpenSSH, rsync, Jabber, IRC, etc.
The variable tunnelAllowedPorts
specifies the set of ports that
Polipo will accept to tunnel traffic to. It defaults to allowing ssh,
HTTP, https, rsync, IMAP, imaps, POP, pops, Jabber, CVS and Git traffic.
If resources on a server change, it is possible for a cached instance to become out-of date. Ideally, a cache would be perfectly transparent, meaning that it never serves an out-of-date instance; in a universe with a finite speed of signal propagation, however, this ideal is impossible to achieve.
If a caching proxy decides that a cached instance is new enough to likely still be valid, it will directly serve the instance to the client; we then say that the cache decided that the instance is fresh. When an instance is stale (not fresh), the cache will check with the upstream server whether the resource has changed; we say that the cached instance is being revalidated.
In HTTP/1.1, responsibility for revalidation is shared between the client, the server and the proxy itself. The client can override revalidation policy by using the ‘Cache-Control’ header12; for example, some user-agents will request end-to-end revalidation in this way when the user shift-clicks on reload. The server may choose to specify revalidation policy by using the ‘Expires’ and ‘Cache-Control’ headers. As to the proxy, it needs to choose a revalidation policy for instances with neither server- nor client-side cache control information. Of course, nothing (except the HTTP/1.1 spec, but that is easily ignored) prevents a proxy from overriding the client's and server's cache control directives.
Polipo's revalidation behaviour is controlled by a number of variables. In the following, an resource's age is the time since it was last validated, either because it was fetched from the server or because it was revalidated.
The policy defining when cached instances become stale in the absence
of server-provided information is controlled by the variables
maxAge
, maxAgeFraction
, maxExpiresAge
and
maxNoModifiedAge
. If an instance has an ‘Expires’ header,
it becomes stale at the date given by that header, or when its age
becomes larger than maxExpiresAge
, whichever happens first. If
an instance has no ‘Expires’ header but has a ‘LastModified’
header, it becomes stale when its age reaches either
maxAgeFraction
of the time since it was last modified or else
the absolute value maxAge
, whichever happens first. Finally,
if an instance has neither ‘Expires’ nor ‘Last-Modified’, it
will become stale when its age reaches maxNoModifiedAge
.
If cacheIsShared
is false (it is true by default), Polipo will
ignore the server-side ‘Cache-Control’ directives ‘private’,
‘s-maxage’ and ‘proxy-must-revalidate’. This is highly
desirable behaviour when the proxy is used by just one user, but might
break some sites if the proxy is shared.
When connectivity is very poor, the variable relaxTransparency
can be used to cause Polipo to serve stale instances under some
circumstances. If relaxTransparency
is false
(the
default), all stale instances are validated (see Cache transparency), and failures to connect are reported to the client.
This is the default mode of operation of most other proxies, and the
least likely to surprise the user.
If relaxTransparency
is maybe
, all stale instances are
still validated, but a failure to connect is only reported as an error
if no data is available in the cache. If a connection fails and stale
data is available, it is served to the client with a suitable HTTP/1.1
‘Warning’ header. Current user-agents do not provide visible
indication of such warnings, however, and this setting will typically
cause the browser to display stale data with no indication that
anything went wrong. It is useful when you are consulting a live web
site but don't want to be bothered with failed revalidations.
If relaxTransparency
is true
, missing data is fetched
from remote servers, but stale data are unconditionally served with no
validation. Client-side ‘Cache-Control’ directives are still
honoured, which means that you can force an end-to-end revalidation
from the browser's interface (typically by shift-clicking on
“reload”). This setting is only useful if you have very bad network
connectivity or are consulting a very slow web site or one that
provides incorrect cache control information13 and are willing to manually revalidate pages that you suspect
are stale.
If mindlesslyCacheVary
is true, the presence of a ‘Vary’
header (which indicates that content-negotiation occurred,
see Censor Accept-Language) is ignored, and cached negotiated
instances are mindlessly returned to the client. If it is false (the
default), negotiated instances are revalidated on every client
request.
Unfortunately, a number of servers (most notably some versions of
Apache's mod_deflate
module) send objects with a ‘ETag’
header that will confuse Polipo in the presence of a ‘Vary’
header. Polipo will make a reasonable check for consistency if
‘dontTrustVaryETag’ is set to ‘maybe’ (the default); it will
systematically ignore ‘ETag’ headers on objects with ‘Vary’
headers if it is set to ‘true’.
A number of websites incorrectly mark variable resources as cachable;
such issues can be worked around in polipo by manually marking given
categories of objects as uncachable. If dontCacheCookies
is
true, all pages carrying HTTP cookies will be treated as uncachable.
If dontCacheRedirects
is true, all redirects (301 and 302) will
be treated as uncachable. Finally, if everything else fails, a list
of uncachable URLs can be given in the file specified by
uncachableFile
, which has the same format as the
forbiddenFile
(see Internal forbidden list). If not
specified, its location defaults to ‘~/.polipo-uncachable’ or
‘/etc/polipo/uncachable’, whichever exists.
The in-memory cache consists of a list of HTTP and DNS objects maintained in least-recently used order. An index to the in-memory cache is maintained as a (closed) hash table.
When the in-memory cache grows beyond a certain size (controlled by a number of variables, see Memory usage), or when a hash table collision occurs, resources are written out to disk.
The on-disk cache consists in a filesystem subtree rooted at
a location defined by the variable diskCacheRoot
, by default
"/var/cache/polipo/"
. This directory should normally be
writeable, readable and seekable by the user running Polipo. While it
is best to use a local filesystem for the on-disk cache, a NFSv3- or
AFS-mounted filesystem should be safe in most implementations. Do not
use NFSv2, as it will cause cache corruption 14.
If diskCacheRoot
is an empty string, no disk cache is used.
The value maxDiskEntries
(32 by default) is the absolute
maximum of file descriptors held open for on-disk objects. When this
limit is reached, Polipo will close descriptors on
a least-recently-used basis. This value should be set to be slightly
larger than the number of resources that you expect to be live at
a single time; defining the right notion of liveness is left as an
exercise for the interested reader.
The value diskCacheWriteoutOnClose
(32kB by default) is
the amount of data that Polipo will write out when closing a disk
file. Writing out data when closing a file can avoid subsequently
reopening it, but causes unnecessary work if the instance is later
superseded.
The integers diskCacheDirectoryPermissions
and
diskCacheFilePermissions
are the Unix filesystem permissions
with which files and directories are created in the on-disk cache;
they default to ‘0700’ and ‘0600’ respectively.
The variable maxDiskCacheEntrySize
specifies the maximum size,
in bytes, of an instance that is stored in the on-disk cache. If set
to -1 (the default), all objects are stored in the on-disk cache,
When Polipo runs out of memory (see Limiting memory usage), it will start discarding instances from its memory cache. If a disk cache has been configured, it will write out any instance that it discards. Any memory allocation that prompted the purge must then wait for the write to complete.
In order to avoid the latency hit that this causes, Polipo will
preemptively write out instances to the disk cache whenever it is
idle. The integer idleTime
specifies the time during which
Polipo will remain idle before it starts writing out random objects to
the on-disk cache; this value defaults to 20s. You may want to
decrease this value for a busy cache with little memory, or increase
it if your cache is often idle and has a lot of memory.
The value maxObjectsWhenIdle
(default 32) specifies the maximum
number of instances that an idle Polipo will write out without
checking whether there's any new work to do. The value
maxWriteoutWhenIdle
specifies the maximum amount of data
(default 64kB) that Polipo will write out without checking for
new activity. Increasing these values will make asynchronous
write-out slightly faster, at the cost of possibly increasing Polipo's
latency in some rare circumstances.
Polipo never removes a file in its on-disk cache, except when it finds that the instance that it represents has been superseded by a newer version. In order to keep the on-disk cache from growing without bound, it is necessary to purge it once in a while. Purging the cache typically consists in removing some files, truncating large files (see Partial instances) or moving them to off-line storage.
Polipo itself can be used to purge its on-disk cache; this is done by invoking Polipo with the -x flag. This can safely be done when Polipo is running (see Modifying the on-disk cache).
For a purge to be effective, it is necessary to cause Polipo to write-out its in-memory cache to disk (see Stopping). Additionally, Polipo will not necessarily notice the changed files until it attempts to access them; thus, you will want it to discard its in-memory cache after performing the purge.  The variable diskCacheUnlinkTime
specifies the time during which an on-disk entry should remain unused
before it is eligible for removal; it defaults to 32 days.
The variable diskCacheTruncateTime
specifies the time for which
an on-disk entry should remain unused before it is eligible for
truncation; it defaults to 4 days and a half. The variable
diskCacheTruncateSize
specifies the size at which files are
truncated after they have not been accessed for
diskCacheTruncateTime
; it defaults to 1MB.
Usually, Polipo uses a file's modification time in order to determine
whether it is old enough to be expirable. This heuristic can be
disabled by setting the variable preciseExpiry
to true.
The on-disk cache consists of a collection of files, one per instance. The format of an on-disk resource is similar to that of an HTTP message: it starts with an HTTP status line, followed by HTTP headers, followed by a blank line (‘\r\n\r\n’). The blank line is optionally followed by a number of binary zeroes. The body of the instance follows.
The headers of an on-disk file have a few minor differences with HTTP messages. Obviously, there is never a ‘Transfer-Encoding’ line. A few additional headers are used by Polipo for its internal bookkeeping:
It is safe to modify the on-disk cache while Polipo is running as long as no file is ever modified in place. More precisely, the only safe operations are to unlink (remove, delete) files in the disk cache, or to atomically add new files to the cache (by performing an exclusive open, or by using one of the ‘link’ or ‘rename’ system calls). It is not safe to truncate a file in place.
Polipo uses two distinct pools of memory, the chunk pool and the malloc pool.
Most of the memory used by Polipo is stored in chunks, fixed-size
blocks of memory; the size of a chunk is defined by the compile-time
constant CHUNK_SIZE
, and defaults to 4096 bytes on 32-bit
platforms, 8192 on 64-bit ones. Chunks are used for storing object
data (bodies of instances) and for temporary I/O buffers. Increasing
the chunk size increases performance somewhat, but at the cost of
larger granularity of allocation and hence larger memory usage.
By default, Polipo uses a hand-crafted memory allocator based on
mmap
(2) (VirtualAlloc
under Windows) for allocating
chunks; while this is very slightly faster than the stock memory
allocator, its main benefit is that it limits memory fragmentation.
It is possible to disable the chunk allocator, and use
malloc
(3) for all memory allocation, by defining
MALLOC_CHUNKS
at compile time; this is probably only useful for
debugging.
There is one assumption made about CHUNK_SIZE
:
CHUNK_SIZE
multiplied by the number of bits in an
unsigned int
(actually in a ChunkBitmap
— see
chunk.c) must be a multiple of the page size, which is 4096 on
most systems (8192 on Alpha, 65536 on Windows — go figure).
As all network I/O will be performed in units of one to two chunks,
CHUNK_SIZE
should be at least equal to your network interface's
MTU (typically 1500 bytes). Additionally, as much I/O will be done at
CHUNK_SIZE
-aligned addresses, CHUNK_SIZE
should ideally
be a multiple of the page size.
In summary, 2048, 4096, 8192 and 16384 are good choices for
CHUNK_SIZE
.
Polipo uses the standard malloc
(3) memory allocator for
allocating small data structures (up to 100 bytes), small strings and
atoms (unique strings).
Polipo is designed to work well when given little memory, but will happily scale to larger configurations. For that reason, you need to inform it of the amount of memory it can use.
You can limit Polipo's usage of chunk memory by setting
chunkHighMark
and chunkLowMark
.
The value chunkHighMark
is the absolute maximum number of bytes
of allocated chunk memory. When this value is reached, Polipo will try
to purge objects from its in-memory cache; if that fails to free memory,
Polipo will start dropping connections. This value defaults to
24MB or one quarter of the machine's physical memory, whichever is
less.
When chunk usage falls back below chunkLowMark
, Polipo will
stop discarding in-memory objects. The value
chunkCriticalMark
, which should be somewhere between
chunkLowMark
and chunkHighMark
, specifies the value
above which Polipo will make heroic efforts to free memory, including
punching holes in the middle of instances, but without dropping
connections.
Unless set explicitly, both chunkLowMark
and
chunkCriticalMark
are computed automatically from
chunkHighMark
.
Besides limiting chunk usage, it is possible to limit Polipo's memory
usage by bounding the number of objects it keeps in memory at any given
time. This is done with objectHighMark
and
publicObjectLowMark
.
The value objectHighMark
is the absolute maximum of objects
held in memory (including resources and server addresses). When the
number of in-memory objects that haven't been superseded yet falls
below publicObjectLowMark
, Polipo will stop writing out objects
to disk (superseded objects are discarded as soon as possible).
On 32-bit architectures, every object costs 108 bytes of memory, plus storage for every globally unique header that is not handled specially (hopefully negligible), plus an overhead of one word (4 bytes) for every chunk of data in the object.
You may also want to change objectHashTableSize
. This is the
size of the hash table used for holding objects; it should be a power
of two and defaults to eight times objectHighMark
. Increasing
this value will reduce the number of objects being written out to disk
due to hash table collisions. Every hash table entry costs one word.
Many operating systems permit limiting a process' memory usage by
setting a usage limit; on most Unix-like systems, this is done
with the -v option to the ulimit command.
Typically, the effect is to cause calls to the malloc
and
mmap
library functions to fail.
Polipo will usually react gracefully to failures to allocate memory15. Nonetheless, you should avoid using OS limits to limit Polipo's memory usage: when it hits an OS limit, Polipo cannot allocate the memory needed to schedule recovery from the out-of-memory condition, and has no choice other than to drop a connection.
Unfortunately, some operating system kernels (notably certain Linux releases) fail to fail an allocation if no usage limit is given; instead, they either crash when memory is exhausted, or else start killing random processes with no advance warning16. On such systems, imposing an (unrealistically large) usage limit on Polipo is the safe thing to do.
You are allowed to do anything you wish with Polipo as long as you don't deny my right to be recognised as its author and you don't blame me if anything goes wrong.
More formally, Polipo is distributed under the following terms:
Copyright © 2003–2006 by Juliusz ChroboczekThe last sentence is what happens when you allow lawyers to have it their way with a language.Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  NNTP does support pipelining. SMTP doesn't, while ESMTP makes it an option. FTP does support pipelining on the control connection.
[2] Other client-side implementations of HTTP that make use of pipelining include Opera, recent versions of Mozilla, APT (the package downloader used by Debian GNU/Linux) and LFTP.
[3] HTML forms should use the ‘GET’ method when the form has no side-effect as this makes the results cacheable.
[4] Recent versions of Squid support instances larger than available memory by using a hack that the authors call a “sliding window algorithm”.
[5] It is not quite clear to me whether HTTP digest authentication is worth implementing. On the one hand, if implemented correctly, it appears to provide secure authentication; on the other hand, and unlike ssh or SSL, it doesn't make any attempt at ensuring privacy, and its optional integrity guarantees are impossible to implement without significantly impairing latency.
[6] HTTP contains many mistakes and even one spelling error.
[7] More precisely, unless CGI scripts cooperate.
[8] Or sequences of eight 16-bit integers if you are running IPv6.
[9] The Unix interface to the resolver
is provided by the gethostbyname
(3) library call
(getaddrinfo
(3) on recent systems), which was designed at
a time when a host lookup consisted in searching for one of five hosts
in a ‘HOSTS.TXT’ file. The gethostbyname
call is
blocking, meaning that all activity must cease while a host
lookup is in progress. When the call eventually returns, it doesn't
provide a time to live (TTL) value to indicate how long the
address may be cached. For these reasons, gethostbyname
is
hardly useful for programs that need to contact more than a few hosts.
(Recent systems replace gethostbyname
(3) by
getaddrinfo
(3), which is reentrant. While this removes one
important problem that multi-threaded programs encounter, it doesn't
solve any of the other issues with gethostbyname
.)
[10] While Polipo does its own caching of DNS
data, I recommend that you run a local caching name server. I am very
happy with pdnsd
,
notwithstanding its somewhat bizarre handling of TCP connections.
[11] This, of course, is only part of the story. Additionally, the server is not required to reply with ‘100 Continue’, hence the client must implement a timeout. Furthermore, according to the obsolete RFC2068, the server is allowed to spontaneously send ‘100 Continue’, so the client must be prepared to ignore such a reply at any time.
[12] Or the obsolete ‘Pragma’ header.
[13] This is for
example the case of www.microsoft.com
, and also of websites
generated by a popular Free content management system written in
Python.
[14] Polipo assumes that ‘open(O_CREAT | O_EXCL)’ works reliably.
[15] There are exactly three places in the code where Polipo will give up and exit if out of memory; all three are extremely unlikely to happen in practice.
[16] How I wish for a ‘SIGXMEM’ signal.


In the light of the new EU legislation Article 13 I've decided to create this service to illustrate how our everyday memes will look like.
If you don't want to read all of it, this is sums up the jist of it.
Put somewhat extremely; If you take a screenshot of a funny scene in the new Marvel movie, and you add some out of context sentences and upload it to reddit, you are breaching copyright law, but reddit is not to blame, they just share a service.
With the new law from the EU, reddit is just as much to blame, and need to protect themselves from lawsuits by filtering and censoring content, creating the memeworld as we know it to an end.
This service is, again, put somewhat extremely, is demonstrating what memes will have to look like if they are to survive copyright identification software.


Page:
Blog Page
Data:
title: Blog Page
one.title: first
two.title: second
defaults.title: Site Title


6.4 psb_cdcpy — Copies a communication descriptor
call psb_cdcpy(desc_in, desc_out, info)
-
Type:
- Asynchronous.
-
On Entry
-
-
desc_in
- the communication descriptor.
Scope:local.
Type:required.
Intent: in.
Specified as: a structured data of type psb_desc_type.
-
On Return
-
-
desc_out
- the communication descriptor copy.
Scope:local.
Type:required.
Intent: out.
Specified as: a structured data of type psb_desc_type.
-
info
- Error code.
Scope: local
Type: required
Intent: out.
An integer value; 0 means no error has been detected.


◆ Activate()
| void Checker.Activate |
( |
| ) |
|
<Kings aren't called at game start, so position must be set when they appear
◆ checker_plates()
| void Checker.checker_plates |
( |
| ) |
|
◆ create_b_king()
| void Checker.create_b_king |
( |
| ) |
|
◆ create_r_king()
| void Checker.create_r_king |
( |
| ) |
|
◆ get_board_x()
| int Checker.get_board_x |
( |
| ) |
|
◆ get_board_y()
| int Checker.get_board_y |
( |
| ) |
|
◆ place_plates()
| void Checker.place_plates |
( |
int |
x, |
|
|
int |
y |
|
) |
| |
- Parameters
-
| y | When called, places move plates in correct position |
◆ remove_plates()
| void Checker.remove_plates |
( |
| ) |
|
◆ set_board_x()
| void Checker.set_board_x |
( |
int |
x | ) |
|
◆ set_board_y()
| void Checker.set_board_y |
( |
int |
y | ) |
|
◆ set_coords()
| void Checker.set_coords |
( |
| ) |
|
◆ spawn_capture_plates()
| void Checker.spawn_capture_plates |
( |
int |
x, |
|
|
int |
y |
|
) |
| |
<Check if the piece being moved is red, so will y axis will inrease
◆ spawn_plates()
| void Checker.spawn_plates |
( |
int |
arrayX, |
|
|
int |
arrayY, |
|
|
bool |
capture = false |
|
) |
| |
< Displays plate on screen
<Changes moveplate sprite to red on capture
Keeps track of new position.
- Parameters
-
| capture | Spawns and places move plates visually on the board |
◆ black_checker
| Sprite Checker.black_checker |
◆ black_checker_captured
| Sprite Checker.black_checker_captured |
◆ black_king
| Sprite Checker.black_king |
◆ black_king_captured
| Sprite Checker.black_king_captured |
◆ capture
| bool Checker.capture = false |
◆ controller
| GameObject Checker.controller |
◆ moveplate
| GameObject Checker.moveplate |
◆ red_checker
| Sprite Checker.red_checker |
◆ red_checker_captured
| Sprite Checker.red_checker_captured |
◆ red_king
◆ red_king_captured
| Sprite Checker.red_king_captured |
◆ jumped
◆ player
variable for different players.
The documentation for this class was generated from the following file:


Will showcase 1-2 pictures per topic listed beflore
Education
Associates Degree ITT Technical Institute: Network Systems Administrator
Hobbies
Sneaker Enthusiast
Funko Pop! Vinyl Collector
Travel
list of locations/ personal pictures taken
future travel goals
Accomplishments
Spartan Race Trifecta.
5k, 10k, half marathon runner


5-27 email
To George Sanchez, chair of the CSI chapter of the PSC,
We, the undersigned members of the CSI chapter of the PSC call for, under Article IX, section 7 of the PSC constitution, for a special meeting of our chapter. The purpose of the meeting is to debate and vote on the resolution attached below. It is crucial that we develop an effective response to the attacks that the CUNY administration and the Governor of New York are carrying out against our members, other CUNY workers, our students and the mission of our hallowed institution. An injury to one is an injury to all. This meeting should be scheduled for this week. Jay Arena, Chris Santiago, Ganesh Trichur, Jean Halley, Maryann Feola, Elizabeth Kane, Ozelm Goner, Alexander Zevin, Ismael Garcia-Colon, Ananya Mukherjea, Jeff Bussolini, Ilgin Erdem, Saadia Toor
No Layoffs, No Non-Reappointments, No Pay Cuts—We Unite with our Students and All Workers to Demand Free Public services, Jobs, and Equal Rights for All: Proposed Resolution for the CSI Chapter of the Professional Staff Congress
TO: CSI President William Fritz, CUNY Chancellor Félix V. Matos Rodríguez, and Governor Andrew Cuomo
WHEREAS the COVID-19 crisis has caused unprecedented physical, emotional, and economic hardship for the students, faculty, and staff of the university, many of whose families have been thrown into chaos due to layoffs, illness, or both, and
WHEREAS adjunct faculty, who teach a majority of classes at CUNY, have faced decades of unstable work, low wages and hyper-exploitation that have left many financially unprepared for this crisis, and
WHEREAS the wellbeing of the faculty and staff are inextricably linked to the wellbeing of the students who attend the university, and
WHEREAS, the federal government has since March, 2020 given away trillions of dollars in public money to bankrupt banks and corporations, while draconian cuts are imposed on education and other public services, and
WHEREAS, America's billionaires, the largest recipients of this public money, saw their wealth increase by $434 billion during the course of the global pandemic, and
WHEREAS, New York State has 122 billionaires with a total wealth of over $525 billion; the wealth of those in New York with over $2 Million in net worth is over $1 Trillion.
THEREFORE BE IT RESOLVED by the members of the College of Staten Island Chapter of the PSC that we join other workers in demanding that the State of New York TAKE BACK New York’s share of the trillions given to the rich by immediately imposing a graduated tax averaging 5% per annum on the wealth of all those with more than $2 million in net worth, and
RESOLVED that the members of the College of Staten Island Chapter of the PSC join with other workers to demand that these new taxes be used to finance a massive direct-government employment public works and services to guarantee free, quality education through university, health care, housing, mass transportation and clean energy—FOR ALL who live here, including all immigrants and the formerly incarcerated and,
RESOLVED, that as immediate measures to prepare for such an expansion of public education, we demand that the college and university place an immediate and indefinite moratorium on all layoffs, furloughs, pay-cuts, and non-reappointments, and
RESOLVED that we demand Equal Pay, Rights and Working Conditions for Equal Work—full time faculty, adjuncts, graduate students and staff. This means ending all two-tier and multi-tier schemes. No Pay Below $20 an hour. Adequate staffing in all areas and
RESOLVED that we demand compensation for hours spent transitioning to remote labor. We own all materials we produce for online work.
RESOLVED that we demand no unsafe work. All CSI and CUNY workers will stay home with full pay until it’s safe to return. At minimum, this would be at the time new cases are brought down to near zero and there is a national plan of testing and tracing. In person teaching would then be restored.
RESOLVED, that we recognize that, since our basic demands can only be funded by TAKING BACK the money given to the rich, and that this demand can only be won by a mass mobilization of all workers, therefore the only way workers and students at CUNY can win is by making our fight the fight of the entire working class and,
RESOLVED, members of the College of Staten Island Chapter of the PSC will back up these demands by forming democratically-run strike committees at each campus, selected at popular assemblies, to prepare for a strike to win these demands
RESOLVED, members of the College of Staten Island Chapter of the PSC, call on other PSC chapters and the Delegate Assembly, to debate and vote on these demands, and back up these demands by forming democratically-run strike committees at each campus, selected at popular assemblies, to prepare for a strike to win these demands and prepare for a mass strike to win them.
RESOLVED, members of the College of Staten Island Chapter of the PSC, call on other public sector unions across New York State, to debate and vote on these demands, and back up these demands by forming democratically-run strike committees at each campus, selected at popular assemblies, to prepare for a strike to win these demands and prepare for a mass strike to win them.
RESOLVED that the PSC will call for a democratically-run state-wide popular assembly with students and workers to debate and vote on these demands, and prepare for a mass strike to win them.


The Treasury Bond And Utilities ETFs Straddle Pivots As The Junk Bond ETF Holds Key Moving Average
by Richard SuttmeierSummary
- The Treasury bond ETF is above its semiannual pivot at $135.75 and its quarterly value level at $131.83 with its annual pivot at $145.84.
- The utilities sector ETF is below its semiannual pivot at $63.67 with quarterly and annual value levels at $59.84 and $58.98 and monthly risky level at $65.24.
- The high yield bond ETF remains above its “reversion to the mean” at $107.87 with its monthly risky level at $109.45.
The yield on the 30-year Treasury bond rose to 2.444% on Nov. 7, holding its semiannual value level at 2.431%. The quarterly value level is 2.583% with its weekly risky level at 2.084%.
The dividend yield for the utilities stock ETF slipped to 3.14% last week, down from 3.17% on Nov. 8.
Continue to avoid junk bonds as their yield spread versus U.S. Treasury yields should continue to widen longer term.
Here are weekly charts for these ETFs
The iShares 20+ Year Treasury Bond ETF (NYSEARCA:TLT)
The U.S. Treasury 30-year bond ETF trades like a stock and is a basket of U.S. Treasury bonds with maturities of 20+ years to 30 years. As a stock-type investment, it never matures and interest income is converted to periodic dividend payments.
Courtesy of Refinitiv XENITH
The Treasury bond ETF ($137.76 on Nov. 15) is up 13.4% year to date and set its 2019 high of $148.90 on Aug. 28 and is 7.5% below the high. This ETF is in bull market territory, up 23.1% from its 2018 low of $111.90 set on Nov. 2, 2018. TLT continues to have a negative weekly chart with the ETF below its five-week modified moving average at $139.16 and remains well above its 200-week simple moving average or “reversion to the mean” at $126.08. The 12x3x3 weekly slow stochastic reading fell to 32.09 last week, down from 38.36 on Nov. 8.
Investor Strategy: Investors should buy weakness to its quarterly value level at $131.83 and reduce holdings on strength to its annual risky level at $145.84. Its semiannual pivot remains at $135.75.
The Utilities Select Sector SPDR ETF (NYSEARCA:XLU)
Courtesy of Refinitiv XENITH
The utility stock ETF ($62.85 on Nov. 15) is up 18.8% so far in 2019 and is 23.7% above its Dec. 26 low of $50.81. XLU has a negative weekly chart with the ETF below its five-week modified moving average at $63.17 and well above its 200-week simple moving average or “reversion to the mean” at $53.12. The 12x3x3 weekly slow stochastic reading fell to 65.89 last week, down from 76.29 on Nov. 8.
Investor Strategy: Investors should buy weakness to its quarterly and annual value levels at $59.84 and $58.98, respectively, and reduce holdings on strength to semiannual and monthly risky levels at $63.67 and $65.24.
SPDR Bloomberg Barclays High Yield Bond ETF (NYSEARCA:JNK)
Courtesy of Refinitiv XENITH
The junk bond ETF ($108.19 on Nov. 15) is up 7.4% so far in 2019 and is 9.5% above its Dec. 26 low of $98.76. The weekly chart for JNK is negative with the ETF below its five-week modified moving average at $108.34. The ETF is above its 200-week simple moving average or “reversion to the mean” at $107.87. The 12x3x3 weekly slow stochastic reading slipped to 64.40 last week, down from 68.54 on Nov. 8.
Investor Strategy: Buy weakness to its quarterly, annual and semiannual value levels at $103.02, $102.60 and $99.15, respectively. Reduce holdings on strength to its monthly risky level at $109.45.
How to use my value levels and risky levels:
Value levels and risky levels are based upon the last nine monthly, quarterly, semiannual and annual closes. The first set of levels was based upon the closes on Dec. 31. The original annual level remains in play.
The mid-year close established the semiannual level for the second half of the year.
The monthly level changes at the end of each month, the latest on Oct. 31. The quarterly level was changed at the end of September.
My theory is that nine years of volatility between closes are enough to assume that all possible bullish or bearish events for the stock are factored in.
To capture share price volatility, investors should buy on weakness to a value level and reduce holdings on strength to a risky level. A pivot is a value level or risky level that was violated within its time horizon. Pivots act as magnets that have a high probability of being tested again before its time horizon expires.
How to use 12x3x3 Weekly Slow Stochastic Readings:
My choice of using 12x3x3 weekly slow stochastic readings was based upon back-testing many methods of reading share-price momentum with the objective of finding the combination that resulted in the fewest false signals. I did this following the stock market crash of 1987, so I have been happy with the results for more than 30 years.
The stochastic reading covers the last 12 weeks of highs, lows and closes for the stock. There is a raw calculation of the differences between the highest high and lowest low versus the closes. These levels are modified to a fast reading and a slow reading and I found that the slow reading worked the best.
The stochastic reading scales between 00.00 and 100.00, with readings above 80.00 considered overbought and readings below 20.00 considered oversold. Recently, I noted that stocks tend to peak and decline 10% to 20% and more shortly after a reading rises above 90.00, so I call that an “inflating parabolic bubble” as a bubble always pops. I also call a reading below 10.00 as being “too cheap to ignore.”
Disclosure: I/we have no positions in any stocks mentioned, and no plans to initiate any positions within the next 72 hours. I wrote this article myself, and it expresses my own opinions. I am not receiving compensation for it (other than from Seeking Alpha). I have no business relationship with any company whose stock is mentioned in this article.


You can edit this template as you like. Just select the element and start editing. You can edit
the Profile Photo and Profile Name, Twitter Handle Id, Time of Publish, Tweet Body and Image,
Number of Comments, Number of Retweets, and Number of Likes. When done you can even export and
save the template as an image.
352
510
2412
Disclaimer
Following Application is just for Fun, The Creator holds no
responsibility for what the end-user do with this application


To me, this project was a crazy journey. I am no programmer. My coding knowledge is limited to a month-old Codecademy account. So figuring out how to make things work and change what I wanted to change was quite a challenge. Also, I am not a math-head. I did take some stats classes back in my Bachelor, but it was more than 5 years ago. Cleaning data was also interesting because of data.
Anyway, I am proud of what you see here. This is certainly not the most beautiful, or crafty visualization (there are great people in our class). But still: I did it myself, relying on Google, RedBull, and long nights. . And I learnt a lot while doing it.
Here are some thing I learned and others which I could have done better:
- D3.js
This was my first take on D3.js. It was not easy, but no doubt now I know way more than a couple of weeks ago. I feel I can really do some things on my own.
- Time Scale
There is a bunch of features I wish my visualization had. For example, it would be way better if my visualization had a time scale, with which the user could slide to see changes overtime. I was not able to figure this out, so creating different html with different data was the best option I manage. Not even close to the best possibility.
- CSS+HTML
Aside from playing around on FrontPage in Windows95, I had tried designed a website. To make this work, I learnt a considerable amount of CSS and HTML. If this page looks awful is because my configs probably are badly-structured. I am 120% my code is super messy.
- Data Treatment
Dealing with data was complicated. I am not quite sure I did things the right way. I should have invested more time here.
- Exploring the Database
I should have played more with the data before starting the project. Figure out what variables were most interesting, which had more countries, how did they were collected. This would led me to a more interesting hypothesis.
- World Mapping is Hard
One of my ideas was to have a global map, to situate the user better. I tried a lot of different approaches, but could not manage to make this work. This is a weakness in the project.
- Time Managment
I postponed this project more than I should. I should have started it earlier. This would have given me more time to explore databases, look for help with implementations, and make things prettier.


Name: Tom Hunja
Nationality: Kenyan
DOB: 27th November, 1984
In a nut shell, Jack of all trades trying to be a master of one. A product of Kitui but born and raised in Nairobi West. A DREAMER, researcher, musician rapper and last but not least a web developer.
I did this video in 2007...


Michy Batshuayi sends message to Chelsea FC supporters about his future
Michy Batshuayi insists that he remains fully committed to Chelsea FC
by The Sport Review staffMichy Batshuayi has insisted that he plans to stay loyal to Chelsea FC despite his lack of playing time at the west London club.
The 26-year-old Belgian striker is yet to start a single Premier League game this season under Frank Lampard despite making seven appearances from the bench for the Blues.
His only starts for Chelsea FC so far this season have come in the League Cup, where he scored three goals in two games for Lampard’s side.
Batshuayi has made 11 appearances in all competitions so far for Chelsea FC this season but he has found himself behind the likes of Tammy Abraham in the pecking order under Lampard this term.
His lack of playing time may eventually lead to speculation about his long-term future at the west London club.
However, the striker has now insisted that he remains fully committed to Chelsea FC and has no intention of leaving any time soon.
Batshuayi is quoted as saying by Metro: “I have never been a full-fledged starter, but Chelsea is my club, that’s where I feel at home. It’s a club I love deeply.”
The striker will be hoping to feature when the west London club return to Premier League action after the international break with a trip to Manchester City on Saturday night.
The Blues have won their last six games in the Premier League to leave them third in the table.


Fortnite: How to find the Pipeman, Hayman, and the Timber Tent
Dance the night away.
by Anthony J NashWith a brand new season of Fortnite comes brand new challenges, and Chapter 2 has once again changed up the way players will be taking them on. One of the challenges in this week's Trick Shot will have you searching for three large, humanoid structures across the map so you can dance near them.
Past challenges have involved fighting enemies here, so it's likely you'll know where to go, but if you're unsure of where to go, we've got you covered.
Knowing the challenge
First and foremost, this challenge won't be live until Thursday, Nov. 21, at 9:30 a.m. EST. After that time, you'll be able to jump in and tackle it, but just know that it won't be live until the weekly missions go live in Fortnite.
You'll only be able to do this challenge once you've completed one of the Trick Shot missions, which shouldn't be too hard at all. After finding the structures, simply start dancing in front of them, and it'll count as the challenge. Finally, make sure to refer to the map below for their locations if you get stuck.
How to find the Pipeman, Hayman, and the Timber Tent in Fortnite
- Jump into any game mode of Fortnite's Battle Royale. I'd suggest Solo or Team Rumble, as it's the best for challenges like these.
- The Timber Tent is located in between Sweaty Sands and Holly Hedges, near a row of trees.
- The Hayman is Southwest of Frenzy Farms, in an open field, and is very hard to miss.
-
The Pipeman is directly South of Misty Meadows, and is just past the snowy mountains near the end of the map.
Once you finish up, you'll be all done with that challenge, and can either get started on some of the other missions for this week or finish up the match you're in.
If you're looking for more challenges to do, you can always check out the full list of Trick Shot Missions to see what you've missed, still need to complete, or head back to the main menu to prepare for the next challenge.


Home
(current)
Logout
Please check if the information is correct proceed to pay to confirm the appointment.
Care Reciever information
Name:
Jenima Thomas
Date of Birth
1/1/1970
Gender
Female
StateID:
xxxx-xxxx-xxxx-xxxx
Country
India
Email
<EMAIL_ADDRESS>Phone:
+xxx xxxxx xxxxx
Care Payer Information
Name:
Sarah Thomas
Email:
<EMAIL_ADDRESS>Mobile Number:
+001<PHONE_NUMBER>
PAY ID:
alice$xpring.money
Appointment Details
Apppointment Date
08/01/2020
Appointment Time
13:30 ET
I hereby verify the entered details are correct and allow Care From Far to process my payment mode of choice including PAY ID.
PAY to Confirm Appointment


| Top |
| GtkWidget * | gtk_switch_new () |
| void | gtk_switch_set_active () |
| gboolean | gtk_switch_get_active () |
| void | gtk_switch_set_state () |
| gboolean | gtk_switch_get_state () |
GtkSwitch implements AtkImplementorIface, GtkBuildable, GtkActionable and GtkActivatable.
GtkSwitch is a widget that has two states: on or off. The user can control which state should be active by clicking the empty area, or by dragging the handle.
GtkSwitch can also handle situations where the underlying state changes with a delay. See “state-set” for details.
void gtk_switch_set_active (GtkSwitch *sw
,gboolean is_active
);
Changes the state of sw
to the desired one.
Since: 3.0
gboolean
gtk_switch_get_active (GtkSwitch *sw
);
Gets whether the GtkSwitch is in its “on” or “off” state.
Since: 3.0
void gtk_switch_set_state (GtkSwitch *sw
,gboolean state
);
Sets the underlying state of the GtkSwitch.
Normally, this is the same as “active”, unless the switch is set up for delayed state changes. This function is typically called from a “state-set” signal handler.
See “state-set” for details.
Since: 3.14
struct GtkSwitch;
The GtkSwitch contains private data and it should only be accessed using the provided API.
“active”
property“active” gboolean
Whether the GtkSwitch widget is in its on or off state.
Flags: Read / Write
Default value: FALSE
“state”
property“state” gboolean
The backend state that is controlled by the switch. See “state-set” for details.
Flags: Read / Write
Default value: FALSE
Since: 3.14
“slider-height”
style property“slider-height” gint
The minimum height of the GtkSwitch handle, in pixels.
GtkSwitch:slider-height
has been deprecated since version 3.20 and should not be used in newly-written code.
Use the CSS min-height property instead.
Flags: Read
Allowed values: >= 22
Default value: 22
Since: 3.18
“slider-width”
style property“slider-width” gint
The minimum width of the GtkSwitch handle, in pixels.
GtkSwitch:slider-width
has been deprecated since version 3.20 and should not be used in newly-written code.
Use the CSS min-width property instead.
Flags: Read
Allowed values: >= 36
Default value: 36
“activate”
signalvoid user_function (GtkSwitch *widget, gpointer user_data)
The ::activate signal on GtkSwitch is an action signal and emitting it causes the switch to animate. Applications should never connect to this signal, but use the notify::active signal.
widget |
the object which received the signal. |
|
user_data |
user data set when the signal handler was connected. |
Flags: Action
“state-set”
signalgboolean user_function (GtkSwitch *widget, gboolean state, gpointer user_data)
The ::state-set signal on GtkSwitch is emitted to change the underlying state. It is emitted when the user changes the switch position. The default handler keeps the state in sync with the “active” property.
To implement delayed state change, applications can connect to this signal,
initiate the change of the underlying state, and call gtk_switch_set_state()
when the underlying state change is complete. The signal handler should
return TRUE
to prevent the default handler from running.
Visually, the underlying state is represented by the trough color of the switch, while the “active” property is represented by the position of the switch.
widget |
the object on which the signal was emitted |
|
state |
the new state of the switch |
|
user_data |
user data set when the signal handler was connected. |
Flags: Run Last
Since: 3.14


We’ll be back to 100% soon. Some long migration or fixes are being put in place. Hold on! Please checkout status.rubygems.org for more real-time status updates.


Your changes have been saved
Question assigned successfully
Invites sent
Invite not valid or expired
Invite already accepted
You have uploaded file successfully
File has been removed successfully
This application has not been entered into the competition


Deprecated¶
As of release 1.3.0, Envoy will follow a Breaking Change Policy.
The following features have been DEPRECATED and will be removed in the specified release cycle. A logged warning is expected for each deprecated item that is in deprecation window. Deprecated items below are listed in chronological order.
Version 1.12.0 (October 31, 2019)¶
The ORIGINAL_DST_LB load balancing policy is deprecated, use CLUSTER_PROVIDED policy instead when configuring an original destination cluster.
The regex field in StringMatcher has been deprecated in favor of the safe_regex field.
The regex field in RouteMatch has been deprecated in favor of the safe_regex field.
The allow_origin and allow_origin_regex fields in CorsPolicy have been deprecated in favor of the allow_origin_string_match field.
The pattern and method fields in VirtualCluster have been deprecated in favor of the headers field.
The regex_match field in HeaderMatcher has been deprecated in favor of the safe_regex_match field.
The value and regex fields in QueryParameterMatcher has been deprecated in favor of the string_match and present_match fields.
The
--allow-unknown-fields
command-line option, use--allow-unknown-static-fields
instead.The use of HTTP_JSON_V1 Zipkin collector endpoint version or not explicitly specifying it is deprecated, use HTTP_JSON or HTTP_PROTO instead.
The operation_name field in HTTP connection manager has been deprecated in favor of the traffic_direction field in Listener. The latter takes priority if specified.
The tls_context field in Filter chain message and Cluster message have been deprecated in favor of transport_socket with name envoy.transport_sockets.tls. The latter takes priority if specified.
The use_http2 field in HTTP health checker has been deprecated in favor of the codec_client_type field.
The use of gRPC bridge filter for gRPC stats has been deprecated in favor of the dedicated gRPC stats filter
Ext_authz filter stats ok, error, denied, failure_mode_allowed in cluster.<route target cluster>.ext_authz. namespace is deprecated. Use http.<stat_prefix>.ext_authz. namespace to access same counters instead.
Use of google.protobuf.Struct for extension opaque configs is deprecated. Use google.protobuf.Any instead or pack udpa.type.v1.TypedStruct in google.protobuf.Any.
Version 1.11.2 (October 8, 2019)¶
Use of idle_timeout is deprecated. Use common_http_protocol_options instead.
Version 1.11.0 (July 11, 2019)¶
The –max-stats and –max-obj-name-len flags no longer has any effect.
Use of cluster in redis_proxy.proto is deprecated. Set a catch_all_route instead.
Use of catch_all_cluster in redis_proxy.proto is deprecated. Set a catch_all_route instead.
Use of json based schema in router check tool tests. The tests should follow validation schema.
Use of the v1 style route configuration for the TCP proxy filter is now fully replaced with listener filter chain matching. Use this instead.
Use of runtime in Bootstrap. Use layered_runtime instead.
Specifying “deprecated_v1: true” in HTTP and network filter configuration to allow loading JSON configuration is now deprecated and will be removed in a following release. Update any custom filters to use protobuf configuration. A struct can be used for a mostly 1:1 conversion if needed. The envoy.deprecated_features.v1_filter_json_config runtime key can be used to temporarily enable this feature once the deprecation becomes fail by default.
Version 1.10.0 (Apr 5, 2019)¶
Use of use_alpha in Ext-Authz Authorization Service is deprecated. It should be used for a short time, and only when transitioning from alpha to V2 release version.
Use of enabled in CorsPolicy, found in route.proto. Set the filter_enabled field instead.
Use of the type field in the FaultDelay message (found in fault.proto) has been deprecated. It was never used and setting it has no effect. It will be removed in the following release.
Version 1.9.0 (Dec 20, 2018)¶
Order of execution of the network write filter chain has been reversed. Prior to this release cycle it was incorrect, see #4599. In the 1.9.0 release cycle we introduced bugfix_reverse_write_filter_order in lds.proto to temporarily support both old and new behaviors. Note this boolean field is deprecated.
Order of execution of the HTTP encoder filter chain has been reversed. Prior to this release cycle it was incorrect, see #4599. In the 1.9.0 release cycle we introduced bugfix_reverse_encode_order in http_connection_manager.proto to temporarily support both old and new behaviors. Note this boolean field is deprecated.
Use of the v1 REST_LEGACY ApiConfigSource is deprecated.
Use of std::hash in the ring hash load balancer is deprecated.
Use of rate_limit_service configuration in the bootstrap configuration is deprecated.
Use of runtime_key in RequestMirrorPolicy, found in route.proto is deprecated. Set the runtime_fraction field instead.
Use of buffer filter max_request_time is deprecated in favor of the request timeout found in HttpConnectionManager
Version 1.8.0 (Oct 4, 2018)¶
Use of the v1 API (including *.deprecated_v1 fields in the v2 API) is deprecated. See envoy-announce email.
Use of the legacy ratelimit.proto is deprecated, in favor of the proto defined in date-plane-api Prior to 1.8.0, Envoy can use either proto to send client requests to a ratelimit server with the use of the use_data_plane_proto boolean flag in the ratelimit configuration. However, when using the deprecated client a warning is logged.
Use of the –v2-config-only flag.
Use of both use_websocket and websocket_config in route.proto is deprecated. Please use the new upgrade_configs in the HttpConnectionManager instead.
Use of the integer percent field in FaultDelay and in FaultAbort is deprecated in favor of the new FractionalPercent based percentage field.
Setting hosts via hosts field in Cluster is deprecated. Use load_assignment instead.
Use of response_headers_to_* and request_headers_to_add are deprecated at the RouteAction level. Please use the configuration options at the Route level.
Use of runtime in RouteMatch, found in route.proto. Set the runtime_fraction field instead.
Use of the string user field in Authenticated in rbac.proto is deprecated in favor of the new StringMatcher based principal_name field.
Version 1.7.0 (Jun 21, 2018)¶
Admin mutations should be sent as POSTs rather than GETs. HTTP GETs will result in an error status code and will not have their intended effect. Prior to 1.7, GETs can be used for admin mutations, but a warning is logged.
Rate limit service configuration via the cluster_name field is deprecated. Use grpc_service instead.
gRPC service configuration via the cluster_names field in ApiConfigSource is deprecated. Use grpc_services instead. Prior to 1.7, a warning is logged.
Redis health checker configuration via the redis_health_check field in HealthCheck is deprecated. Use custom_health_check with name envoy.health_checkers.redis instead. Prior to 1.7, redis_health_check can be used, but warning is logged.
SAN is replaced by URI in the x-forwarded-client-cert header.
The endpoint field in the http health check filter is deprecated in favor of the headers field where one can specify HeaderMatch objects to match on.
The sni_domains field in the filter chain match was deprecated/renamed to server_names.
Version 1.6.0 (March 20, 2018)¶
DOWNSTREAM_ADDRESS log formatter is deprecated. Use DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT instead.
CLIENT_IP header formatter is deprecated. Use DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT instead.
‘use_original_dst’ field in the v2 LDS API is deprecated. Use listener filters and filter chain matching instead.
value and regex fields in the HeaderMatcher message is deprecated. Use the exact_match or regex_match oneof instead.
Version 1.5.0 (Dec 4, 2017)¶
The outlier detection ejections_total stats counter has been deprecated and not replaced. Monitor the individual ejections_detected_* counters for the detectors of interest, or ejections_enforced_total for the total number of ejections that actually occurred.
The outlier detection ejections_consecutive_5xx stats counter has been deprecated in favour of ejections_detected_consecutive_5xx and ejections_enforced_consecutive_5xx.
The outlier detection ejections_success_rate stats counter has been deprecated in favour of ejections_detected_success_rate and ejections_enforced_success_rate.
Version 1.4.0 (Aug 24, 2017)¶
Config option statsd_local_udp_port has been deprecated and has been replaced with statsd_udp_ip_address.
HttpFilterConfigFactory filter API has been deprecated in favor of NamedHttpFilterConfigFactory.
Config option http_codec_options has been deprecated and has been replaced with http2_settings.
The following log macros have been deprecated: log_trace, log_debug, conn_log, conn_log_info, conn_log_debug, conn_log_trace, stream_log, stream_log_info, stream_log_debug, stream_log_trace. For replacements, please see logger.h.
The connectionId() and ssl() callbacks of StreamFilterCallbacks have been deprecated and replaced with a more general connection() callback, which, when not returning a nullptr, can be used to get the connection id and SSL connection from the returned Connection object pointer.
The protobuf stub gRPC support via Grpc::RpcChannelImpl is now replaced with Grpc::AsyncClientImpl. This no longer uses protoc generated stubs but instead utilizes C++ template generation of the RPC stubs. Grpc::AsyncClientImpl supports streaming, in addition to the previous unary, RPCs.
The direction of network and HTTP filters in the configuration will be ignored from 1.4.0 and later removed from the configuration in the v2 APIs. Filter direction is now implied at the C++ type level. The type() methods on the NamedNetworkFilterConfigFactory and NamedHttpFilterConfigFactory interfaces have been removed to reflect this.


The Game
The Survivors
The Zombies
Home
Open Games
Create a Game
How to play
Credits
Zombie Time!
Will you survive?
Current Games
There aren't any games, create your own!
Players:
/
Zombie Time every
seconds
Create a Game
1 Slot
2 Slot
3 Slot
4 Slot
Difficult Normal (Zombie Time! every 60 seconds)
Difficult Hard (Zombie Time! every 45 seconds)
Difficult Extreme (Zombie Time! every 30 seconds)
Mission1: Run to the car
Mission2: Get the weapons!
How to play
Instructions...
Credits
Team
Pablo Alba (backend developer)
Miguel de la Cruz (frontend developer)
Laura Pareja (ilustrator)
Yamila Moreno (backend developer)
Special thanks
Sigil.biz (use of custom art)
Bootply.com (web template)
zombietime-back on github
zombietime-front on github
×
×
Join game
Players:
/
Zombie Time every
seconds
×
You can't join the game
Sorry, the password was wrong or the game is full


Sales
Add A Store:
Store Name:
Minimum Customers Per Hour:
Maximum Customers Per Hour:
Average Cookies Per Customer:
Estimated Cookie Needs: