]>
Agents are used to add new protocols to a browser. They are characterized by
one or more protocols (possibly given as a regular
expression matching a URL, such as "wais:*"
or
"new-proto:*"
).
the object file(s) to load (could be a list of object files or the name of a library).
a suffix, that is used to distinguish function names in this agent from functions in all other applets.
Agents are responsible for determining the (MIME) type of a document and also for decoding of compressed or otherwise encoded documents. In some case that may even entail using heuristic rules to guess the type (e.g., in case of the FTP protocol).
Agents are also responsible for authentication, encryption and
decryption for protocols that require it.
Question: This is a difficult area, since it may
involve user interaction, which is normally not a task for an
agent. How can the user interface be decoupled from such an
agent?
All agents must define (and export) the following functions:
Bool initXXX(char ***protocols, int
*nrprotocol)
(Where XXX
is the abovementioned suffix.)
Initializes private variables inside the applet and returns the
list of protocols that the agent handles. When the
function returns FALSE
, the errno variable holds
the reason.
int openXXX(const char *url, int
method, int flags, const char *referer)
Opens a connection and returns a file descriptor that is
valid in subsequent readXXX
, writeXXX
or closeXXX
calls. The file descriptor may also be
used in select(2)
calls.
The GET_METHOD
(=0),
PUT_METHOD
(=1), or POST_METHOD
(=2).
The symbolic constants and types are defined in
w3a.h
.
The O_NONBLOCK
, which directs
the agent to return as quickly as possible, without blocking
forever until the request is sent. The flags also affects
readXXX
and writeXXX
calls.
The NULL
if no such URL is available.
When the call fails, it returns -1
and
errno holds an error
code.
int readXXX(int fd, char *buf, size_t
nbytes)
Returns the number of characters copied to openXXX
.
When the return code is -1, the variable errno holds the reason.
Bool doneXXX(int fd)
doneXXX
is only needed if fd
has
been opened with O_NONBLOCK
. (Calling it in other
cases is allowed, but meaningless.) Because openXXX
may not have succeeded in sending a complete query to the remote
server, the application must repeatedly call
doneXXX
until that function returns
TRUE
. Calling it again after that is allowed, but
meaningless.
When doneXXX
returns FALSE
, the
application should inspect errno
to see if an error
occurred. If errno = EAGAIN
, no error occurred, but
doneXXX
should be called again.
The application may use select(2)
to wait until
fd
is ready for writing before calling
doneXXX
. Note that fd
may become ready
for reading before it is ready for writing. In that case the
application may (but need not) call readXXX
.
Deadlock is prevented by the agent itself, which is required to
buffer any data until the application calls readXXX
.
int peekXXX(int fd)
The Note: peekXXX
function returns the number of bytes
that are (minimally) available for reading with
readXXX
.
peekXXX
should not return
-1 with an error code of EAGAIN
. It should return
0 instead.
int writeXXX(int fd, const char *buf, size_t
nbytes)
Returns the number of characters actually sent, or -1 in case
of error. The browser should repeat the call with any character
that remained unwritten. The openXXX
with a method of
PUT_METHOD
or POST_METHOD
.
In case fd
had been opened with
O_NONBLOCK
, the application should not start
calling writeXXX
until doneXXX
returns
TRUE
.
Bool closeXXX(int fd)
Closes the connection. If the return code is
FALSE
, errno contains the error code.
Bool deleteXXX(const char *url)
Tries to delete the indicated document. If the return code is
FALSE
, errno contains the error code.
Bool infoXXX(int fd, W3ADocumentInfo
*buf)
Returns information about the retrieved document. Returns
TRUE
on success, FALSE
on error. W3ADocumentInfo
is
a struct defined in w3a.h
.
The function will return at least the MIME type of the document. Other information may be available, depending on the protocol and the document.
If the connection has been opened without the
O_NONBLOCK
flag, the function will not return until
it knows the requested information, even if that means reading
additional data from the document. (The data will be buffered,
so that it can still be returned by readXXX
).
On the other hand, if the connection has been opened for
non-blocking I/O with Note: When used in combination with
O_NONBLOCK
, the
infoXXX
function will return immediately, whether
or not the information is available. If not, it returns
FALSE
and sets errno
to
EAGAIN
. The function can be called repeatedly until
it succeeds. It will buffer any data that it must skip in order
to reach the desired information.
select(2)
, use the read mask to see when it is
useful to call infoXXX
again.
The browser uses these functions subject to the obvious
constraints: Question: How about URNs? I guess resolving URNs
to URLs will be an (exported) function of the browser. See
initXXX
must be called exactly once,
prior to the first call to openXXX
. The functions
readXXX
, writeXXX
, peekXXX
,
doneXXX
and infoXXX
can only be called
with an object that is returned by openXXX
. After a
call to closeXXX
no further calls to any of the
others are possible for the same object.
W3AresolveURN()
.