Module: AUTOPROXY

About this module

The AUTOPROXY module implements a Netscape technology: "Automatic proxy configuration through JavaScript".

The general idea is that there exists a special script that the browser loads. Every time the browser tries to load a URL, the script is run and returns information about how to go about fetching the document at that URL: whether to connect directly to the host, or to connect through a proxy. In the latter case, the script also returns information about the proxy to use.

The technology is popular in large companies, which can use it to balance traffic among multiple proxies or to different proxies at different times of the day.

Visibility in Opera

Setting up a proxy script

The proxy script is a JavaScript source file defining a global function FindProxyForURL that takes some specific arguments and returns some specific values; it is described in Netscape's documentation.

In the (Windows) preferences UI, go to the "Network" panel, click the "Proxy servers" button, and at the bottom of the dialog check the box for "Use automatic proxy configuration" and enter a URL to the proxy configuration script in the box below it. Then "OK" your way out.

Power users may edit the "[Proxy]" section of opera6.ini, like this:

  [Proxy]
  Use Automatic Proxy Configuration=1
  Automatic Proxy Configuration URL=file:///C:/mydir/myautoproxy.pac
The ".pac" extension is traditional, though other extensions are known (".jsc", for "JavaScript Configuration").

Interactions inside Opera

If Opera is compiled with SUPPORT_AUTO_PROXY_CONFIGURATION (controlled by the feature FEATURE_AUTO_PROXY_CONFIG) then the proxy-determining code in URL_DataStorage will consult the autoproxy module about a configured proxy for some URLs. Exactly which URLs is determined by clients of this code (ie, the URL module).

Policies

The following policies are currently in effect, implemented partly by the autoproxy module and partly by the URL module:

BTS

Autoproxy bugs are flagged with the string [AUTOPROXY] in the Summary field and usually have the component "Proxy".

Interface overview and API documentation

API documentation generated by Doxygen contains all necessary information.

Implementation description

Overview

Implementation documentation generated by Doxygen contains what you need to know.

Footprint

The module is small and can be disabled completely.

Older versions of autoproxy stores the proxy configuration library as a unicode string (probably about 20KB) in the library itself. Newer versions store this library in compiled form, thus reducing footprint.

Dynamic memory use and OOM handling

(I'm using "UAPCL" as an abbreviation for "URL_AutoProxyConfig_LoadHandler" below.)
OOM policies

Since the autoproxy module runs as a client of the URL module, it generally uses the same OOM outward signalling mechanisms as the URL module.

An OOM result is generally signalled through a call on MemoryManager::RaiseCondition, while at the same time an error code is posted to the URL layer: either returned as a COMM_REQUEST_FAILED error from UAPCL::Load() or posted as an error on that load handler (MSG_COMM_LOADING_FAILED, with error ERR_AUTO_PROXY_CONFIG_FAILED).

Internally in the module OOM is usually handled by propagating OP_STATUS values.

Who handles OOM?

Whoever created the load handler and called UAPCL::Load() on it must be prepared to handle OOM, signalled as described above. The autoproxy module only performs local cleanup, making sure that things remain consistent and leak-free. Generally the responsibility falls on the URL module.

Flow

All entry points to the module are through UAPCL::Load() and UAPCL::HandleCallback(); follow the flow from there, into UAPCL::ExecuteScript(). It's straightforward.

Also see the general implementation description, above.

Heap memory usage

The module itself allocates very little: only a few small objects to hold data temporarily. But it does use the ECMAScript engine, which can allocate quite a lot. Autoproxy creates one global ES_Runtime, as well as one ES_Context per request, to run requests.

The autoproxy module caches an ES_Runtime, and this may prevent some memory from being freed even if all windows are closed. See "Caching and freeing memory" below.

Stack memory usage

The module itself uses no recursive calls and no stack-allocated arrays or large objects. It calls the ECMAScript engine and the URL layer; they may use more. Locally in the module I'd say that less than 50 words of stack memory are live in the worst case on a system with a dense processor stack (like x86).

Static memory usage

The module currently has three global variables (total of three words of memory).

Caching and freeing memory

One ES_Runtime is cached by the module and may hold onto some usually not very large amount of memory (though there are no bounds on how much memory a runtime can reference.)

The caches can be cleaned out by calling the global function ReleaseAutoProxyResources(). It is safe to call this function at any time. If there are no pending autoproxy requests, this will release all dynamic memory that is currently held by the module. In order to actually free memory held by the ECMAScript environment, it may be necessary to run a garbage collection; the autoproxy module does not do that.

Freeing memory on exit

The function ReleaseAutoProxyResources() must be called on exit before the ECMAScript environment is destroyed.

Temp buffers

One of the methods in the autoproxy module is using the buffer returned from MemoryManager::GetTempBuffer(). There is no check on whether this buffer is used outside the module. (Reuse of the buffer internally is not a problem: this is the only place in the code that uses the temp buffer, and the code does not call any interesting functions.) It would be trivial to allocate a temporary string on the heap to serve the same purpose.

Memory tuning

No known opportunities in the module proper.

Tests

There are no tests, since memory use is fairly trivial.

If the deallocation function is not called before Opera exits, one will get an assert in the ECMAScript engine when that is destroyed.

Coverage

Running the selftests for the module (see comments in testsuite/autoproxy.ot for detailed description; it is more than running with -test) should exercise most of the code.

Design choices

One trade-off has been made: an ES_Runtime is cached, to avoid having to recreate it for every URL lookup. This means that RAM use is higher than the theoretical minimum. It is probably the case that it is not practical to avoid at least some kind of caching.

There are no other known tradeoffs.

Improvements

There are no planned improvements. All known improvements would come as a result of the ECMAScript engine improving its memory use.

Performance

The performance of the module is largely dependent on the performance of the ECMAScript engine.

The important things that happen in the autoproxy module are:

References

ECMAScript module
ECMAScript utilities module
Netscape's original documentation (local copy)
A revised version of Netscape's documentation that include some design choices (local copy)
Module repository page (Wiki)
ECMAScript 3rd edition (external)


$Id$