1. Trang chủ
  2. » Công Nghệ Thông Tin

OReilly writing apache modules with perl and c apr 1999 ISBN 156592567x

215 45 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 215
Dung lượng 1,18 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Tables are similar to Perl hashes in that they are lists of key/value pairs.However, unlike a Perl hash, keys are case-insensitive, and a single keymay correspond to a list of several va

Trang 1

Apache provides a general API for creating and maintaining lookup

tables Apache tables are ubiquitous, used for everything from storing thecurrent request's outgoing HTTP headers to maintaining the list of

environment variables passed to subprocesses

Tables are similar to Perl hashes in that they are lists of key/value pairs.However, unlike a Perl hash, keys are case-insensitive, and a single keymay correspond to a list of several values.[2] In addition, Apache tablekeys and values are always strings; arbitrary data types cannot be used

[2] Despite the differences between Perl hashes and Apache tables,the Perl API allows programmers to access tables via tied Perl

hashes See Section 9.2.5

10.5.1 The table and table_entry Data Types

Currently, a table is an Apache array containing array elements of thetable_entry data type (defined in include/alloc.h):

access the table_entry directly, but use API function calls to

manipulate the keys and values for you If you do read directly from thetable_entry, a note in the include file indicates that you should checkthe key for null This is because the table_entry may be made part of

a more sophisticated hash table in the future

The table structure itself is a private data type intended to be accessedvia an opaque table * If you want to peek at its definition, you can find

Trang 5

ap_table_merge(r->headers_out, "Content-language", "fr");ap_table_merge(r->headers_out, "Content-language", "sp");

Trang 8

client However, as a convenience, mod_perl ties the STDIN and

STDOUT filehandles to the Apache class prior to invoking Perl API

modules This allows handlers to read from standard input and write tostandard output exactly as if they were in the CGI environment

Trang 9

its methods from there Here are two examples of fetching subrequestobjects:

would like to invoke the content handler, the run( ) method will do it:

my $status = $subr->run;

When you invoke the subrequest's response handler in this way, itwill do everything a response handler is supposed to, including

sending the HTTP headers and the document body run( ) returns

the content handler's status code as its function result If you are

invoking the subrequest run( ) method from within your own content

handler, you must not send the HTTP header and document bodyyourself, as this would be appended to the bottom of the information

that has already been sent Most handlers that invoke run() will

immediately return its status code, pretending to Apache that theyhandled the request themselves:

Apache::Server object can be obtained by calling the Apache request object's server( ) method At Perl startup time (such as within a startup

Trang 10

is_virtual()

This method returns true if the current request is being applied to avirtual server This is a read-only method

messages logged with Apache::log() will include the IP address of

the browser and add the messages to the notes table under a key

named error-notes See the description of notes() under Section

Trang 11

port()

This method returns the port on which this (virtual) server is listening

If no port is explicitly listed in the server configuration file (that is, theserver is listening on the default port 80), this method will return 0

Trang 13

object's connection( ) method The connection object is not available

outside of handlers for the various request phases because there is noconnection established in those cases By convention, we use the

aborted()

This method returns true if the client has broken the connection

prematurely This can happen if the remote user's computer hascrashed, a network error has occurred, or, more trivially, the userpressed the stop button before the request or response was fullytransmitted However, this value is only set if a soft timeout occurred.if($c->aborted) {

the request object's auth_type( ) method, which we discussed

earlier, because the request object's method returns the value of the

AuthType configuration directive; in other words, the type of

authentication the server would like to use The connection object's

Trang 16

the case of a single request that has been forwarded across multipleproxies It's safest to choose the last IP address in the list since this

Trang 17

tables API function calls allow you to obtain the list of defined keys,iterate through them, get the value of a key, and set key values Sincemany HTTP header fields are potentially multivalued, Apache also

provides functionality for getting, setting, and merging the contents ofmultivalued fields

interface that allows transparent access to its methods via a tied hashreference, as well as API methods that can be called directly

The TIEHASH interface is easy to use Simply call one of the methodslisted earlier in a scalar context to return a tied hash reference For

Trang 18

defined value of the field You can get around this by using the object-or by using the each operator to access each key and value sequentially The following code snippet shows one way to fetch all the Set-cookie

fields in the outgoing HTTP header:

while (my($key, $value) = each %{$r->headers_out}) { push @cookies, $value if lc($key) eq 'set-cookie';}

When you treat an Apache::Table object as a hash reference, you are accessing its internal get() and set() methods (among others) indirectly.

To gain access to the full power of the table API, you can invoke thesemethods directly by using the method call syntax

Trang 19

do()

This method provides a way to iterate through an entire table item byitem Pass it a reference to a code subroutine to be called once for

each table entry The subroutine should accept two arguments

corresponding to the key and value, respectively, and should return atrue value The routine can return a false value to terminate the

Trang 22

An Apache::URI object is returned when you call the request object's parsed_uri() method You may also call the Apache::URI parse()

my $fragment = $uri->fragment;

$uri->fragment('section_1');

hostinfo()

This method gets or sets the remote host information, which usuallyconsists of a hostname and port number in the format

hostname:port Some rare URIs, such as those used for

nonanonymous FTP, attach a username and password to this

information, for use in accessing private resources In this case, theinformation returned is in the format

username:password@hostname:port

This method returns the host information when called without

arguments, or sets the information when called with a single stringargument

my $hostinfo = $uri->hostinfo;

$uri->hostinfo('www.modperl.com:8000');

hostname()

This method returns or sets the hostname component of the URIobject

Trang 24

path_info() gets or sets the additional path information portion of the

URI, using the current request object to determine what part of thepath is real and what part is additional

my $query = $uri->query;

$uri->query('one+two+three');

rpath()

This method returns the "real path;" that is, the path( ) minus the path_info( ).

my $scheme = $uri->scheme;

$uri->scheme('http');

Trang 25

This method returns the string representation of the URI RelativeURIs are resolved into absolute ones

my $string = $uri->unparse;

Beware that the unparse() method does not take the additional path

information into account It returns the URI minus the additionalinformation

corresponding Perl functions and avoid the memory bloat of pulling in yetanother Perl package

URI::Escape::uri_escape( ) function from the LWP package.

Trang 29

the presence of individual features

# require Authen and Authz handlers to be enableduse mod_perl qw(PerlAuthenHandler PerlAuthzHandler);

Trang 30

The hook( ) function can be used at runtime to determine whether the current mod_perl installation provides support for a certain

feature This is the internal function that import() uses to check for

configured features This function is not exported, so you have to

refer to it using its fully qualified name, mod_perl::hook() hook() recognizes the same list of features that import() does.

Trang 34

:server

Trang 35

These are constants related to the version of the Apache serversoftware:

Trang 37

keep memory consumption at a reasonable level

There are two options if you need to access a constant that is not

exportable by default One is simply to use the fully qualified subroutinename, for example:

die FORBIDDEN;

}

Trang 38

The previous chapters have taken you on a wide-ranging tour of the mostpopular and useful areas of the Apache API But we're not done yet! TheApache API allows you to customize URI translation, logging, the

handling of proxy transactions, and the manner in which HTTP headersare parsed There's even a way to incorporate snippets of Perl code

directly into HTML pages that use server-side includes

We've already shown you how to customize the response, authentication,authorization, and access control phases of the Apache request cycle.Now we'll fill in the cracks At the end of the chapter, we show you thePerl server-side include system, and demonstrate a technique for

extending the Apache Perl API by subclassing the Apache request objectitself

Trang 39

The last two chapters of this book, Chapters Chapter 10 and Chapter

11, focus on aspects of the Apache module API that C-language

programmers need to know The majority of the API has already beencovered in previous chapters, where we looked at it from the perspective

of its Perl incarnation We will briefly revisit each of the topics that we'vealready discussed in order to show you how the API appears in C Topicsthat are specific to the C API, such as memory management, are covered

in more detail

Because the C API is so much of a recapitulation of the Perl API,[1] wewon't show you as many complete examples in this chapter as we have

arrays, tables, and resource pools, and techniques for getting and settinginformation about the request The next chapter describes how to defineand manage configuration directives and covers the less essential parts

of the C API, such as string manipulation functions, and esoterica such

as opening pipes to subprocesses

We do our best to follow the Apache coding style guide throughout You'llfind this guide along with other developer resources at the Apache

Project Development site, http://dev.apache.org/

Trang 40

The Apache request object implements a huge number of methods Tohelp you find the method you're looking for, we've broken them down intoeight broad categories:

Client request methods

Methods that have to do with retrieving information about the currentrequest, such as fetching the requested URI, learning the requestdocument's filename, or reading incoming HTTP headers

Server response methods

Methods that are concerned with setting outgoing information, such

as setting outgoing headers and controlling the document languageand compression

Sending data to the client

Methods for sending document content data to the client

Server core functions

Methods that control key aspects of transaction processing but arenot directly related to processing browser data input or output Forexample, the subrequest API is covered in this section

Server configuration methods

Methods for retrieving configuration information about the server

Logging

Methods for logging error messages and warnings to the server errorlog

Access control methods

Trang 41

my $query = $r->args;

my %in = $r->args;

One trap to be wary of: if the same argument name is present severaltimes (as can happen with a selection list in a fill-out form), assignment of

args() to a hash will discard all but the last argument To avoid this, you'll

need to use the more complex argument processing scheme described inChapter 4

Trang 42

This method returns an object blessed into the Apache::Connection

class See Section 9.2.4" later in this chapter for information onwhat you can do with this object once you get it

my $c = $r->connection;

content()

When the client request method is POST, which generally occurswhen the remote client is submitting the contents of a fill-out form,

the $r->content method returns the submitted information but only if the request content type is application/x-www-form-urlencoded.

When called in a scalar context, the entire string is returned Whencalled in a list context, a list of parsed name=value pairs is returned

To handle other types of PUT or POSTed content, you'll need to use

a module such as CGI.pm or Apache::Request or use the read()

method and parse the data yourself

Note that you can only call content() once If you call the method more than once, it will return undef (or an empty list) after the first try filename()

The filename( ) method sets or returns the result of the URI

translation phase During the URI translation phase, your handler willcall this method with the physical path to a file in order to set thefilename During later phases of the transaction, calling this methodwith no arguments returns its current value

Trang 43

finfo()

Immediately following the translation phase, Apache walks along thecomponents of the requested URI trying to determine where the

physical file path ends and the additional path information begins(this is described at greater length at the beginning of Chapter 4) In

Trang 44

for manipulating the contents of the stat structure For example, the

ht_time() routine turns Unix timestamps into HTTP-compatible human readable strings See the Apache::Util manpage and the section Section

Chapter 10, and provides for timeouts and other niceties Althoughthe Perl API supports them, Perl programmers should generally use

the simpler read() method instead.

get_remote_host()

This method can be used to look up the remote client's DNS

hostname or simply return its IP address When a DNS lookup issuccessful, its result is cached and returned on subsequent calls to

get_remote_host( ) to avoid costly multiple lookups This cached value can also be retrieved with the Apache::Connection object's remote_host() method.

This method takes an optional argument The type of lookup

performed by this method is affected by this argument, as well as the

value of the HostNameLookups directive Possible arguments to this

method, whose symbolic names can be imported from the

Trang 45

following:

REMOTE_HOST

If this argument is specified, Apache will try to look up the DNSname of the remote host This lookup will fail if the Apache

representation of the client's IP address otherwise This is thedefault lookup type when no argument is specified

REMOTE_NOLOOKUP

When this argument is specified, get_remote_host() will not perform a new DNS lookup (even if the HostNameLookups

directive says so) If a successful lookup was done earlier in therequest, the cached hostname will be returned Otherwise, themethod returns the dotted decimal representation of the client's

returns the hostname Otherwise, it returns undef The reason

for this baroque procedure is that standard DNS lookups aresusceptible to DNS spoofing in which a remote machine

temporarily assumes the apparent identity of a trusted host.Double-reverse DNS lookups make spoofing much harder and

Trang 47

it also provides object methods for dealing correctly with multivaluedentries See Section 9.2.5" later in this chapter for details

my %headers_in = $r->headers_in;

my $headers_in = $r->headers_in;

Once you have copied the headers to a hash, you can refer to them

by name See Table 9.1 for a list of incoming headers that you mayneed to use For example, you can view the length of the data that

For these reasons it's better to call headers_in() in a scalar context and use the returned tied hash Since Apache::Table sits on top of

the C table API, lookup comparisons are performed in a case-insensitive manner The tied interface also allows you to add orchange the value of a header field, in case you want to modify therequest headers seen by handlers downstream This code fragmentshows the tied hash being used to get and set fields:

Ngày đăng: 19/04/2019, 10:14