summaryrefslogtreecommitdiff
path: root/docs/manual/developer/layeredio.html
blob: acf9c1b802357d094a061598b3388a5c9895827a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Apache 2.0 Layered I/O</title>
</head>

<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
<BODY
 BGCOLOR="#FFFFFF"
 TEXT="#000000"
 LINK="#0000FF"
 VLINK="#000080"
 ALINK="#FF0000"
>

<H1 align="center">Apache Layered I/O</H1>

<P>Layered I/O has been the holy grail of Apache module writers for years.  
With Apache 2.0, module writers can finally take advantage of layered I/O
in their modules.

<P>In all previous versions of Apache, only one handler was allowed to modify
the data stream that was sent to the client.  With Apache 2.0, one module
can modify the data and then specify that other modules can modify the data
if they would like.

<H2>Taking advantage of layered I/O</H2>

<P>In order to make a module use layered I/O, there are some modifications 
needed.  A new return value has been added for modules, RERUN_HANDLERS.
When a handler returns this value, the core searches through the list of 
handlers looking for another module that wants to try the request.

<P>When a module returns RERUN_HANDLERS, it must modify two fields of the
request_rec, the handler and content_type fields.  Most modules will
set the handler field to NULL, and allow the core to choose the which 
module gets run next.  If these two fields are not modified, then the server
will loop forever calling the same module's handler.

<P>Most modules should not write out to the network if they want to take 
advantage of layered I/O.  Two BUFF structures have been added to the
request_rec, one for input and one for output.  The module should read and
write to these BUFFs.  The module will also have to setup the input field for
the next module in the list.  A new function has been added, ap_setup_input,
which all modules should call before they do any reading to get data to modify.
This function checks to determine if the previous module set the input field,
if so, that input is used, if not the file is opened and that data source 
is used.  The output field is used basically the same way.  The module must
set this field before they call ap_r* in order to take advantage of
layered I/O.  If this field is not set, ap_r* will write directly to the
client.  Usually at the end of a handler, the input (for the next module)
will be the read side of a pipe, and the output will be the write side of
the same pipe.

<H3>An Example of Layered I/O.</H3> 

<P>This example is the most basic layered I/O example possible.  It is 
basically CGIs generated by mod_cgi and sent to the network via http_core.

<P>mod_cgi executes the cgi script, and then sets request_rec->input to 
the output pipe of the CGI.  It then NULLs out request_rec->handler, and 
sets request_rec->content_type to whatever the CGI writes out (in this case,
text/html).  Finally, mod_cgi returns RERUN_HANDLERS.

<P>ap_invoke_handlers() then loops back to the top of the handler list 
and searches for a handler that can deal with this content_type.  In this case
the correct module is the default_handler from http_core.

<P>When default handler starts, it calls ap_setup_input, which has found
a valid request_rec->input, so that is used for all inputs.  The output field
in the request_rec is NULL, so when default_handler calls an output primitive
it gets sent out over the network.</P>

<I>Ryan Bloom, 25th March 2000</I>
</body>
</html>