|
The Request object gives you access to the users HTTP request header
and body.
It is arguably the most important built-in ASP object to understand, since
it is
through this object that you will be able to react to the decisions made
by the
user. Using the Request object, you can dynamically create web pages and
perform more meaningful server-side actions (such as updating a database)
based
on input from the user.
How HTTP Works
I will cover the Request object in detail in just a moment. First, however,
it is
important for you to understand the basics of the HTTP protocol. With
such an
introduction, use of the Request object is translated from the realm of
the mysterious
to the ordinary. For those of you whose eyes are beginning to glaze over,
dont worry. This will be only a brief overview of the HTTP protocol.
HTTP: A Simple Example
You probably already know that HTTP is a transaction style
protocol. The
browser (the client) sends a request to the server. The server obeys the
request if
it can and sends a response back to the client. The server then completely
forgets
about the transaction. The browser may or may not forget about it.
To illustrate the interaction between web browser and server, lets
examine a fairly
simple example that illustrates this exchange. Figure 6-1 shows Netscape
Navigator
displaying a very simple form, HELLO.HTM, that prompts the user for her
name. When the user clicks the Submit button, a CGI application is invoked
on a
WebSite server that sends back the page displayed in Figure 6-2. (Although
Navigator
and WebSite are used for this example, the exchange between any browser
and any server would be more or less identical. Also, although this example
uses a
CGI application, the HTTP request/response cycle is almost exactly the
same as
that for ASP applications. For more about CGI-to-ASP conversion, see Appendix
A,
Converting CGI/WinCGI Applications into ASP Applications.) Lets
see how this
interchange between browser and server are handled by the protocol:
1. When the user finishes entering the URL for HELLO.HTM, Navigator sends*
the
following stream to the server:
[73:send:(179)]GET /hello.htm HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/3.0 (Win95; I)
Host: pc229.west.ora.com
Accept: image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg, */*
Figure 6-1: HELLO.HTM, a simple HTML form
Figure 6-2: HELLOCGI.HTM, an HTML page created by a CGI application
* send in the following output listing is a sockets
function that sends a stream in a connected
socket. In the output, 73 identifies the socket, while 179 is the value
returned by the function
and represents the total number of bytes sent.
This is a request header. The browser indicates that it wants the server
to get
the document /HELLO.HTM. Get is more than a generic description of what
the server should do; it indicates the HTTP request type. (For details,
see
HTTP Request Types, later in this chapter.) The browser also
indicates that
its using version 1.0 of the Hypertext Transfer Protocol.
Note that the first line in this HTTP header is actually an artifact of
the TCP/IP packet sniffer used in this demonstration and not part of
the actual HTTP request sent. The same is true for all HTTP segments
in this chapter.
2. The server receives* the headers sent by the browser, as shown in the
following output produced by our spy program, and processes the request:
[21:recv: completed (179)]GET /hello.htm HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/3.0 (Win95; I)
Host: pc229.west.ora.com
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
3. The server sends the document HELLO.HTM to the browser:
[21:send:(535)]HTTP/1.0 200 OK
Date: Monday, 30-Sep-98 23:33:00 GMT
Server: WebSite/1.1
Allow-ranges: bytes
Accept-ranges: bytes
Connection: Keep-Alive
Content-type: text/html
Last-modified: Monday, 30-Sep-98 23:30:38 GMT
Content-length: 297
<HTML>
<HEAD><TITLE>Hello, World!</TITLE></HEAD>
<BODY>
<FORM ACTION="/cgi-win/hello.exe" METHOD="POST">
What is your name? <INPUT TYPE="text" NAME="name"
SIZE=60><BR>
<INPUT TYPE="submit" VALUE="Submit the form">
<INPUT TYPE="reset" VALUE="Clear all fields">
</FORM>
</BODY> </HTML>
Here, WebSite sends a total of 535 bytes to the browser. This consists
of a
response header, followed by a blank line, followed by the HTML document
itself. The header fields indicate, among other things, the number of
bytes
(the Content-length header) and the format (the Content-type header) of
the
* The recv function is used to receive data from a socket. In the output,
the initial number, 21,
represents the socket used by the server. Completed (179)
indicates the functions return value,
in this case that it completed normally by receiving 179 bytes. Note that
this corresponds
to the number of bytes sent by the browser.
transmitted data. 200 OK is a status code indicating that
the browsers
request was fulfilled. The server also indicates that, like the browser,
its using
version 1.0 of HTTP.
4. The browser reads the headers and data sent by the server:
[73:recv: posted]
[73:recv: completed (260)]HTTP/1.0 200 OK
Date: Monday, 30-Sep-98 23:33:00 GMT
Server: WebSite/1.1
Allow-ranges: bytes
Accept-ranges: bytes
Connection: Keep-Alive
Content-type: text/html
Last-modified: Monday, 30-Sep-98 23:30:38 GMT
Content-length: 297
<HTML>
<HEAD><TITLE>H
[73:recv: posted]
[73:recv: completed (275)]ello, World!</TITLE></HEAD>
<BODY>
<FORM ACTION="/cgi-win/hello.exe" METHOD="POST">
What is your name? <INPUT TYPE="text" NAME="name"
SIZE=60><BR>
<INPUT TYPE="submit" VALUE="Submit the form">
<INPUT TYPE="reset" VALUE="Clear all fields">
</FORM>
</BODY> </HTML>
Although two recv operations are required to retrieve the header records
along with the document, the total number of bytes read in these two operations
equals the total number of bytes sent by the server.
5. The browser displays the form asking for the users name and,
when the user
fills it out and clicks the Submit button, sends the following to the
server:
[70:send:(232)]POST /cgi-win/hello.exe HTTP/1.0
Referer: http://pc229.west.ora.com/hello.htm
Connection: Keep-Alive
User-Agent: Mozilla/3.0 (Win95; I)
Host: pc229.west.ora.com
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
[70:send:(69)]Content-type: application/x-www-form-urlencoded
Content-length: 14
[70:send:(2)]
[70:send:(16)]name=Jayne+Doe
Because the browser is transmitting form data, the HTTP request type is
POST, as the very first header record indicates. Similarly,
the Content-length
and Content-type records indicate that the browser is transmitting 14
bytes of
x-www-form-urlencoded data in the body of the request. This consists of
the information input by the user in the forms single data field,
the name text
box.
6. The server receives the header records and form data transmitted by
the
browser in the previous step. (Since its basically identical to
the text sent by
the browser, we wont duplicate it here.) The URL (/cgi-win/hello.exe)
causes
the server to launch the CGI application HELLO.EXE and to transmit the
forms data to it. The CGI application may do some back-end processing,
then
builds an HTML document on the fly and returns it to the server.
7. The server returns the HTML document to the browser along with the
necessary
header records, as the following output from WSock32 Spy shows:
[18:send:(422)]HTTP/1.0 200 OK
Date: Monday, 30-Sep-98 23:33:10 GMT
Server: WebSite/1.1
Allow-ranges: bytes
Accept-ranges: bytes
Connection: Keep-Alive
Content-type: text/html
Content-length: 231
<HTML><HEAD>
<TITLE>Welcome to this Web Page!</TITLE></HEAD>
<BODY><H1>Welcome to Our Web Server!</H1><p><p>
Hello, Jayne Doe! We're glad that you took
the time out of your busy day to visit us!
<HR></PRE></BODY></HTML>
Notice that the server indicates to the browser that its sending
231 bytes of an
HTML document.
8. The browser receives the data stream send by the server and uses it
to render
the HTML page.
Hopefully, this gives you a fairly good sense of whats involved
in the interchange
between browser and server. Its important, though, to take a more
in-depth look
at some of the points that weve touched on only briefly, as well
as to cover some
additional features that are not included in this simple example.
HTTP Request Types
The request type is passed by the client to the server to indicate what
the server
should do with the URL thats also supplied by the browser. Although
the HTTP
specification details a number of request types, like PUT and DELETE,
only two are
supported by all servers and in common use: GET and POST. A GET request
asks
the server to get a piece of information, typically a document,
and return it to
the client. If the request includes any additional information, these
are appended
as arguments to the URL. A POST request, on the other hand, provides the
server
with information to be posted to the URL; typically, its
used to send the contents
of an HTML form to the server, or to provide the server with information
thats
needed for back-end processing. The information itself is contained in
the body of
the request.
Most servers cannot handle data received from either the POST or GET methods
internally. Normally, POST requests, as well as GET requests that also
send data to
the server, are handled by accessory programs or DLLs (CGI and ISAPI applica-
tions and ISAPI filters). Both POST and GET requests can return any kind
of data of
any size.
While it may seem when transmitting data to a web server that GET and
POST are
similar, one rule is hard and fast: A GET request must never change anything.
Dont write an ASP script that makes changes to a database, for instance,
in
response to a GET request. The reason for this is discussed in greater
detail in the
following section, Form Submission.
Form Submission
A user enters input into the fields of a form. When the form is submitted,
the data
contained in each field of the form is transferred to the server, which
then passes
it to ASP. This data is sent in the format name=value, where name is the
name
assigned to the field by the NAME= attribute of the <INPUT> tag,
and value is the
value entered in that field. For example, if the user enters Archie
in a field
prompting for his first name, the browser may send along the string first_
name=Archie.
If the form is written to use METHOD=GET, the form data is appended to
the URL as
an argument string. If the form contains many fields or if fields contain
long strings
of text, the complete URL can become very large and unwieldy. In addition,
the
limit of the number of characters submitted in a GETtypically about
2000is
much lower than in a POST.
If the form instead uses METHOD=POST, the name=value pairs are sent as
the body
of the request instead of being appended to the URL. In addition to the
greater
ease of handling of POST requests, most servers offer better performance
when
extracting data from the body of a request than from a URL in the request
header.
Always use the POST method with forms that change something or cause any
irreversible
action (most do). POST is safer and more efficient; GET should never be
used to change anything. In developing your ASP scripts, you can decide
whether
you want to support data passed to your program using the GET method.
GET Versus POST
In the event that youre confused about the difference between these
two
methods, GET can be used to retrieve any document, POST cannot. On the
other hand, both GET and POST can be used to pass data to the object indicated
by the URL. When GET is used for this purpose, the data is included in
the URL as the argument string; in order to extract this data with Win-CGI,
you have to parse the argument string. When POST is used, the data is
passed to the server in the body of the request message. So, in cases
in
which data is sent to the server, GET and POST differ in the method used
to
transmit that data.
HTTP Request and Response
Headers are the most misunderstood part of HTTP, yet understanding their
role
can make understanding the properties and methods of both the ASP Request
and
Response objects much easier.
Take a look at any Internet email message. It consists of two parts, the
header and
the body. The header consists of several lines that describe the body
of the
message and perhaps the way the message was handled as it was routed to
you.
The header and body are separated by a blank line. (For more information
on
header syntax, consult RFC-822.)
An HTTP message (either a request or a response) is structured the same
way. The
first line is special, but the rest of the lines up to the first blank
line are headers
just like in a mail message. The header describes the request and its
content, if
any, or the response and its content.
The request
In an earlier section, HTTP: A Simple Example, we saw a number
of requests
from the browser. Here is another example of a simple HTTP request:
POST /cgi-win/hello.exe HTTP/1.0
Accept: image/gif, image/jpeg, */*
User-Agent: Mozilla/2.0N (Windows; I; 32Bit)
Content-type: application/x-www-form-urlencoded
Content-length: 14
[mandatory blank line]
name=Jayne+Doe
The first line, which is known as the request-line, describes the type
of request (or
method)in this case POST, the URL, and, finally, the version of
the HTTP
protocol that the client uses. The second line describes the types of
documents
that the client can accept. The third line is an extra header
thats not required by
HTTP. It gives the name and version of the client software. Following
this, as
discussed in the section HTTP: A Simple Example, are two lines
describing the
information contained in the body of the request.
Everything up to the mandatory blank line is part of the HTTP request
header. In
addition to the example lines here, there can be other lines in this section.
For
example, if the browser is sending information contained in a cookie,
that information
also will be in the request header.
Below the mandatory blank line is the HTTP request body. In most cases,
this
section of the request is empty (for example, when the browser is requesting
only
a static page and is not sending any information). However, when the POST
method is used, the information sent to the web server is located in this
section of
the request.
The response
Here is an example of a simple HTTP response:
HTTP/1.0 200 OK
Date: Thursday, 02-Nov-95 08:44:52 GMT
Server: WebSite/1.1
Last-Modified: Wednesday, 01-Nov-95 02:04:33 GMT
Content-Type: text/html
Content-length: 8151
[mandatory blank line]
<HTML><HEAD>
<TITLE>...
The first line of the response is also special and is known as the status-line.
It
contains the protocol version the server uses, plus a status code and
a reason
phrase. The server uses the status code and reason phrase to inform the
browser
whether it was able to respond to the browsers request; in this
case, its successfully
filled the browsers request for a document. The second line contains
the date
and time the server handled the request. Third is a header line describing
the
server software and version. The fourth line indicates the date and time
when the
requested document was last modified. The last two lines describe the
type of data
and the number of bytes in the requested document. This is followed by
exactly
one blank line, then the body of the message, which contains the document
data
that the server is sending back for the browser to display.
As with the HTTP request, everything above the mandatory blank line is
considered
part of the HTTP response header. Everything below this line is part of
the
response body.
This chapter covers the ASP Request object, which you can use to access
both the
header and the body of the HTTP request. The next chapter discusses the
ASP
Response object, which you use in manipulating the HTTP response from
the web
server.
The HTTP Request and the ASP Request Object
As mentioned earlier, the ASP Request object allows you to access both
the header
and body of the HTTP request sent to the web server by the clients
browser. The
method of retrieving information from the HTTP request is basically the
same for
an ASP script as it is for a CGI application. The exceptions come not
from the
actual request mechanics but from how each type of application is loaded
into the
web server (CGI versus an ISAPI filter), as described in the first two
chapters of
this book.
Just as with CGI applications, the client browser can send information
to an ASP
script in two different manners. First, it also can send information by
means of an
HTML form using the GET method:
<HTML>
<HEAD><TITLE>Welcome to the Corp.</TITLE></HEAD>
<BODY>
<FORM ACTION=" http://mycorp.com/secure.asp" METHOD="GET">
First name: <INPUT TYPE="text" NAME="first_name"
SIZE=60><BR>
Last name: <INPUT TYPE="text" NAME="last_name"
SIZE=60><BR>
<INPUT TYPE="submit" VALUE="Submit the form">
<INPUT TYPE="reset" VALUE="Clear all fields">
</FORM>
</BODY> </HTML>
When the client submits a GET request, the information about the request
is
appended to the end of the request URL as name/value pairs separated by
ampersands
and preceded by a question mark. Each name corresponds to an element in
the form. For example, suppose the user entered Horatia and Thompson into
the
two fields in the last example and clicked on the Submit button. The submission
of the preceding form is, as far as the server is concerned, identical
to the
following:
http://mycorp.com/secure.asp?first_name=horatia&last_
name=thompson
This is an important point. Following this example, consider the following
line of
code:
http://mycorp.com/secure.asp?first_name=horatia&last_
name=thompson
If the user were to type this into the address line or click on a link
containing the
preceding as a URL, the web server would treat that resulting HTTP request
exactly as if the information had been sent as part of a form using the
GET request.
From within your ASP application, you can access this information through
the
QueryString collection of the Request object. For example:
<%
strFirstName = Request.QueryString("first_name")
%>
will initialize the strFirstName variable to the value sent in the first_name
parameter. The QueryString collection is discussed in detail later in
this chapter.
Just as with CGI applications, you also can send information to an ASP
script using
the POST method. In this case, instead of being part of the HTTP request
header,
the information would be in the body of the request object:
<HTML>
<HEAD><TITLE>Welcome to the Corp.</TITLE></HEAD>
<BODY>
<FORM ACTION="http://mycorp.com/secure.asp" METHOD="POST">
First name: <INPUT TYPE="text" NAME="first_name"
SIZE=60><BR>
First name: <INPUT TYPE="text" NAME="last_name"
SIZE=60><BR>
<INPUT TYPE="submit" VALUE="Submit the form">
<INPUT TYPE="reset" VALUE="Clear all fields">
</FORM>
</BODY> </HTML>
This forms submission would result in an HTTP request similar to
the following:
POST /secure.asp HTTP/1.0
Accept: image/gif, image/jpeg, */*
User-Agent: Mozilla/2.0N (Windows; I; 32Bit)
Content-type: application/x-www-form-urlencoded
Content-length: 35
[mandatory blank line]
first_name=horatio&last_name=aubrey
For your application to manipulate the information sent in that HTTP request,
you
would have to use the Form collection of the Request object:
<%
strFirstName = Request.Form("first_name")
%>
This will initialize the strFirstName variable to the value sent in the
first_name
parameter. The Form collection is discussed in detail later in this chapter.
The ASP Request Object
The properties, collections, methods, and events of the ASP Request object
are as
follows:
Comments/Troubleshooting
In the previous discussion of ASP and the GET and POST methods, we saw
that
information from a GET is retrieved by using the QueryString collection
and that
information from a POST is retrieved by using the Form collection. This
is true, but
there is a simpler way: you do not have to specify a collection. For example,
the
code:
strName = Request("name")
returns the value of the name key regardless of the collection
in which its
located, because IIS searches all collections. When you specify a value
in this
manner, ASP looks through each Request object collection in the following
order:
1. QueryString
2. Form
3. Cookies
4. ClientCertificate
5. ServerVariables
Request Object Summary
Properties
TotalBytes
Collections
ClientCertificate
Cookies
Form
QueryString
ServerVariables
Methods
BinaryRead
Events
None
The variable you are initializing will receive the value in the first
instance of the
name/value pair whose name matches the string requested. For this reason,
it is
important to realize that if you have the same name/value pair in two
or more
collections, you will receive the first one found according to the preceding
sequence, unless you specify a particular collection.
As with the other collections in the ASP object model, all the collections
discussed
in this chapter for the Request object support the Item and Key properties,
the
Count method, and the For..Each construct.
Properties Reference
TotalBytes
Var = Request.TotalBytes
The TotalBytes property is a read-only value that specifies the total
number of
bytes posted to the web server by the client in the HTTP request body.
This property
is important when preparing to read data from the request body using the
BinaryRead method of the Request object.
Parameters
Var
Receives the total number of bytes in the clients HTTP request body
when it
posts data to the web server. Remember that the TotalBytes property is
readonly.
Example
In this example, assume that the user has responded to the following form:
<HTML>
<HEAD><TITLE>File Upload Form</TITLE></HEAD>
<BODY>
<FORM ENCTYPE = "multipart/form-data
ACTION= "http://mycorp.com/secure.asp" METHOD="POST">
Select a file to upload:
<INPUT TYPE="file" NAME="filename"><BR>
<INPUT TYPE="submit" VALUE="Submit the form">
</FORM>
</BODY> </HTML>
You can use the TotalBytes property to determine exactly how many bytes
of
information were sent to the web server in the HTTP request:
<%
' The following code retrieves the total number of
' bytes sent in the user's HTTP request. This variable
' is then used to determine how many bytes to retrieve
' using the Request object's BinaryRead method.
Dim lngTotalByteCount
Dim vntRequestData
lngTotalByteCount = Request.TotalBytes
vntRequestData = Request.BinaryRead(lngTotalByteCount)
%>
Notes
Most often, you will not need to access data in the HTTP request body
at the low
level provided by the Request objects BinaryRead method and so will
not need to
retrieve the value of the TotalBytes property. You will use the Form and
QueryString collections for almost all of your request data access.
In the preceding example, the value of vntRequestData represents
the total bytes sent, not just the byte count of the uploaded file; i.e.,
all header-related HTTP request information also counts toward this
total. To retrieve from the preceding upload only the file contents,
you would have to parse out the header information.
Collections Reference
ClientCertificate
Request.ClientCertificate
The ClientCertificate collection of the Request object provides access
to the certification
fields of the clients digital certificate. Client certificates are
sent to the web
server when a clients browser supports the Secure Sockets Layer
and that browser
is connected to a web server also running the Secure Sockets Layer (i.e.,
the URL
starts with https:// rather than http:// ). For example, if you were using
Internet
Explorer 4.01 and were connected to an Internet Information Server web
site with
SSL running, each request made by your browser would include your client
certificate,
if you have one. The fields of a client certificate are specified in the
International Telecommunications Union (ITU) recommendation X.509.
The ClientCertificate collection, like the other ASP collections, has
the following
properties:
Item
Returns the value of a specific element in the collection. To specify
an item,
you can use an index number or a key.
Key
Represents the name of a specific element in the ClientCertificate collection.
Just as each elements value is represented by the Item property,
each
elements name is represented by its Key property.
If you do not know the name of a specific key, you can obtain it using
its
ordinal reference. For example, assume that you want to learn the key
name
for the third element in the collection and, subsequently, that elements
value.
You could use the following code:
strKeyName = Request.ClientCertificate.Key(3)
strKeyValue = Request.ClientCertificate.Item(strKeyName)
If, on the other hand, you know that the third elements key name
is
ISSUER, you could simply use the following code to retrieve
the value of
that element:
strKeyValue = Request.ClientCertificate.Item("ISSUER")
As with other ASP collections, you can retrieve the value of any field
of the
Cookies collection through the use of the Item property. Note that, because
Item is
the default property of the collection, the syntax can be abbreviated
so that it does
not explicitly show the use of the Item property. For example:
strClientCountry = Request.ClientCertificate("Issuer")
is only an abbreviated form of:
strCertIssuer = Request.ClientCertificate.Item("Issuer")
For more information on the Item, Key, and Count properties of a
collection, see the discussion in the section Contents Collection
in
Chapter 4, Application Object.
The available Key values are predefined and are as follows:
Certificate
A string value that contains the entire binary stream from the certificate
content. The content is retrieved in standard ASN.1 (Abstract Syntax Notation
One) format, the international standard for representing data types and
structures.
Flags
A set of flags that provide additional information about the clients
certificate.
These flags are integer values that can be represented by the constants
ceCertPresent and ceUnrecognizedIssuer if the VBScript include file
cervbs.inc is included in your scripts (see Chapter 10, Preprocessing
Directives,
Server-Side Includes, and GLOBAL.ASA, for more on including files). As
the constant names suggest, ceCertPresent signifies that a client certificate
is present, and ceUnrecognizedIssuer signifies that the clients
digital certificate
was issued by an unknown certificate authority.
Issuer
A string that contains several pieces of information about the issuer
of the
clients digital certificate. If no SubKey parameter (discussed later)
is added,
using the Issuer key returns a comma-delimited list of all the Issuer
subfield
values (e.g., C=US, O=VeriSign, GN=Weissinger, etc.).
SerialNumber
An ASCII representation of the hexadecimal bytes of the clients
certification
serial number. This value is provided by the issuer. Retrieving the Serial-
Number key would provide a number such as 0A-B7-34-23.
Subject
A list of comma-delimited strings that provide information about the owner
of
the digital certificate. If no SubKey is provided, the entire comma-delimited
list of subfields is retrieved, similar to that described for the Issuer
key.
ValidFrom
The date the c ertificate becomes valid. This keys value is provided
as a date
and time. For example, a possible value of the ValidFrom key (in the U.S.)
could be 1/29/98 12:01:00 A.M.
ValidUntil
The date the certificate becomes invalid. This keys value is provided
as a date
and time. For example, a possible value of the ValidUntil key (in the
U.S.)
could be 1/28/99 11:59:59 P.M.
You can add a subkey to some of the Key values to retrieve
an individual
subfield from either the Issuer or Subject key lists. For example, if
you wanted to
obtain the country of origin subkey value from the Issuer key list, you
would
retrieve the value:
Request.ClientCertificate("IssuerC")
If you wanted to retrieve the locality subkey value from the Subject key
list, you
would retrieve its value using the syntax:
Request.ClientCertificate("SubjectL")
You also can retrieve a value from a specific subkey, including those
not listed here, from the Certificate key string value using the subkeys
ASN.1 identifier. An ASN.1 identifier is a list of numbers separated
by a period, similar in appearance to an IP address, but not
limited to 0 through 255. For example: 3.56.7886.34.
The available subkeys are as follows:
C The country of origin for the Subject or Issuer.
CN The common name of the Subject key. Note this subkey is not defined
for the
Issuer key.
GN The given name of the Subject or Issuer.
I The initials of the Subject or Issuer.
L The locality of the Subject or Issuer.
O The organization or company name of the Subject or Issuer.
OU The name of the specific organizational unit within an organization
or
company for a Subject or Issuer.
S The state (or province) of the Subject or Issuer.
T The title of the Subject or Issuer.
Example
<%
' The following code retrieves the country of origin
' for the client's certificate issuer.
strCertIssuerCountry = Request.ClientCertificate("IssuerC")
%>
<!-- #include file="cervbs.inc" -->
<%
' The next example code determines whether the
' issuer is recognized by using the flags key.
If Request.ClientCertificate("Flags") _
and ceUnrecognizedIssuer Then
%>
Your identification is in question because your issuer
is not recognized.
<%
Else
%>
Welcome to our site.
<%
End If
' Finally the following code iterates through the
' ClientCertificate collection and writes the key-key
' value pairs to the response buffer.
For Each key In Request.ClientCertificate
Response.Write "The " & key & " key contains the
value "
Response.Write Request.ClientCertificate(key) & "<BR>"
Next
%>
Notes
Before you can retrieve information from a clients digital certificate,
you must
ensure that the clients web browser uses the SSL3.0/PCT1 protocol
in its requests
to your site. The simplest way to do this is to attempt to retrieve an
element from
the ClientCertificate collection.
You also must ensure that you have set up your IIS web server to request
client
certificates.
If the client sends no digital certificate, any key you attempt to retrieve
from the
ClientCertificate collection will be empty.
The ITU Recommendation X.509 is just thata recommendation. It has
not been
recognized as an official standard. For this reason, various companies
certificates
may function slightly differently or may not contain all the fields you
are
attempting to retrieve. To ensure you are properly identifying your clients,
it is
wise to do some experimentation with the ClientCertificate collection
before
relying on it.
Cookies
Request.Cookies
Before discussing the Cookies collection, well briefly introduce/review
the
concept of HTTP cookies. This will be only a brief overview. For more
information,
visit either the Netscape Preliminary Specification at www.netscape.com/
newsref/std/cookie_spec.html, or visit Cookie Central, a clearinghouse
of all cookierelated
information. I can specifically recommend www.cookiecentral.com/
unofficial_cookie_faq.htm.
The problem with a stateless protocol like HTTP is that it forces both
the server
and client to do a great deal of repetitive work. For example, with a
truly stateless
protocol, the web server would have to ask you who you are every single
time
you navigate to a page on the siteeven if you navigate to this new
page from
another page within the same site. Likewise, your interaction would be
limited to
what you can enter and save on one page of information, because without
some
way of storing the data from one page, a second page has no way of getting
to
that data.
Netscape Communications Corp. foresaw this problem early on and devised
a
method by which small pieces of information could be stored by the web
server
on the web clients machine. This information would, in turn, be
sent to the server
each time the client requested a page from the same area from which she
received
the information. That little bit of information is at the root of Netscapes
Persistent
Client State Mechanism or cookies, as they are known. (Its
interesting to note
that, according to the Netscape preliminary specification, this state
object was
called a cookie for no compelling reason.)
Through the use of cookies, web servers can store information on the client
machine in a safe, easy-to-retrieve fashion that make almost all e-commerce
possible. Web sites can now keep track of who you are, when you last visited,
and what type of books you like, for example.
Cookies are very simple. They are sent to the client using a Set-Cookie
HTTP
response header in the following format (note that the Set-Cookie header
should
all be on one line):
Set-Cookie: NAME=VALUE; expires=DATE; domain=DOMAIN_NAME;
path=PATH; secure
The syntax breaks down as follows:
NAME=VALUE
The name/value pair of the specific cookie the web server wishes saved
on
the client machine. The value can contain any character but white space,
commas, or semicolons. This part of the cookie is mandatory.
expires
Holds a date after which the browser can dispose of the cookie. If no
expires attribute is given, this defaults to the end of the current HTTP
session. The format of the expires date is the following:
Wdy, DD-Mon-YYYY HH:MM:SS GMT
Note that only Greenwich mean times are allowed.
domain
Each time the user navigates to a specific URL, the domain attributes
of all the
cookies on the users machine are compared against the domain of
the URL. If
the domain attribute of any cookie on the users machine matches
the tail of
the URL domain (the last two segments of the full domain name), then that
cookie is sent as a Request header (more on this later) to that URL. A
domain
must have at least two periods in its name to set the domain attribute
of a
cookie sent to the client. For example, www.microsoft.com can send cookies
to your machine (and does), but mydomain.com cannot. The actual value
of
the Microsoft-related cookie domain attribute would be Microsoft.com.
This cookie would thus be sent to any URL ending with Microsoft.com,
including www.microsoft.com, home.microsoft.com. Likewise, only pages
within this domain can set cookies with this domain attribute. For example,
www.microsoft.com can send cookies with a domain of Microsoft.com, but
www.ora.com cannot.
If no domain attribute is included in the cookie sent to the client browser,
the
default is the domain name of the sender of the cookie. This is an optional
parameter.
path
The subset of URLs within the domain defined by the cookies domain
attribute. Its value determines whether the cookie is sent back to the
server. If
no path attribute is sent, the default is the path of the document the
browser
is viewing. For example, cookies from www.oreilly.com/newtitles/upcoming.
asp without a path attribute set would default to /newtitles/. The browser
will send cookies from this page only to those pages in this path. The
most
general path for a domain is /. This is an optional attribute.
This discussion of path brings up a sometimes confusing point. Does the
browsers machine store one cookie for each page in a path or does
it only
store a single cookie that is used repeatedly? The answer is that the
browser
stores a cookie for each individual cookie value. There is no single cookie
that contains those cookie values for the current page. Each cookie value
has
its own entry.
secure
When present for a cookie, instructs the browser to send this cookie only
to
pages within the path specified in the path property if the server and
browser
are communicating over a secure channel (HTTPS, for example).
If the user navigates to a URL for which a cookie is present on the local
machine,
the browser will send a Request header in the following format:
Cookie:Name1=Value1;Name2=Value2;...NameX=ValueX;
where:
NameX
Is the name of a cookie for that URL.
ValueX
Is the value of the corresponding cookie with the name NameX. This value
must be a string with no spaces, semicolons, or commas.
An example will help to make this clearer. Suppose a client navigates
to a URL
and his browser receives the following HTTP response headers:
Set-Cookie: userid=a.keyton.weissinger; domain=yourbooks.com;
path=/; expires=Thursday, 10-Nov-1999 23:59:59
Set-Cookie: usersel=aspbooks; domain=yourbooks.com;
path=/sales/; expires=Monday, 01-Jan-2010 23:59:59
Between now and 10 November 1999 at 11:59 P.M., the first cookie will
be sent to
the web server any time the client navigates to any page within any domain
whose last two segments are yourbooks.com. The HTTP request header will
resemble the following:
Cookie: userid=a.keyton.weissinger
Between now and 1 January 2010 at 11:59 P.M., the second cookie will be
sent to
any page in the yourbooks.com domain whose path is /sales/something. For
example, the following cookie request header:
Cookie: usersel=aspbooks
would be sent to www.yourbooks.com/sales/default.asp or to www.yourbooks.com/
sales/final/asp, or even to www.yourbooks.com/sales/checkout/default.asp.
Finally, if both sets of criteria (for both cookies userid and usersel)
are met, the
following cookie header will be sent by the user browser:
Cookie: userid=a.keyton.weissinger; usersel=aspbooks
There are several other details about cookies that you should be aware
of if you
plan to make extensive use of them. See either of the preceding references
for
more information. With this brief overview concluded, well now move
on to the
Cookies collection of the Request object.
The Cookies collection of the Request object enables your ASP application
to
retrieve the values of cookies and cookie dictionary items from the clients
HTTP
request body.
The Cookies collection, like the other ASP collections, has the following
properties:
Item
Represents the value of a specific cookie in the collection. To specify
a
cookie, you can use an index number or a key.
Key
Represents the name of a specific element in the Cookies collection. Just
as
each elements value is represented by the Item property, each elements
name is represented by its Key property.
If you do not know the name of a specific key, you can obtain it using
its
ordinal reference. For example, assume that you want to learn the key
name
for the third element in the collection and, subsequently, that elements
value.
You could use the following code:
strKeyName = Request.Cookies.Key(3)
strKeyValue = Request.Cookies.Item(strKeyName)
If, on the other hand, you know that the third elements key name
is STATE,
you could simply use the following code to retrieve the value of that
element:
strKeyValue = Request.Cookies.Item("STATE")
Count
Represents the number of elements in the collection.
As with other ASP collections, you can retrieve the value of any field
of the
Cookies collection through the use of the Item property. Note that in
the examples
and explanations given here, the syntax has been abbreviated so that it
does
not explicitly show the use of the Item property. For example:
strLastSearch = Request.Cookies("LastSearch")
is only an abbreviated form of:
strLastSearch = Request.Cookies.Item("LastSearch")
For more information on the Item, Key, and Count properties of a
collection, see the discussion in the section Contents Collection
in
Chapter 4.
In addition to storing simple values, a cookie in the Cookies collection
can represent
a cookie dictionary. A dictionary is a construct that is similar to an
associative
array in that each element of the array is identifiable by its name.
However, it is important to note that although a cookie can contain a
cookie
dictionary, it cannot contain more complex data types, such as objects.
To determine the value of a specific value within a cookie dictionary,
you must
use a SubKey. For example, suppose a specific cookie represents the five
colors
chosen by a user on a web page. The cookie itself is called Colors and
the
subkeys have the following names: color1, color2, . . . color5. To determine
the value residing in color3, you would use code resembling the following:
strColor3 = Request.Cookies("Colors")("color3")
To determine whether a specific cookie has subkeys, you must use the HasKeys
property of that specific cookie, as in the following:
blnHasKeys = Request.Cookies("Colors").HasKeys
If blnHasKeys Then
strColor3 = Request.Cookies("Colors")("color3")
End If
Example
<%
' The following code iterates through the Cookies collection.
' If a given cookie represents a cookie dictionary, then
' a second, internal for...each construct iterates through
' it retrieving the value of each subkey in the dictionary.
Dim strCookie
Dim strSubKey
Dim str3rdCookieValue
Dim strCompanyCookieValue
For Each strCookie In Request.Cookies
If Request.Cookies(strCookie).HasKeys Then
' The cookie is a dictionary. Iterate through it.
%>
The cookie dictionary <%=strCookie%> has the
following values:
<%
For Each strSubKey In Request.Cookies(strCookie)
%>
SubKey: <%= strSubKey %><BR>
Value:
<%=Request.Cookies(strCookie)(strSubKey)%><BR>
<%
Next
Else
' The cookie represents a single value.
%>
The cookie <%=strCookie%> has the following value:
<%=Request.Cookies(strCookie)%> <BR>
<%
End If
Next
' The following code retrieves the value of the third cookie
' in the Cookies collection.
str3rdCookieValue = Request.Cookies(2)
' The following code retrieves the value of the "company"
' cookie in the Cookies collection.
strCompanyCookieValue = Request.Cookies("Company")
%>
Notes
When accessing a cookie that represents a cookie dictionary, if you do
not specify
a subkey, you will retrieve a string value similar to the following:
FirstSubKey=FirstSubKeyValue&SecondSubKey=SecondSubKeyValue
Part of the cookie structure on the clients machine is a path representing
the web
page from which the client received the cookie. An important point about
retrieving cookie values comes into play when two cookies with the same
name,
but different paths, exist. In such a case, attempting to retrieve the
cookie will
retrieve only the cookie from the deeper directory. For example, if the
web page
www.MyCompany.com/ContribApp/Contrib1.asp has a cookie named UserPref
and a second web page with a deeper path, for example, www.MyCompany.com/
ContribApp/Addresses/AddrContrib1.asp, also has a cookie named UserPref,
then
attempting to retrieve the UserPref cookie will retrieve only the second
UserPref cookie.
If you attempt to retrieve the value of a subkey for a cookie name that
does not
represent a cookie dictionary, the result will be null. For this reason,
it is important
to take advantage of the HasKeys property before attempting to retrieve
the
value of a subkey.
As you know, the HTTP Persistent Client State Mechanism (cookies to most
people) is a continuously evolving recommendation. Any cookie draft remains
valid for only six months. The current draft, as of this writing, can
be found at ftp:/
/ftp.isi.edu/internet-drafts/draft-ietf-http-state-man-mec-08.txt.
From this document (or its more recent equivalent), you will learn that
the latest
draft for the cookies specification goes far beyond that originally proposed
by
Netscape. Obviously, the current Cookies collection of the Request object
supports
only some of this specification. It is assumed that as the draft becomes
a standard,
more aspects of cookies will be retrievable through the Request Cookies
collection.
Form
Request.Form
The Form collection allows you to retrieve the information input into
an HTML
form on the client and sent to the server using the POST method. This
information
resides in the body of the HTTP request sent by the client.
The Form collection, like the other ASP collections, has the following
properties:
Item
Represents the value of a specific element in the collection. To specify
an
item, you can use an index number or a key. In the case of the Form collection,
the index number represents the number of the element on the HTML
form. For example, suppose you have the following HTML form:
<FORM ACTION = "RecordPrefs.asp" METHOD = POST>
Name: <INPUT TYPE = TEXT NAME = "Name"><BR>
Color Pref: <SELECT NAME = "optColor">
<OPTION VALUE = "red" SELECTED>Red
<OPTION VALUE = "blue" >Blue
<OPTION VALUE = "green" >Green
</SELECT><BR>
Have a Modem? <INPUT TYPE = CHECKBOX NAME = "Modem"><BR>
<INPUT TYPE=submit VALUE=submit>
</FORM>
From within RecordPrefs.ASP, the first element (element 1) is Name.
The
third element is Modem. Note that the numbering begins with
1 (one).
Key
Represents the name of a specific element in the Form collection. Just
as each
elements value is represented by the Item property, so each elements
name
is represented by its Key property.
If you do not know the name of a specific key, you can obtain it using
its
ordinal reference. For example, assume that you want to learn the key
name
for the third element in the collection and, subsequently, that elements
value.
You could use the following code:
strKeyName = Request.Form.Key(3)
strKeyValue = Request.Form.Item(strKeyName)
If, on the other hand, you know that the third elements key name
is STATE,
you could simply use the following code to retrieve the value of that
element:
strKeyValue = Request.Form.item("STATE")
Count
Returns the number of elements in the collection.
As with other ASP collections, you can retrieve the value of any field
of the Form
collection through the use of the Item property. Note that in the following
examples
and explanations, the syntax has been abbreviated so that it does not
explicitly show the use of the Item property. For example:
strFirstName = Request.Form("txtFirstName")
is only an abbreviated form of:
strFirstName = Request.Form.Item("txtFirstName")
For more information on the Item, Key, and Count properties of a
collection, see the discussion in the section Contents Collection
in
Chapter 4.
Example
The examples of the Form collection of the Request object will all use
the
following HTML form:
<HTML>
<HEAD>
<TITLE>User Information</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>User Information</H1>
Please enter your user information using the form below:
<FORM NAME = "frmInfo" ACTION="UserInfo.ASP"
METHOD = "POST">
First Name: <INPUT TYPE="text" NAME = "txtFirstName"><BR>
Last Name: <INPUT TYPE="text" NAME = "txtLastName"><BR>
Zipcode: <INPUT TYPE="text" NAME = "txtZipCode"><BR>
Occupation: <INPUT TYPE="text" NAME = "txtOccupation"><BR>
Please select your connection speed:
<SELECT NAME = "optConnSpeed">
<OPTION VALUE = "28.8" SELECTED>28.8 Modem
<OPTION VALUE = "ISDN" >ISDN
<OPTION VALUE = "T1" >T1
<OPTION VALUE = "T3" >T3
</SELECT><BR>
Below, select all the peripherals you have:
<INPUT TYPE = "checkbox" NAME = "chkPeriph"
VALUE = "Joystick">Joystick<BR>
<INPUT TYPE = "checkbox" NAME = "chkPeriph"
VALUE= "GraphicsAccel">3D Graphics Card<BR>
<INPUT TYPE = "checkbox" NAME = "chkPeriph"
VALUE = "Printer">Printer<BR>
<BR>
Check here if it's ok to send your information:
<INPUT TYPE = "checkbox" NAME = "chkSellInfo"><BR>
<INPUT TYPE = "Submit"VALUE = "Submit User Info">
</FORM>
</BODY>
</HTML>
Once the client clicks on the forms Submit button, the form information
is sent to
the web server via the HTTP Post method in the body of the HTTP request
body.
The following code could be used in UserInfo.ASP to determine the values
of the
specific elements of the form frmInfo in the previous example. It is assumed
in
the following code that you know before writing it the exact fields in
the form that
are to be processed.
<%
' The following code example demonstrates the use of
' the Form collection of the Request object to retrieve
' the values entered by the client into an HTML form.
Dim strFirstName
Dim strLastName
Dim strZipCode
Dim strOccupation
Dim blnSendInfo
Dim strConnSpeed
Dim intPeriphCount
Dim aryPeripherals()
Dim chkItem
intPeriphCount = 0
' Retrieve the information from the form's text boxes.
strFirstName = Request.Form("txtFirstName")
strLastName = Request.Form("txtLastName")
strZipCode = Request.Form("txtZipCode")
strOccupation = Request.Form("txtOccupation")
' Retrieve the information from the Sell Information
' checkbox.
blnSendInfo = Request.Form("chkSellInfo")
' Determine the connection speed from the Connection
' Speed option buttons.
strConnSpeed = Request.Form("optConnSpeed")
' Populate an array with the peripherals the user has.
For Each SubKey in Request.Form("chkPeriph")
ReDim Preserve aryPeripherals(intPeriphCount + 1)
intPeriphCount = intPeriphCount + 1
aryPeripherals(intPeriphCount) = _
Request.Form("chkPeriph")(intPeriphCount)
Next
%>
Notes
If you refer to an element without an index and that element contains
multiple
values, your code will return a comma-delimited string. For example, suppose
that
instead of using a subkey with the chkPeriph element of the Form collection
earlier in this chapter, we included the following line of code:
response.write Request.Form("chkPeriph")
Assuming we chose all three options (Joystick, GraphicsAccel, and Printer),
this line of code would result in the following string:
Joystick, GraphicsAccel, Printer
Your application also can retrieve unparsed data from the clients
HTTP request.
To retrieve unparsed data from the HTTP request body, use Request.Form
without
any parameters. Note that the use of unparsed HTTP request dataspecifically
binary datain this manner can be problematic. However, there are
several
ActiveX controls and Java applets that can be used to retrieve binary
data more
efficiently.
To submit information from an HTML form to an ASP application, you must
set the
<FORM> tags ACTION attribute to the name of the file that
will process the HTML
form data. This Active Server Page can be in the same virtual directory
or can be
specified in terms of its virtual directory. You can do this from an HTML
page or
from another ASP file. However, one of the most powerful uses of this
process is
the construction of an ASP that calls itself. This is not necessarily
faster, but its
development is more efficient.
The following example demonstrates a simple ASP that constructs an HTML
form
whose entered data is processed by the same ASP:
<%
' UserInfo2.ASP
' The following code determines whether the HTML form (see
' the bottom portion of the script) has been filled out. If
' it has, then some processing takes place and one HTML output
' is sent back to the client. If not, the HTML form is sent to
' the client.
If Not IsEmpty(Request.Form("txtFirstName")) And _
Not IsEmpty(Request.Form("txtLastName")) Then
' The form has been filled out and the reply is
' a brief thank you.
%>
<HTML>
<HEAD><TITLE>Thank You</TITLE>
</HEAD>
<BODY>
Thank you, <%= Request.Form("txtFirstName")%> 
<%= Request.Form("txtLastName")%> for your information.
Have a nice day.
</BODY>
</HTML>
<%
Else
%>
<HTML>
<HEAD><TITLE>Thank You</TITLE>
</HEAD>
<BODY>
<FORM NAME = "frmInfo" ACTION="UserInfo2.ASP"
METHOD = "POST">
First Name: <INPUT TYPE="text" NAME="txtFirstName"><BR>
Last Name: <INPUT TYPE="text" NAME="txtLastName"><BR>
<INPUT TYPE = "Submit" VALUE = "Submit User Info">
</FORM>
</BODY>
</HTML>
<%
End If
%>
This script first determines whether the form elements have been filled
out by the
client. If so, then this script sends a brief Thank You to
the client and the script
ends. If the information was not entered, the form is presented to the
user. This
technique, though it uses only a rudimentary form here, is very powerful
and can
significantly help you to modularize your code, a sometimes difficult
task in ASP
application development.
If your HTML form contains ActiveX controls in addition to (or instead
of) standard
HTML form elements, you can refer to their values in the same manner.
For
example, suppose you have the following (simple) HTML form containing
a single
Microsoft Forms 2.0 textbox:
<FORM NAME = "frmInfo" ACTION="UserInfo.ASP"
METHOD = "POST">
First Name:
<OBJECT NAME = "txtFirstName" WIDTH=211 HEIGHT=20
CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3">
<PARAM NAME="VariousPropertyBits" VALUE="746604571">
<PARAM NAME="BackColor" VALUE="16777215">
<PARAM NAME="MaxLength" VALUE="255">
<PARAM NAME="Size" VALUE="5574;529">
<PARAM NAME="Value" VALUE="">
<PARAM NAME="BorderColor" VALUE="0">
<PARAM NAME="FontCharSet" VALUE="0">
<PARAM NAME="FontPitchAndFamily" VALUE="2">
<PARAM NAME="FontWeight" VALUE="0">
</OBJECT>
<INPUT TYPE = "Submit"VALUE = "Submit User Info">
</FORM>
You could refer to the value entered into the textbox from UserInfo.ASP
using the
following line of code:
strFirstName = Request.Form("txtFirstName")
If you have an HTML form containing ActiveX controls whose values are
validated
using client-side script, make sure that none of your elements (the submission
button, for example) have the name Submit. This seems like a small point,
but if
you overlook it, you will not be able to submit your form! Try it.
Remember that data in the Form collection represents only that data in
the HTTP
request body. You also can use the HTTP Get method to send data from the
client
to the server. Using Get results in the information being sent from the
client in the
HTTP request header. To retrieve this data, you must use the Request objects
QueryString collection.
QueryString
Request.QueryString(element)[(key) | .Count]
The QueryString collection allows you to retrieve the information sent
by the client
using the HTTP Get method with an HTML form and data appended to the URL
when the page is requested. The QueryString collection is less capable
than the
Form collection, since there is a limit to the amount of data that can
be sent in the
header of an HTTP request. In my experience, this limit is around 2000
charac-
ters. More characters than this, sent as part of the QueryString, will
not be
processed, although the script still executes.
The QueryString collection, like the other ASP collections, has the following
properties:
Item
Returns the value of a specific element in the collection. To specify
an item,
you can use an index number or a key. In the case of the QueryString collection,
the index number represents the number of the element as it appears in
the URL or the number of the element on the HTML form (assuming a GET
method is used to send the data). If the POST method is used to submit
form
data, however, these HTML elements do not exist in the QueryString collection,
but rather in the Form collection of the Request object.
Key
Returns the name of a specific element in the QueryString collection.
Just as
each elements value is represented by the Item property, each elements
name is represented by its Key property.
If you do not know the name of a specific key, you can obtain it using
its
ordinal reference. For example, assume that you want to learn the key
name
for the third element in the collection and, subsequently, that elements
value.
You could use the following code:
strKeyName = Request.QueryString.Key(3)
strKeyValue = Request.QueryString.Item(strKeyName)
If, on the other hand, you know that the third elements key name
is STATE,
you could simply use the following code to retrieve the value of that
element:
strKeyValue = Request.QueryString.Item("STATE")
Count
The number of elements in the collection.
As with other ASP collections, you can retrieve the value of any field
of the
QueryString collection through the use of the Item property. Note that
in the
following examples and explanations, the syntax has been abbreviated so
that it
does not explicitly show the use of the Item property. For example,:
strFirstName = Request.QueryString("FirstName")
is only an abbreviated form of:
strFirstName = Request.QueryString.Item("FirstName")
For more information on the Item, Key, and Count properties of a
collection, see the discussion in the section Contents Collection
in
Chapter 4.
Example
<%
' This code iterates through the QueryString collection
' and fills an array with the values retrieved.
Dim item
Dim aryQueryValues()
Dim intItemCount
intItemCount = 0
For Each item In Request.QueryString
ReDim Preserve aryQueryValues(intItemCount + 1)
aryQueryValues(intItemCount) = _
Request.QueryString(item)
intItemCount = intItemCount + 1
Next
%>
Notes
Like the elements of the Form collection, elements of the QueryString
collection
can represent multiple values. For example, suppose your ASP file receives
a
submission from the following HTML form:
<FORM NAME = "frmInfo" ACTION="UserInfo2.ASP"
METHOD = "GET">
Below, select all the peripherals you have:
<INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE
=
"Joystick">Joystick<BR>
<INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE=
"GraphicsAccel">3D Graphics Card<BR>
</FORM>
Assume the user checks both checkboxes. The resulting information would
be
interpreted in the ASP exactly as if the ASP had been requested using
the
following URL:
UserInfo2.ASP?chkPeriph=Joystick&chkPeriph=GraphicsAccel
To refer to the first element, you could use the following code (note
that like other
ASP collections, the elements start at 1):
strFirstOption = Request.QueryString("chkPeriph")(1)
If you do not specify a subkey, as in:
strOptions = Request.QueryString("chkPeriph")
then strOptions would have the following value:
Joystick, GraphicsAccel
Also like the Form collection, the QueryString collection contains information
sent
from the client to the web server. This information can be in the form
of parameter/
value pairs appended to the end of the requested URL in the HTTP request
header, appended to the URL in the address field of the browser, or from
an
HTML form whose action is set to the HTTP Get method.
There are some limitations to the use of the QueryString collection, the
most
important of which is its limited length. Although this length varies
with varying
amounts of client and web server available memory, you should not count
on
being able to send more than ~1800 characters from the client to the server
using
the QueryString collection. This ~1800-character limit is
counted from the end of
the script name being called to the end of the parameter list appended
to the
requested URL, including the names, not just the values, of the parameters
sent.
Like elements of the Form collection, elements of the QueryString collection
can
contain multiple values. To determine the number of values available for
a specific
element of the collection, use the Count property of the element in question.
The
value of the Count property is equal to the number of values contained
in the
element and is zero (0) if the element is not in the collection.
You can retrieve all the values for a given multiple-value element by
leaving off
the index parameter for the specific element. The values are returned
as a commadelimited
string containing only the values from the element being addressed.
Also like the Form collection, you are able to retrieve unparsed data
in the
QueryString collection. To retrieve the raw, unparsed QueryString collection
data,
use the syntax Request.QueryString without any element parameter.
The data in the QueryString collection is also accessible from the ServerVariables
collection of the Request object, using the HTTP_QUERYSTRING parameter.
This is
covered in more depth in the section on the ServerVariables collection.
Finally, note that you must encode several special characters when used
in the
QueryString:
& The ampersand is used by ASP to delineate separate parameter/value
pairs
that have been added to the QueryString collection.
? The question mark delineates the beginning of the QueryString that is
added
after the filename extension in the filename requested in the URL from
the
client.
% The percentage symbol is used in the encoding of other special characters.
+ The plus sign is recognized in the QueryString as representing a space.
These characters can be encoded automatically using the URLEncode and
HTMLEncode methods of the Server object on the server side and custom
script on
the client side.
ServerVariables
Var = Request.ServerVariables(key)
The ServerVariables collection contains several predefined environment
variables
in the context of the clients specific HTTP request of the web server.
The ServerVariables collection, like the other ASP collections, has the
following
properties:
Item
The value of a specific element in the collection. To specify an item,
you can
use an index number or a key.
Key
Returns the name of a specific element in the ServerVariables collection.
Just
as each elements value is represented by the Item property, each
elements
name is represented by its Key property.
If you do not know the name of a specific key, you can obtain it using
its
ordinal reference. For example, assume that you want to learn the key
name
for the third element in the collection and, subsequently, that elements
value.
You could use the following code:
strKeyName = Request.ServerVariables.Key(3)
strKeyValue = Request.ServerVariables.Item(strKeyName)
If, on the other hand, you know that the third elements key name
isQUERY_STRING, you could simply use the following code to
retrieve the value of that element:
strKeyValue = _
Request.ServerVariables.Item("QUERY_STRING")
Or, simply
strKeyValue = Request.ServerVariables("QUERY_STRING")
Count
The number of elements in the collection.
As with other ASP collections, you can retrieve the value of any field
of the Server-
Variables collection through the use of the Item property. Note that in
the
following examples and explanations below (and in nearly all examples
from
other sources), the syntax has been abbreviated so that it does not explicitly
show
the use of the Item property. For example:
strFirstName = Request.ServerVariables("REMOTE_ADDR")
is only an abbreviated form of:
strFirstName = Request.ServerVariables.Item("REMOTE_ADDR")
For more information on the Item, Key, and Count properties of a
collection, see the discussion in the section Contents Collection
in
Chapter 4.
The possible values for Key are in the following list. Although they typically
appear in uppercase, Key is actually case insensitive. Note that like
elements from
other ASP collections, the element values from the ServerVariables collection
also
can be retrieved using an index number. However, it is important to realize
that
the following list is in alphabetical order, not in the order in which
the elements
exist in the ServerVariables collection.
ALL_HTTP
One long string containing all the HTTP headers sent by the clients
browser.
Each of the following elements can be parsed from this element.
ALL_RAW
One long string containing all the HTTP headers in their original state
as sent
by the client browser. The primary difference between the ALL_RAW and
the
ALL_HTTP values is that the values of the ALL_HTTP element are all prefixed
with HTTP_ and the header name is always capitalized. Each of the following
elements can be parsed from this element.
APPL_MD_PATH
Internally, the IIS metabase holds all the settings of the server. It
is similar in
function to the registry except for the fact that the metabase holds only
information
about those items added (as snap-ins) into the Microsoft Management
Console. This can include Internet Information Server, Index Server, and
SQL
Server 7.0, among others. The information in the metabase almost exclusively
represents installation and configuration information.
The APPL_MD_PATH element of the ServerVariables collection represents
the
metabase-specific path for the ISAPI DLL. This is the metabase path from
which the ISAPI DLL is called, not its physical location on the server.
For
example, on my Windows 95 machine (running Personal Web Server) the
value of this element is the following:
/LM/W3SVC/1/ROOT
APPL_PHYSICAL_PATH
The physical path of the APPL_MD_PATH element. This value is retrieved
from
the conversion of APPL_MD_PATH by IIS. For example, on my system this
translates to C:\Inetpub\wwwroot\.
AUTH_PASSWORD
If IIS security is set to Basic Authentication, AUTH_PASSWORD represents
the
password entered in the authentication box when the client logs into the
web
server. If a password is not supplied, its value is a null string.
AUTH_TYPE
The method of authentication set on the web server. This authentication
method is used to validate all users requesting scripts on the server
protected
by Windows NT security.
AUTH_USER
The raw username entered upon authentication of the client by the web
server.
CERT_COOKIE
A unique ID for the clients digital certificate. The value for this
element can
be used as a signature for the entire certificate. This element has a
value only
for clients using the HTTPS protocol. Note that the ClientCertificate
collection
contains all client-related digital certificate information. The ClientCertificate
collection is easier to use than the HTTP header information. Note also
that if
the client does not send a digital certificate, these CERT_ elements still
exist in
the ServerVariables collection, but they are empty (i.e., they have no
value).
CERT_FLAGS
CERT_FLAGS represents a two-bit value. Bit #0 is set to 1 if the client
certificate
is present. Bit #1 is set to 1 if the client certificates certifying
authority is
invalid (i.e., the issuer is not found in the list of verified certificate
issuers that
resides on the web server). Note that these values correspond to the
ceCertPresent and ceUnrecognizedIssuer constants for the Flags
element of the ClientCertificate collection.
CERT_ISSUER
The issuer of the client certificate, if one exists. The value of this
element is a
comma-delimited string that contains the subfields for each of the possible
subelements described in the Issuer element section of the ClientCertificate
collection explanation earlier in this chapter.
CERT_KEYSIZE
The number of bits used in the Secure Sockets Layer connection key size
(for
example, 64 or 128).
CERT_SECRETKEYSIZE
The number of bits in the secret server certificate private key (for example,
1024).
CERT_SERIALNUMBER
The value of the clients certificate serial number.
CERT_SERVER_ISSUER
The issuer of the server certificate.
CERT_SERVER_SUBJECT
The subject field of the server certificate. Like the Subject field of
the client
certificate, this elements value is a comma-delimited string containing
the
subfields described in the Subject element section of the ClientCertificate
collection description.
CERT_SUBJECT
The subject field of the client certificate. This elements value
is a commadelimited
string containing the subfields described in the Subject element
section of the ClientCertificate collection description.
CONTENT_LENGTH
The total length of the body of the HTTP request body sent by the client.
You
can use this value to determine the length of the raw HTTP content in
the
clients HTTP request. This value does not include the length of
any data
presented through the request header (i.e., information sent with a GET
method), only that information in the request body.
CONTENT_TYPE
This is the MIME type of the content sent by the client. When used with
HTTP
queries that contain attached information (such as HTTP GET, POST, and
PUT
actions), this can allow you to determine the data type of the clients
HTTP
request content data. The most common value for this element is
application/x-www-form-urlencoded. If you were to include a file
element in your HTML form, you would set the ENCTYPE parameter (and
thus the CONTENT_TYPE header in your request) to multipart/form-data.
GATEWAY_INTERFACE
The revision of the Common Gateway Interface that is used by the web server.
This string value is in the format CGI/revision #. For example, if you
were
connected to an IIS 4.0 web server, the value of this item would be CGI/1.1.
HTTP_[HeaderName]
The value sent in the HTTP header called headername. To retrieve the value
of any HTTP header not mentioned in this list (including custom headers),
you must prefix the header name with HTTP_. Note that if you specify an
HTTP_CUSTOM_SELECTION header, IIS will actually look for an HTTP
header labeled as Custom-Header by the client in its HTTP request. In
other
words, when looking for an HTTP header with hyphens in the name in the
ServerVariables collection, use underscores instead. Note that attempting
to
retrieve a nonexistent header returns an empty string, not an error. For
example, each of the following:
HTTP_ACCEPT_LANGUAGE
HTTP_CONNECTION
HTTP_HOST
HTTP_AUTHORIZATION (same as the AUTH_TYPE element)
HTTP_USER-AGENT
requires code resembling the following to receive its value:
strUserAgent = _
Request.ServerVariables("HTTP_USER-AGENT")
HTTPS
This elements value is the string ON if the clients
HTTP request was sent
using SSL. It is OFF otherwise.
HTTPS_KEYSIZE
The same as CERT_KEYSIZE described earlier.
HTTPS_SECRETKEYSIZE
The same as CERT_SECRETKEYSIZE described earlier.
HTTPS_SERVER_ISSUER
The same as CERT_SERVER_ISSUER described earlier.
HTTPS_SERVER_SUBJECT
The same as CERT_SERVER_SUBJECT described earlier.
INSTANCE_ID
The ID of the current IIS instance specified in textual format. If this
element
evaluates to 1, then the value is a string. The INSTANCE_ID represents
the
number of the instance of the web server to which this request belongs.
This
is useful only if there is more than one instance of the web server running
on
your server. Otherwise, this value is always 1, representing the first
(and only)
instance of the web server on the machine.
INSTANCE_META_PATH
The path in the metabase for the instance of IIS to which the clients
HTTP
request is sent. As discussed in the earlier section on the APPL_MD_PATH
element of the ServerVariables collection, the metabase holds information
specific to the installation and configuration of your web server. For
my
machine running Personal Web Server, the value of this element is /LM/
W3SVC/1.
LOCAL_ADDR
The TCP/IP address of the web server that is accepting the client HTTP
request. This element of the ServerVariables collection is especially
important
when your web server resides in a server farm of several machines with
distinct IP addresses, all answering requests to the same domain name.
If the
server is accessed as localhost, its value is 127.0.0.1.
LOGON_USER
The Windows NT user account with which the user has logged onto the
system. This is true regardless of the security type you have set for
your web
server (i.e., anonymous, basic, or Windows NT challenge/response).
PATH_INFO
The virtual path of the web page from which the client makes its HTTP
request. If this information evaluates to a virtual directory, the virtual
directory
is mapped to a physical directory before it is sent to the CGI filter.
PATH_TRANSLATED
The virtual-to-physical mapping of the value of the PATH_INFO element
of the
ServerVariables collection.
QUERY_STRING
The values sent by the client after the question mark (?) at the end of
the
HTTP request URL. This element also contains the information sent to the
web server using the HTTP GET method. All the information in this element
is
also available via the QueryString collection (which is easier to utilize,
as it
does not require parsing).
REMOTE_ADDR
The TCP/IP address of the client.
REMOTE_HOST
The IP address from which the web server receives the clients HTTP
request.
If the HTTP request does not include this information, the REMOTE_ADDR
elements value will be set and this value will be empty.
REQUEST_METHOD
The method by which the client made the HTTP request (GET, POST, HEAD,
etc.).
SCRIPT_NAME
The entire virtual path to the current script. It does not include the
base
portion of the URL, which is represented by the URL element of the Server-
Variables collection. It is used (largely internally) for self-referencing
URLs.
This is equivalent to the value of the PATH_INFO element.
SERVER_NAME
The web servers TCP/IP address, its DNS or hostname as it would
appear in
a self-referencing URL.
SERVER_PORT
The server port to which the clients HTTP request is sent. This
is typically 80
or 8080 for most web servers.
SERVER_PORT_SECURE
If the HTTP request is being managed by the web server on a secure port,
this value evaluates to 1. If the port is not secure, this value is 0.
SERVER_PROTOCOL
The name and version of the protocol used by the web server to handle
the
client request. For example, if the client is using Microsoft Internet
Explorer
4.01 and the web server is IIS 4.0, this value is the string HTTP/1.1.
SERVER_SOFTWARE
The name and version of the web server software handling the client HTTP
request. For example, again using Microsoft IIS 4.0, an example value
for this
element of the ServerVariables collection is Microsoft-IIS/4.0.
URL
The base URL requested by the client in its HTTP request.
Example
<%
' The following code determines the value of the
' LOGON_USER item of the ServerVariables collection. This
' code can be used to determine the identity of the
' client.
Dim strUserName
strUserName = Request.ServerVariables("LOGON_USER")
%>
Notes
As the list earlier in this section illustrates, the ServerVariables collection
contains
many very useful pieces of information regarding the clients HTTP
request.
Perhaps the most important elements allow you to determine the identity
and
address of the user. These elements allow you to customize your security
efforts.
Also, many of the Request objects other collections data can
be obtained through
the ServerVariables collection (usually with more effort, however).
Methods Reference
BinaryRead
MySafeArray = Request.BinaryRead(ByteCount)
The BinaryRead method reads a number of bytes directly from the HTTP request
body sent by the client as part of an HTTP Post. The data read from an
HTTP
request using the BinaryRead method is returned into a SafeArray. A SafeArray
is a
special variant array that contains, in addition to its items, the number
of dimensions
in the array and the upper bounds of the array.
In actuality, a SafeArray is not an array at all. Its a special
type of
structure used internally to maintain information held in its array
portion. The dimensions and upper bounds values are available only
from C/C++ as elements of the structure. You cannot manipulate
these values (or even retrieve them) through script.
Parameters
MySafeArray
The name of a SafeArray used to store the information returned from a
BinaryRead.
ByteCount
The number of bytes read using the BinaryRead method. Typically, this
variables
value evaluates to the number of bytes returned using the TotalBytes
property of the Request object described previously.
Example
<%
' The following code determines the total number of bytes
' sent in the client's HTTP request. It then reads the
' bytes, checks for errors, and if there are none,
' reports to the client that the read was successful.
Dim lngTotalByteCount
Dim vntRequestData
On Error Resume Next
lngTotalByteCount = Request.TotalBytes
vntRequestData = Request.BinaryRead(lngTotalByteCount)
If Err = 0 Then
' For details about the Response object, see Chapter 7.
' For now, suffice it to say the following code sends
' information to the client.
Response.Clear
Response.Write lngTotalByteCount & _
" bytes successfully read.<BR>"
Response.End
End If
%>
Notes
If your web applications client piece could control exactly what
was sent in the
HTTP request body, this method would be invaluable, since it would enable
your
client to upload information on a byte level (or upload files). However,
controlling
the information sent in a Post request at byte level is difficult. There
are,
however, several file-transfer controls available via third parties that
allow you to
add file-transfer functionality to your application more efficiently and
with less
difficulty.
It is important to note that if you have previously retrieved information
from the
Form collection of the Request object, subsequent calls to the BinaryRead
method
will cause an error. Likewise, if you have previously called the BinaryRead
method
of the Request object and subsequently attempt to retrieve information
from the
Form collection, your script will result in an error.
|