<html>
<head>
<title>Request Object</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div id="Description">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">Request Object</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description">







<p>The Request object gives you access to the user's 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.</p>
</td></tr>
</table>
</div>
<div id="HowHTTPWorks">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
How HTTP Works</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2">&nbsp;</td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">

<p><!--<primary>HTTP
(Hypertext Transfer Protocol)</primary>-->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, don't worry. This will be
only a brief overview of the HTTP protocol.</p>




<sect2 role="" id="ch07-20114" label="7.1.1">
<p class="TITLE">HTTP: A Simple Example</p>




<p><!--<primary>HTTP
(Hypertext Transfer Protocol)</primary><secondary>example
of</secondary>-->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.</p>




<!--
<p class="TITLE">HELLO.HTM, a simple HTML form</p>



<graphic width="431" depth="209" fileref="figs/ASP2.0701.gif"/>-->

<figure id="ch07-15144" label="7.2">
<p class="TITLE">HELLOCGI.HTM, an HTML page created by a CGI application</p>



<graphic width="431" depth="199" fileref="figs/ASP2.0702.gif"/></figure>

<p>To illustrate the interaction between <!--<primary>web browsers</primary><secondary>HTTP
interaction, example</secondary>--> <!--<primary>web
servers</primary><secondary>HTTP interaction,
example</secondary>--> <!--<primary>servers</primary><see>web
servers</see>-->web browser and server, let's examine
a fairly simple example that illustrates this exchange. <link linkend="ch07-22039">Figure 7.1</link> shows Netscape Navigator displaying a very
simple form, <filename>HELLO.HTM</filename>, 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 <link linkend="ch07-15144">Figure 7.2</link>. (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 <link linkend="appb-1-fm2xml">Appendix B</link>.) Let's
see how this interchange between browser and server are handled by
the protocol:</p>




<orderedlist><dd><p>When the user finishes entering the URL for
<filename>HELLO.HTM</filename>, Navigator sends the following stream to the server:</p>



<p><function>send </function>in the following output listing is a
socket 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.</p>


<span class="PROGRAMLISTING"><pre>[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, */*</pre></span>



<p>This is a <!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>request headers</secondary>-->
<!--<primary>requests,
HTTP</primary><secondary>headers</secondary>-->
<!--<primary>headers,
HTTP</primary><secondary>requests</secondary>-->request
header. The browser indicates that it wants the server to get the
document <em>/HELLO.HTM</em>. <em>Get</em> is
more than a generic description of what the server should do; it
indicates the HTTP request type. (For details, see <link linkend="ch07-20207">Section 7.1.2</link>, later in this chapter.) The browser
also indicates that it's using version 1.0 of the Hypertext
Transfer Protocol.</p>


<tip id="ch07-3-fm2xml" role="ora">
<p>Note that a portion of 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.</p>



</tip>
</dd>



<dd><p>The server receives the headers sent by the browser, as
shown in the following output produced by our spy program, and
processes the request:</p>

<p>The <function>recv
</function>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 function's
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.</p>

<span class="PROGRAMLISTING"><pre>[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, */*</pre></span>
</dd>


<dd>
<p>The server sends the document <em>HELLO.HTM</em> to the
browser:</p>


<span class="PROGRAMLISTING"><pre>[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

&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;Hello, World!&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;FORM ACTION="/cgi-win/hello.exe" METHOD="POST"&gt;
What is your name? &lt;INPUT TYPE="text" NAME="name" SIZE=60&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit" VALUE="Submit the form"&gt;
&lt;INPUT TYPE="reset" VALUE="Clear all fields"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt; &lt;/HTML&gt;</pre></span>



<p>Here, WebSite sends a total of 535 bytes to the browser. This
consists of a <em>response
header</em><!--<primary>responses,
HTTP</primary><secondary>headers</secondary>-->
<!--<primary>headers,
HTTP</primary><secondary>responses</secondary>-->
<!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>response
headers</secondary>-->, 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 transmitted data. "200
OK" is a status code indicating that the browser's
request was fulfilled. The server also indicates that, like the
browser, it's using version 1.0 of HTTP.</p></dd>



<dd><p>The browser reads the headers and data sent by the
server:</p>


<span class="PROGRAMLISTING"><pre>[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

&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;H
[73:recv: posted]
[73:recv: completed (275)]ello, World!&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;FORM ACTION="/cgi-win/hello.exe" METHOD="POST"&gt;
What is your name? &lt;INPUT TYPE="text" NAME="name" SIZE=60&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit" VALUE="Submit the form"&gt;
&lt;INPUT TYPE="reset" VALUE="Clear all fields"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt; &lt;/HTML&gt;</pre></span>



<p>Although two <function>recv</function> 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.</p></dd>

<dd><p>The browser displays the form asking for the user's name and,
when the user fills it out and clicks the Submit button, sends the
following to the server:</p>

<span class="PROGRAMLISTING"><pre>[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</pre></span>



<p>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
<span class="LITERAL">x-www-form-urlencoded</span> data in the body of the
request. This consists of the information input by the user in the
form's single data field, the <span class="LITERAL">name</span> text box.</p></dd><dd><p>The server receives the header records and form data transmitted by
the browser in the previous step. (Since it's basically
identical to the text sent by the browser, we won't duplicate
it here.) The URL (<em>/cgi-win/hello.exe</em>) causes the server to
launch the CGI application <filename>HELLO.EXE</filename> and to
transmit the form's 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.</p></dd>

<dd><p>The server returns the HTML document to the browser along with the
necessary header records, as the following output from WSock32 Spy
shows:</p>


<span class="PROGRAMLISTING"><pre>[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

&lt;HTML&gt;&lt;HEAD&gt;
&lt;TITLE&gt;Welcome to this Web Page!&lt;/TITLE&gt;&lt;/HEAD&gt;

&lt;BODY&gt;&lt;H1&gt;Welcome to Our Web Server!&lt;/H1&gt;&lt;p&gt;&lt;p&gt;
Hello, Jayne Doe! We're glad that you took
the time out of your busy day to visit us!
&lt;HR&gt;&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</pre></span>



<p>Notice that the server indicates to the browser that it's
sending 231 bytes of an HTML document.</p></dd><dd><p>The browser receives the data stream sent by the server and uses it
to render the HTML page.</p></dd></orderedlist>


<p>Hopefully, this gives you a fairly good sense of what's
involved in the interchange between browser and server. It's
important, though, to take a more in-depth look at some of the points
that we've touched on only briefly, as well as to cover some
additional features that are not included in this simple  example.</p>
</sect2>












<sect2 role="" id="ch07-20207" label="7.1.2">
<p class="TITLE">HTTP Request Types</p>




<p><!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>request types</secondary>-->
<!--<primary>request types</primary>-->The request
type is passed by the client to the server to indicate what the
server should do with the URL that's also supplied by the
browser. Although the HTTP specification details a number of request
types, like <span class="LITERAL">PUT</span> and <span class="LITERAL">DELETE</span>,
only two are supported by all servers and in common use:
<span class="LITERAL">GET</span><!--<primary>GET request type</primary>-->
<!--<primary>POST
request type</primary>--> and <span class="LITERAL">POST</span>. A
<span class="LITERAL">GET</span> 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 <span class="LITERAL">POST</span> request,
on the other hand, provides the server with information to be
"posted" to the URL; typically, it's used to send
the contents of an HTML form to the server, or to provide the server
with information that's needed for back-end processing. The
information itself is contained in the body of the request.</p>




<p>Most servers cannot handle data received from either the
<span class="LITERAL">POST</span> or <span class="LITERAL">GET</span> methods internally.
Normally, <span class="LITERAL">POST</span> requests, as well as
<span class="LITERAL">GET</span> requests that also send data to the server,
are handled by accessory programs or DLLs (CGI and ISAPI applications
and ISAPI filters). Both <span class="LITERAL">POST</span> and
<span class="LITERAL">GET</span> requests can return any kind of data of any
size.</p>




<p>While it may seem when transmitting data to a web server that
<span class="LITERAL">GET</span> and <span class="LITERAL">POST</span> are similar, one
rule is hard and fast: <em>A GET request must never change
anything.</em> Don't 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 <link linkend="ch07-26056">Section 7.1.3</link>.</p>




<!--
<p class="TITLE">GET Versus POST</p>




<p>In the event that you're confused about the difference between
these two methods, <span class="LITERAL">GET</span> can be used to retrieve any
document, <span class="LITERAL">POST</span> cannot. On the other hand, both
<span class="LITERAL">GET</span> and <span class="LITERAL">POST</span> can be used to
pass data to the object indicated by the URL. When
<span class="LITERAL">GET</span> 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
<span class="LITERAL">POST</span> 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, <span class="LITERAL">GET</span> and <span class="LITERAL">POST</span>
differ in the method used to transmit that
data. </p>



-->
</sect2>












<sect2 role="" id="ch07-26056" label="7.1.3">
<p class="TITLE">Form Submission</p>




<p><!--<primary>form submissions</primary>-->
<!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>form
submissions</secondary>--> <!--<primary>NAME=
attribute ()</primary>--> <!--<primary sortas="INPUT tags">tags</primary><secondary sortas="NAME attribute">NAME=
attribute</secondary>-->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
<var class="replaceable">name</var>=<var class="replaceable">value
</var>, where <var class="replaceable">name</var> is the name
assigned to the field by the <span class="LITERAL">NAME=</span> attribute of
the <span class="LITERAL">&lt;INPUT&gt;</span> tag, and
<var class="replaceable">value</var> 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
<span class="LITERAL">first_name=Archie</span>.</p>




<p>If the form is written to use
<span class="LITERAL">METHOD=GET</span><!--<primary>METHOD attribute
()</primary>--> <!--<primary sortas="FORM tags">tags</primary>-->, 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 <span class="LITERAL">GET</span>—typically
about 2000—is much lower than in a <span class="LITERAL">POST</span>.</p>




<p>If the form instead uses <span class="LITERAL">METHOD=POST</span>, the
<var class="replaceable">name</var>=<var class="replaceable">value</var>
pairs are sent as the <em>body</em> of the request
instead of being appended to the URL. In addition to the greater ease
of handling of <span class="LITERAL">POST</span> requests, most servers offer
better performance when extracting data from the body of a request
than from a URL in the request header.</p>




<p>Always use the <span class="LITERAL">POST</span> method with forms that change
something or cause any irreversible action (most do).
<span class="LITERAL">POST</span> is safer and more efficient;
<span class="LITERAL">GET</span> 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 <span class="LITERAL">GET</span>
method.</p>
</sect2>












<sect2 role="" id="ch07-5-fm2xml" label="7.1.4">
<p class="TITLE">HTTP Request and Response</p>




<p><!--<primary>headers, HTTP</primary>-->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.</p>




<p>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.)</p>




<p>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.</p>




<sect3 role="" id="ch07-6-fm2xml" label="7.1.4.1">
<p class="TITLE">The request</p>




<p><!--<primary>requests,
HTTP</primary><secondary>headers</secondary>-->
<!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>request headers</secondary>-->
<!--<primary>headers,
HTTP</primary><secondary>requests</secondary>-->In <link linkend="ch07-20114">Section 7.1.1</link> we saw a number
of requests from the browser. Here is another example of a simple
HTTP request:</p>




<span class="PROGRAMLISTING"><pre>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
<lineannotation>[mandatory blank line]</lineannotation>
name=Jayne+Doe</pre></span>




<p>The first line, which is known as the
<em>request-line</em><!--<primary>request-line</primary>-->,
describes the type of request (or <em>method
</em>)—in this case <span class="LITERAL">POST</span>, 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 that's
not required by HTTP. It gives the name and version of the client
software. Following this, as discussed in <link linkend="ch07-20114">Section 7.1.1</link>, are two lines describing the
information contained in the body of the request.</p>




<p>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.</p>




<p>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 <span class="LITERAL">POST</span> method is
used, the information sent to the web server is located in this
section of the request.</p>
</sect3>







<sect3 role="" id="ch07-7-fm2xml" label="7.1.4.2">
<p class="TITLE">The response</p>




<p><!--<primary>responses,
HTTP</primary><secondary>headers</secondary>-->
<!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>response
headers</secondary>--> <!--<primary>headers,
HTTP</primary><secondary>responses</secondary>-->Here is an
example of a simple HTTP response:</p>




<span class="PROGRAMLISTING"><pre>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
<lineannotation>[mandatory blank line]</lineannotation></pre></span>




<span class="PROGRAMLISTING"><pre>&lt;HTML&gt;&lt;HEAD&gt;
&lt;TITLE&gt;...</pre></span>




<p>The first line of the response is also special and is known as the
<em>status-line</em><!--<primary>status-line</primary>-->.
It contains the protocol version the server uses, plus a
<em>status code</em><!--<primary>status
code</primary>--> <!--<primary>reason
phrase</primary>--> and a <em>reason
phrase</em>. The server uses the status code and reason phrase
to inform the browser whether it was able to respond to the
browser's request; in this case, it's successfully filled
the browser's 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.</p>




<p>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.</p>




<p>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.</p>
</sect3>
</sect2>












<sect2 role="" id="ch07-8-fm2xml" label="7.1.5">
<p class="TITLE">The HTTP Request and the ASP Request Object</p>




<p><!--<primary>Request
object</primary><secondary>HTTP requests and</secondary>-->
<!--<primary>HTTP
(Hypertext Transfer
Protocol)</primary><secondary>requests</secondary><tertiary>Request
object and</tertiary>--> <!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>requests</secondary><seealso>Request object</seealso>-->As <!--<primary>requests,
HTTP</primary><secondary>Request object
and</secondary>-->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 client's 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.</p>




<p>Just as with CGI applications, the client browser can send
information to an ASP script in two different manners. First, it can
send information by means of an HTML form using the
<span class="LITERAL">GET</span><!--<primary>GET request
type</primary><secondary>sending to ASP
scripts</secondary>--> method:</p>




<span class="PROGRAMLISTING"><pre>&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;Welcome to the Corp.&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;FORM ACTION=" http://mycorp.com/secure.asp" METHOD="GET"&gt;
First name: &lt;INPUT TYPE="text" NAME="first_name" SIZE=60&gt;&lt;BR&gt;
Last name: &lt;INPUT TYPE="text" NAME="last_name" SIZE=60&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit" VALUE="Submit the form"&gt;
&lt;INPUT TYPE="reset" VALUE="Clear all fields"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt; &lt;/HTML&gt;</pre></span>




<p>When the client submits a <span class="LITERAL">GET</span> 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:</p>




<span class="PROGRAMLISTING"><pre>http://mycorp.com/secure.asp?first_name=horatia&amp;last_name=thompson</pre></span>




<p>This is an important point. Following this example, consider the
following line of code:</p>




<span class="PROGRAMLISTING"><pre>http://mycorp.com/secure.asp?first_name=horatia&amp;last_name=thompson</pre></span>




<p>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 <span class="LITERAL">GET</span> request. From
within your ASP application, you can access this information through
the <!--<primary>QueryString collection
(Request)</primary>-->QueryString collection of the Request
object. For example:</p>




<span class="PROGRAMLISTING"><pre>&lt;%
strFirstName = Request.QueryString("first_name")
%&gt;</pre></span>




<p>will initialize the <var class="replaceable">strFirstName</var> variable
to the value sent in the <span class="LITERAL">first_name</span> parameter. The
QueryString collection is discussed in detail later in this chapter.</p>




<p>Just as with CGI applications, you also can send information to an
ASP script using the <span class="LITERAL">POST</span><!--<primary>POST
request type</primary><secondary>sending to ASP
scripts</secondary>--> method. In this case, instead of
being part of the HTTP request header, the information would be in
the body of the request object:</p>




<span class="PROGRAMLISTING"><pre>&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;Welcome to the Corp.&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;FORM ACTION="http://mycorp.com/secure.asp" METHOD="POST"&gt;
First name: &lt;INPUT TYPE="text" NAME="first_name" SIZE=60&gt;&lt;BR&gt;
Last name:&lt;INPUT TYPE="text" NAME="last_name" SIZE=60&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit" VALUE="Submit the form"&gt;
&lt;INPUT TYPE="reset" VALUE="Clear all fields"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt; &lt;/HTML&gt;</pre></span>




<p>This form's submission would result in an HTTP request similar
to the following:</p>




<span class="PROGRAMLISTING"><pre>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
<lineannotation>[mandatory blank line]</lineannotation></pre></span>




<span class="PROGRAMLISTING"><pre>first_name=horatio&amp;last_name=aubrey</pre></span>




<p>For your application to manipulate the information sent in that HTTP
request, you would have to use the <!--<primary>Form
collection (Request)</primary>-->Form collection of the
Request object:</p>




<span class="PROGRAMLISTING"><pre>&lt;%
strFirstName = Request.Form("first_name")
%&gt;</pre></span>




<p>This will initialize the <var class="replaceable">strFirstName</var>
variable to the value sent in the <span class="LITERAL">first_name</span>
parameter. The Form collection is discussed in detail later in this


chapter.</p>
</sect2>
</td>
</tr>
</table>
</div>
<div id="TheASPRequestObject">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
The ASP Request Object</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2">&nbsp;</td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">




<p><!--<primary>Request object</primary>-->
<!--<primary>HTTP
(Hypertext Transfer
Protocol)</primary><secondary>requests</secondary>-->
<!--<primary>requests,
HTTP</primary>-->The properties, collections, methods, and
events of the ASP Request object are shown in the following box.</p>




<sidebar id="ch07-10-fm2xml" label="2">
<p class="TITLE">Request Object Summary</p>




<dl>
<dt>Properties</dt>
<dd><p>TotalBytes</p></dd>




<dt>Collections</dt>
<dd><p>ClientCertificate</p>






<p>Cookies</p>




<p>Form</p>




<p>QueryString</p>




<p>ServerVariables</p>
</dd>




<dt>Methods</dt>
<dd><p>BinaryRead</p></dd>




<dt>Events</dt>
<dd><p>None</p></dd>

</dl>



</sidebar>
</td>
</tr>
</table>
</div>
<div id="CommentsTroubleshooting">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
Comments/Troubleshooting</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2">&nbsp;</td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">

<p><!--<primary>comments and
troubleshooting</primary><secondary>Request
object</secondary>-->In the previous discussion of ASP and
the <span class="LITERAL">GET</span> and <span class="LITERAL">POST</span> methods, we
saw that information from a <span class="LITERAL">GET</span> is retrieved by
using the QueryString collection and that information from a
<span class="LITERAL">POST</span> 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:</p>

<span class="PROGRAMLISTING"><pre>strName = Request("name")</pre></span>




<p>returns the value of the "name" key regardless of the
collection in which it's 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:</p>




<orderedlist><dd><p>	QueryString</p></dd><dd><p>	Form</p></dd><dd><p>	Cookies</p></dd><dd><p>	ClientCertificate</p></dd><dd><p>	ServerVariables</p></dd></orderedlist>
<p>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.</p>




<p>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
<span class="LITERAL">For..Each</span> construct.</p>
</td>
</tr>
</table>
</div>
<div id="TotalBytes">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
TotalBytes</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><var class="replaceable">Var</var> <span class="LITERAL">= Request.</span>TotalBytes
</td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p>The <!--<primary>requests, HTTP</primary><secondary>size of
request body</secondary>--> <!--<primary>HTTP
(Hypertext Transfer
Protocol)</primary><secondary>requests</secondary><tertiary>size of
request body</tertiary>--> <!--<primary>TotalBytes
property (Request)</primary>--> <!--<primary>Request
object</primary><secondary>TotalBytes
property</secondary>-->
<!--<primary>size</primary><secondary>HTTP request
body</secondary>-->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.</p>



</td>
</tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td></tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Parameters</td>
</tr>
<tr>
<td colspan="2" class="description">




<dl>
<dt>Var</dt>
<dd><p>Receives the total number of bytes in the client's HTTP request
body when it posts data to the web server. Remember that the
TotalBytes property is read-only.</p></dd>

</dl>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>In this example, assume that the user has responded to the following
form:</p>




<span class="PROGRAMLISTING"><pre>&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;File Upload Form&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;FORM ENCTYPE = "multipart/form-data" 
ACTION= "http://mycorp.com/secure.asp" METHOD="POST"&gt;
Select a file to upload:
&lt;INPUT TYPE="file" NAME="filename"&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit" VALUE="Submit the form"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt; &lt;/HTML&gt;</pre></span>




<p>You can use the TotalBytes property to determine exactly how many
bytes of information were sent to the web server in the HTTP request:</p>




<span class="PROGRAMLISTING"><pre>&lt;% 
' 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)

%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>Most often, you will not need to access data in the HTTP request body
at the low level provided by the Request object's 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.</p>




<tip id="ch07-17-fm2xml" role="ora">
<p>In the preceding example, the value of
<var class="replaceable">vntRequestData</var> represents the
<em>total</em> 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.</p>



</tip>
</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="ClientCertificate">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
ClientCertificate</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><span class="PROGRAMLISTING"><pre>strKeyName = Request.ClientCertificate.Key(3)
strKeyValue = Request.ClientCertificate.Item(strKeyName)</pre></span></td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p><!--<primary>Request
object</primary><secondary>collections
reference</secondary>-->The <!--<primary>ClientCertificate collection
(Request)</primary>--> <!--<primary>digital
certificates</primary><secondary>client certificate field
access</secondary>--> <!--<primary>certificates</primary><see>digital
certificates</see>--> <!--<primary>client
certificates</primary><see>digital
certificates</see>-->ClientCertificate collection of the
Request object provides access to the certification fields of the
client's digital certificate. Client certificates are sent to
the web server when a client's 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
<em>https://</em>
rather than <em>http://</em>). For
example, if you were using Internet Explorer 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
<!--<primary>ITU Recommendation X.509</primary>-->
<!--<primary>X.509
Recommendation</primary>-->International Telecommunications
Union (ITU) recommendation X.509.</p>




<p>The ClientCertificate collection, like other ASP collections, has the
following properties:</p>




<dl>
<dt>Item</dt>
<dd><p><!--<primary>Item
property</primary><secondary>ClientCertificate
collection</secondary>-->Returns the value of a specific
element in the collection. To specify an item, you can use an index
number or a key.</p></dd>




<dt>Key</dt>
<dd><p><!--<primary>Key
property</primary><secondary>ClientCertificate
collection</secondary>-->Represents the name of a specific
element in the ClientCertificate collection. Just as each
element's value is represented by the Item property, each
element's name is represented by its Key property.</p>




<p>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 element's value. You could use the following
code:</p>




<span class="PROGRAMLISTING"><pre>strKeyName = Request.ClientCertificate.Key(3)
strKeyValue = Request.ClientCertificate.Item(strKeyName)</pre></span>




<p>If, on the other hand, you know that the third element's key
name is "ISSUER," you could simply use the following code
to retrieve the value of that element:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = Request.ClientCertificate.Item("ISSUER")</pre></span></dd>

</dl>



<p>As with other ASP collections, you can retrieve the value of any
field of the ClientCertificate 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:</p>




<span class="PROGRAMLISTING"><pre>strCertIssuer = Request.ClientCertificate("Issuer")</pre></span>




<p>is only an abbreviated form of:</p>




<span class="PROGRAMLISTING"><pre>strCertIssuer = Request.ClientCertificate.Item("Issuer")</pre></span>




<tip id="ch07-20-fm2xml" role="ora">
<p>For more information on the Item, Key, and Count properties of a
collection, see the discussion in <link linkend="ch04-3-fm2xml">Section 4.2</link> in <link linkend="ch04-40130">Chapter 4</link>.</p>



</tip>

<p>The available Key values are predefined and are as follows:</p>




<dl>
<dt>Certificate</dt>
<dd><p><!--<primary>Certificate value (Key
property)</primary>-->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.</p></dd>




<dt>Flags</dt>
<dd><p><!--<primary>Flags value (Key property)</primary>-->A
set of flags that provide additional information about the
client's certificate. These flags are integer values that can
be represented by the constants
<span class="LITERAL">ceCertPresent</span><!--<primary>ceCertPresent
constant</primary>-->
<!--<primary>ceUnrecognizedIssuer
constant</primary>--> <!--<primary>unrecognized
certificate issuers</primary>--> <!--<primary>issuer,
certificate</primary><see>digital certificates</see>--> and
<span class="LITERAL">ceUnrecognizedIssuer</span> if the VBScript include file
<filename>cervbs.inc</filename> is included in your scripts (see
<link linkend="ch11-1-fm2xml">Chapter 11</link>, for more on including files). As the
constant names suggest, <span class="LITERAL">ceCertPresent</span> signifies
that a client certificate is present, and
<span class="LITERAL">ceUnrecognizedIssuer</span> signifies that the
client's digital certificate was issued by an unknown
certificate authority.</p></dd>




<dt>Issuer</dt>
<dd><p><!--<primary>Issuer value (Key property)</primary>-->
<!--<primary>digital certificates</primary><secondary>issuer
information</secondary>-->A string that contains several
pieces of information about the issuer of the client's 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.).</p></dd>




<dt>SerialNumber</dt>
<dd><p><!--<primary>SerialNumber value (Key
property)</primary>-->An ASCII representation of the
hexadecimal bytes of the client's certification serial number.
This value is provided by the issuer. Retrieving the SerialNumber key
would provide a number such as 0A-B7-34-23.</p></dd>




<dt>Subject</dt>
<dd><p><!--<primary>Subject value (Key
property)</primary>-->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.</p></dd>




<dt>ValidFrom</dt>
<dd><p><!--<primary>ValidFrom value (Key
property)</primary>-->The date the certificate becomes
valid. This key's 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.<!--<primary>expiring</primary><secondary>digital
certificates</secondary>--></p></dd>




<dt>ValidUntil</dt>
<dd><p><!--<primary>ValidUntil value (Key
property)</primary>-->The date the certificate becomes
invalid. This key's 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.</p></dd>

</dl>




<p>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:</p>




<span class="PROGRAMLISTING"><pre>Request.ClientCertificate("IssuerC")</pre></span>




<p>If you wanted to retrieve the locality subkey value from the Subject
key list, you would retrieve its value using the syntax:</p>




<span class="PROGRAMLISTING"><pre>Request.ClientCertificate("SubjectL")</pre></span>




<tip id="ch07-21-fm2xml" role="ora">
<p>You also can retrieve a value from a specific subkey, including those
not listed here, from the Certificate key string value using the
subkey's ASN.1 identifier. An <!--<primary>ASN.1
identifiers</primary>-->ASN.1 identifier is a list of
numbers separated by a period, similar in appearance to an IP
address, but not limited to
through 255. For example: 3.56.7886.34.</p>



</tip>

<p>The available subkeys are as follows:</p>




<dl>
<dt>C</dt>
<dd><p>The country of origin for the Subject or Issuer.</p></dd>




<dt>CN</dt>
<dd><p>The common name of the Subject key. Note this subkey is not defined
for the Issuer key.</p></dd>




<dt>GN</dt>
<dd><p>The given name of the Subject or Issuer.</p></dd>




<dt>I</dt>
<dd><p>The initials of the Subject or Issuer.</p></dd>




<dt>L</dt>
<dd><p>The locality of the Subject or Issuer.</p></dd>




<dt>O</dt>
<dd><p>The organization or company name of the Subject or Issuer.</p></dd>




<dt>OU</dt>
<dd><p>The name of the specific organizational unit within an organization
or company for a Subject or Issuer.</p></dd>




<dt>S</dt>
<dd><p>The state (or province) of the Subject or Issuer.</p></dd>




<dt>T</dt>
<dd><p>The title of the Subject or Issuer.</p></dd>

</dl>



</td>
</tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td></tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<span class="PROGRAMLISTING"><pre>&lt;% 

' The following code retrieves the country of origin
' for the client's certificate issuer.
strCertIssuerCountry = Request.ClientCertificate("IssuerC")

%&gt;

&lt;!-- #include file="cervbs.inc" --&gt;

&lt;%
' The next example code determines whether the
' issuer is recognized by using the flags key.
If Request.ClientCertificate("Flags") _
   and ceUnrecognizedIssuer Then
%&gt;
   Your identification is in question because your issuer 
   is not recognized.
&lt;%
Else
%&gt;
   Welcome to our site.
&lt;%
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 " &amp; key &amp; " key contains the value "
   Response.Write Request.ClientCertificate(key) &amp; "&lt;BR&gt;"
Next 

%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>Before you can retrieve information from a client's digital
certificate, you must ensure that the client's 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.</p>




<p>You also must ensure that you have set up your IIS web server to
request client certificates.</p>




<p>If the client sends no digital certificate, any key you attempt to
retrieve from the ClientCertificate collection will be empty.</p>




<p>The <!--<primary>ITU Recommendation
X.509</primary>--> <!--<primary>X.509
Recommendation</primary>-->ITU Recommendation X.509 is just
that—a 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.   </p>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="Cookies">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
Cookies</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><span class="PROGRAMLISTING"><pre>Set-Cookie: NAME=VALUE; expires=DATE; domain=DOMAIN_NAME; 
path=PATH; secure</pre></span></td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p><!--<primary>cookies</primary>-->
<!--<primary>HTTP
(Hypertext Transfer
Protocol)</primary><secondary>cookies</secondary>-->Before
discussing the Cookies collection, we'll 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 <systemitem role="url">http://www.netscape.com/newsref/std/cookie_spec.html</systemitem>,
or visit Cookie Central, a clearinghouse of all cookie-related
information. I can specifically recommend <systemitem role="url">http://www.cookiecentral.com/unofficial_cookie_faq.htm</systemitem>.</p>




<p>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 site—even 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.</p>




<p>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 client's 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 Netscape's
Persistent Client State Mechanism or "cookies," as they
are known. (It's interesting to note that, according to the
Netscape preliminary specification, this state object was called a
cookie "for no compelling reason.")</p>




<p>Through the use of cookies, web servers can store information on the
client machine in a safe, easy-to-retrieve fashion that makes 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.</p>




<p>Cookies are very simple. They are sent to the client using a
<!--<primary>Set-Cookie header</primary>-->Set-Cookie
HTTP response header in the following format (note that the
Set-Cookie header should all be on one line):</p>




<span class="PROGRAMLISTING"><pre>Set-Cookie: NAME=VALUE; expires=DATE; domain=DOMAIN_NAME; 
path=PATH; secure</pre></span>




<p>The syntax breaks down as follows:</p>




<dl>
<dt><span class="LITERAL">NAME=VALUE</span></dt>
<dd><p>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.</p></dd>




<dt><span class="LITERAL">expires</span></dt>
<dd><p><!--<primary>expires attribute (Set-Cookie
header)</primary>-->
<!--<primary>expiring</primary><secondary>cookies</secondary>-->
<!--<primary>cookies, expiration
dates</primary>-->Holds a date after which the browser can
dispose of the cookie. If no <span class="LITERAL">expires</span> attribute is
given, this defaults to the end of the current HTTP session. The
format of the expires date is the following:</p>




<span class="PROGRAMLISTING"><pre>Wdy, DD-Mon-YYYY HH:MM:SS GMT</pre></span>




<p>Note that only Greenwich mean times are allowed.</p></dd>




<dt><span class="LITERAL">domain</span></dt>
<dd><p><!--<primary>domain attribute</primary><secondary>Set-Cookie
header</secondary>-->Each time the user navigates to a
specific URL, the domain attributes of all the cookies on the
user's machine are compared against the domain of the URL. If
the domain attribute of any cookie on the user's 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, <em>www.microsoft.com</em> can send cookies to your
machine (and does), but <em>mydomain.com</em> cannot. The actual value of the
Microsoft-related cookie <span class="LITERAL">domain</span> attribute would be
<span class="LITERAL">Microsoft.com</span>.</p>




<p>This cookie would thus be sent to any URL ending with <em>Microsoft.com</em>, including <systemitem role="httpurl">www.microsoft.com</systemitem>, <systemitem role="httpurl">home.microsoft.com</systemitem>. Likewise, only pages
within this domain can set cookies with this domain attribute. For
example, <systemitem role="httpurl">www.microsoft.com</systemitem> can
send cookies with a domain of <em>Microsoft.com</em>, but <systemitem role="httpurl">www.ora.com</systemitem> cannot.</p>




<p>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.</p></dd>




<dt><span class="LITERAL">path</span> </dt>
<dd><p><!--<primary>path attribute (Set-Cookie
header)</primary>-->The subset of URLs within the domain
defined by the cookie's <span class="LITERAL">domain</span> 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 <em>http://www.oreilly.com/newtitles/upcoming.ASP</em>
without a path attribute set would default to
<span class="LITERAL">/newtitles/</span>. 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.</p>




<p>This discussion of path brings up a sometimes confusing point. Does
the browser's 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.</p></dd>




<dt><span class="LITERAL">secure</span></dt>
<dd><p><!--<primary>secure attribute (Set-Cookie
header)</primary>-->
<!--<primary>security</primary><secondary>cookie
information</secondary>-->When present for a cookie,
instructs the browser to send this cookie only to pages within the
path specified in the <span class="LITERAL">path</span> property if the server
and browser are communicating over a secure channel (HTTPS, for
example).</p></dd>

</dl>




<p>If the user navigates to a
<!--<primary>URLs</primary><secondary>cookies</secondary><see>cookies</see>-->URL
for which a cookie is present on the local machine, the browser will
send a Request header in the following format:</p>




<span class="PROGRAMLISTING"><pre>Cookie:Name1=Value1;Name2=Value2;...NameX=ValueX;</pre></span>




<p>where:</p>




<dl>
<dt><var class="replaceable">NameX</var></dt>
<dd><p>Is the name of a cookie for that URL.</p></dd>




<dt><var class="replaceable">ValueX</var></dt>
<dd><p>Is the value of the corresponding cookie with the name
<var class="replaceable">NameX</var>. This value must be a string with no
spaces, semicolons, or commas.</p></dd>

</dl>




<p>An example will help to make this clearer. Suppose a client navigates
to a URL and his browser receives the following HTTP response
headers:</p>




<span class="PROGRAMLISTING"><pre>Set-Cookie: userid=a.keyton.weissinger; domain=yourbooks.com;
path=/; expires=Thursday, 10-Nov-2000 23:59:59

Set-Cookie: usersel=aspbooks; domain=yourbooks.com;
path=/sales/; expires=Monday, 01-Jan-2010 23:59:59</pre></span>




<p>Between now and 10 November 2000 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 <em>yourbooks.com</em>. The HTTP request header will
resemble the following:<!--<primary sortas="Cookie header">Cookie: header</primary>--></p>




<span class="PROGRAMLISTING"><pre>Cookie: userid=a.keyton.weissinger</pre></span>




<p>Between now and 1 January 2010 at 11:59 P.M., the second cookie will
be sent to any page in the <em>yourbooks.com</em> domain whose path is
<filename>/sales/something</filename>. For example, the following
cookie request header:</p>




<span class="PROGRAMLISTING"><pre>Cookie: usersel=aspbooks</pre></span>




<p>would be sent to <em>http://www.yourbooks.com/sales/default.ASP</em> or
to <em>http://www.yourbooks.com/sales/final/asp</em>, or
even to <em>http://www.yourbooks.com/sales/checkout/default.ASP</em>.</p>




<p>Finally, if both sets of criteria (for both cookies
<span class="LITERAL">userid</span> and <span class="LITERAL">usersel</span>) are met,
the following cookie header will be sent by the user browser:</p>





<span class="PROGRAMLISTING"><pre>Cookie: userid=a.keyton.weissinger; usersel=aspbooks</pre></span>




<p>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, we'll now move on to the Cookies collection of the
Request object.</p>




<p>The <!--<primary>Cookies
collection</primary><secondary>Request
object</secondary>-->Cookies collection of the Request
object enables your ASP application to retrieve the values of cookies
and cookie dictionary items from the client's HTTP request
body.</p>




<p>The Cookies collection, like the other ASP collections, has the
following properties:</p>




<dl>
<dt>Item</dt>
<dd><p><!--<primary>Item property</primary><secondary>Cookie
collection (Request)</secondary>-->Represents the value of a
specific cookie in the collection. To specify a cookie, you can use
an index number or a key.</p></dd>




<dt>Key</dt>
<dd><p><!--<primary>Key property</primary><secondary>Cookies
collection</secondary><tertiary>Request
object</tertiary>-->Represents the name of a specific
element in the Cookies collection. Just as each element's value
is represented by the Item property, each element's name is
represented by its Key property.</p>




<p>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 element's value. You could use the following
code:</p>




<span class="PROGRAMLISTING"><pre>strKeyName = Request.Cookies.Key(3)
strKeyValue = Request.Cookies.Item(strKeyName)</pre></span>




<p>If, on the other hand, you know that the third element's key
name is "STATE," you could simply use the following code
to retrieve the value of that element:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = Request.Cookies.Item("STATE")</pre></span></dd>




<dt>Count</dt>
<dd><p><!--<primary>Count property</primary><secondary>Cookie
collection (Request)</secondary>-->Represents the number of
elements in the collection.</p></dd>

</dl>




<p>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:</p>




<span class="PROGRAMLISTING"><pre>strLastSearch = Request.Cookies("LastSearch")</pre></span>




<p>is only an abbreviated form of:</p>




<span class="PROGRAMLISTING"><pre>strLastSearch = Request.Cookies.Item("LastSearch")</pre></span>




<tip id="ch07-24-fm2xml" role="ora">
<p>For more information on the Item, Key, and Count properties of a
collection, see the discussion in <link linkend="ch04-3-fm2xml">Section 4.2</link> in <link linkend="ch04-40130">Chapter 4</link>.</p>



</tip>

<p>In addition to storing simple values, a cookie in the Cookies
collection can represent a <!--<primary>cookie
dictionary</primary>--> <!--<primary>dictionary,
cookie</primary>-->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.</p>




<p>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.</p>




<p>To determine 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 <span class="LITERAL">Colors</span> and the subkeys have the following
names: <span class="LITERAL">color1</span>, <span class="LITERAL">color2</span>, . . .
<span class="LITERAL">color5</span>. To determine the value residing in
<span class="LITERAL">color3</span>, you would use code resembling the
following:</p>




<span class="PROGRAMLISTING"><pre>strColor3 = Request.Cookies("Colors")("color3")</pre></span>




<p>To determine whether a specific cookie has subkeys, you must use the
<!--<primary>HasKeys property, Cookies collection
(Request)</primary>-->HasKeys property of that specific
cookie, as in the following:</p>




<span class="PROGRAMLISTING"><pre>blnHasKeys = Request.Cookies("Colors").HasKeys
If blnHasKeys Then
   strColor3 = Request.Cookies("Colors")("color3")
End If</pre></span>



</td>
</tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td></tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<span class="PROGRAMLISTING"><pre>&lt;% 
' 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.
%&gt;
      The cookie dictionary &lt;%=strCookie%&gt; has the
      following values:
&lt;%
      For Each strSubKey In Request.Cookies(strCookie)
%&gt;
         &amp;nbsp; &amp;nbsp; SubKey: &lt;%= strSubKey %&gt;&lt;BR&gt;
         &amp;nbsp; &amp;nbsp; Value:
         &lt;%=Request.Cookies(strCookie)(strSubKey)%&gt;&lt;BR&gt;
&lt;%      
      Next
   Else
      ' The cookie represents a single value.
%&gt;
      The cookie &lt;%=strCookie%&gt; has the following value:
      &lt;%=Request.Cookies(strCookie)%&gt; &lt;BR&gt;
&lt;%
   End If

Next

' The following code retrieves the value of the third cookie
' in the Cookies collection.
str3rdCookieValue = Request.Cookies(3)

' The following code retrieves the value of the "company" 
' cookie in the Cookies collection.
strCompanyCookieValue = Request.Cookies("Company")

%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>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:</p>




<span class="PROGRAMLISTING"><pre>FirstSubKey=FirstSubKeyValue&amp;SecondSubKey=SecondSubKeyValue</pre></span>




<p>Part of the cookie structure on the client's 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
<em>http://www.MyCompany.com/ContribApp/Contrib1.ASP</em>
has a cookie named <span class="LITERAL">UserPref</span> and a second web page
with a deeper path, for example, <em>http://www.MyCompany.com/ContribApp/Addresses/AddrContrib1.ASP</em>,
also has a cookie named <span class="LITERAL">UserPref</span>, then attempting
to retrieve the <span class="LITERAL">UserPref</span> cookie will retrieve only
the second <span class="LITERAL">UserPref</span> cookie.</p>




<p>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.</p>




<p>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 <systemitem role="url">ftp://ftp.isi.edu/internet-drafts/draft-ietf-http-state-man-mec-08.txt</systemitem>.</p>




<p>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.  </p>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="Form">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
Form</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><span class="PROGRAMLISTING"><pre>&lt;FORM ACTION = "RecordPrefs.asp" METHOD = POST&gt;
Name: &lt;INPUT TYPE = TEXT NAME = "Name"&gt;&lt;BR&gt;
Color Pref: &lt;SELECT NAME = "optColor"&gt;
&lt;OPTION VALUE = "red" SELECTED&gt;Red
&lt;OPTION VALUE = "blue" &gt;Blue
&lt;OPTION VALUE = "green" &gt;Green   
&lt;/SELECT&gt;&lt;BR&gt;
Have a Modem? &lt;INPUT TYPE = CHECKBOX NAME = "Modem"&gt;&lt;BR&gt;
&lt;INPUT TYPE=submit VALUE=submit&gt;
&lt;/FORM&gt;</pre></span></td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p>The <!--<primary>Form collection
(Request)</primary>--> <!--<primary>forms</primary>-->Form
collection allows you to retrieve the information input into an HTML
form on the client and sent to the server using the
<span class="LITERAL">POST</span> method. This information resides in the body
of the HTTP request sent by the client.</p>




<p>The Form collection, like the other ASP collections, has the
following properties:</p>




<dl>
<dt>Item</dt>
<dd><p><!--<primary>Item property</primary><secondary>Form
collection</secondary>-->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:</p>




<span class="PROGRAMLISTING"><pre>&lt;FORM ACTION = "RecordPrefs.asp" METHOD = POST&gt;
Name: &lt;INPUT TYPE = TEXT NAME = "Name"&gt;&lt;BR&gt;
Color Pref: &lt;SELECT NAME = "optColor"&gt;
&lt;OPTION VALUE = "red" SELECTED&gt;Red
&lt;OPTION VALUE = "blue" &gt;Blue
&lt;OPTION VALUE = "green" &gt;Green   
&lt;/SELECT&gt;&lt;BR&gt;
Have a Modem? &lt;INPUT TYPE = CHECKBOX NAME = "Modem"&gt;&lt;BR&gt;
&lt;INPUT TYPE=submit VALUE=submit&gt;
&lt;/FORM&gt;</pre></span>




<p>From within <filename>RecordPrefs.ASP</filename>, the first element
(element 1) is "Name." The third element is
"Modem." Note that the numbering begins with 1 (one).</p></dd>




<dt>Key</dt>
<dd><p><!--<primary>Key property</primary><secondary>Form
collection</secondary>-->Represents the name of a specific
element in the Form collection. Just as each element's value is
represented by the Item property, so each element's name is
represented by its Key property.</p>




<p>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 element's value. You could use the following
code:</p>




<span class="PROGRAMLISTING"><pre>strKeyName = Request.Form.Key(3)
strKeyValue = Request.Form.Item(strKeyName)</pre></span>




<p>If, on the other hand, you know that the third element's key
name is "STATE," you could simply use the following code
to retrieve the value of that element:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = Request.Form.Item("STATE")</pre></span>




<p>Note that you cannot always count on the order with which the Form
elements are stored. For example, you may have eight items in your
submitted form. You have no way of knowing that the first element in
your form is the first element of the Form collection. For this
reason, you should always use a key string to identify the specific
element of the Form collection that you want.</p></dd>




<dt>Count</dt>
<dd><p><!--<primary>Count property</primary><secondary>Form
collection</secondary>-->Returns the number of elements in
the collection.</p></dd>

</dl>




<p>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:</p>




<span class="PROGRAMLISTING"><pre>strFirstName = Request.Form("txtFirstName")</pre></span>




<p>is only an abbreviated form of:</p>




<span class="PROGRAMLISTING"><pre>strFirstName = Request.Form.Item("txtFirstName")</pre></span>




<tip id="ch07-28-fm2xml" role="ora">
<p>For more information on the Item, Key, and Count properties of a
collection, see the discussion in <link linkend="ch04-3-fm2xml">Section 4.2</link> in <link linkend="ch04-40130">Chapter 4</link>.</p>



</tip>
</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>The examples of the Form collection of the Request object will all
use the following HTML form:</p>




<span class="PROGRAMLISTING"><pre>&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;User Information&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;CENTER&gt;
&lt;H1&gt;User Information&lt;/H1&gt;
Please enter your user information using the form below:
&lt;FORM NAME = "frmInfo" ACTION="UserInfo.ASP" 
      METHOD = "POST"&gt;
First Name:  &lt;INPUT TYPE="text" NAME = "txtFirstName"&gt;&lt;BR&gt;
Last Name:   &lt;INPUT TYPE="text" NAME = "txtLastName"&gt;&lt;BR&gt;
Zipcode:     &lt;INPUT TYPE="text" NAME = "txtZipCode"&gt;&lt;BR&gt;
Occupation:  &lt;INPUT TYPE="text" NAME = "txtOccupation"&gt;&lt;BR&gt;
Please select your connection speed:
&lt;SELECT NAME = "optConnSpeed"&gt;
&lt;OPTION VALUE = "28.8" SELECTED&gt;28.8 Modem
&lt;OPTION VALUE = "ISDN" &gt;ISDN
&lt;OPTION VALUE = "T1" &gt;T1   
&lt;OPTION VALUE = "T3" &gt;T3
&lt;/SELECT&gt;&lt;BR&gt;
Below, select all the peripherals you have: 
&lt;INPUT TYPE = "checkbox" NAME = "chkPeriph" 
       VALUE = "Joystick"&gt;Joystick&lt;BR&gt;
&lt;INPUT TYPE = "checkbox" NAME = "chkPeriph" 
       VALUE= "GraphicsAccel"&gt;3D Graphics Card&lt;BR&gt;
&lt;INPUT TYPE = "checkbox" NAME = "chkPeriph" 
        VALUE = "Printer"&gt;Printer&lt;BR&gt;
&lt;BR&gt;
Check here if it's ok to send your information: 
&lt;INPUT TYPE = "checkbox" NAME = "chkSellInfo"&gt;&lt;BR&gt;

&lt;INPUT TYPE = "Submit" VALUE = "Submit User Info"&gt;

&lt;/FORM&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;</pre></span>




<p>Once the client clicks on the form's Submit button, the form
information is sent to the web server via the HTTP Post method in the
body of the HTTP request body.</p>




<p>The following code could be used in <filename>UserInfo.ASP</filename>
to determine the values of the specific elements of the form
<span class="LITERAL">frmInfo</span> 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.</p>




<span class="PROGRAMLISTING"><pre>&lt;%

' 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
%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>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
<span class="LITERAL">chkPeriph</span> element of the Form collection earlier
in this chapter, we included the following line of code:</p>




<span class="PROGRAMLISTING"><pre>response.write Request.Form("chkPeriph")</pre></span>




<p>Assuming we chose all three options (<span class="LITERAL">Joystick</span>,
<span class="LITERAL">GraphicsAccel</span>, and <span class="LITERAL">Printer</span>),
this line of code would result in the following string:</p>




<span class="PROGRAMLISTING"><pre>Joystick, GraphicsAccel, Printer</pre></span>




<p>Your application also can retrieve unparsed data from the
client's 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 data—specifically binary
data—in this manner can be problematic. However, there are
several ActiveX controls and Java applets that can be used to
retrieve binary data more efficiently.</p>




<p>To submit information from an HTML form to an ASP application, you
must set the <span class="LITERAL">&lt;FORM&gt;</span> tag's
<span class="LITERAL">ACTION</span><!--<primary>ACTION attribute
()</primary>--> <!--<primary sortas="FORM tags">tags</primary><secondary>ACTION
attribute</secondary>--> 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
<!--<primary>ASP
(Active Server Pages)</primary><secondary>scripts calling
themselves</secondary>-->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.</p>




<p>The following example demonstrates a simple ASP that constructs an
HTML form whose entered data is processed by the same ASP:</p>




<span class="PROGRAMLISTING"><pre>&lt;%
' 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.
%&gt;
   &lt;HTML&gt;
   &lt;HEAD&gt;&lt;TITLE&gt;Thank You&lt;/TITLE&gt;
   &lt;/HEAD&gt;
   &lt;BODY&gt;
   Thank you, &lt;%= Request.Form("txtFirstName")%&gt;&amp;nbsp 
&lt;%= Request.Form("txtLastName")%&gt; for your information. 
Have a nice day.
   &lt;/BODY&gt;
   &lt;/HTML&gt;
&lt;%
Else
%&gt;
   &lt;HTML&gt;
   &lt;HEAD&gt;&lt;TITLE&gt;Thank You&lt;/TITLE&gt;
   &lt;/HEAD&gt;
   &lt;BODY&gt;
   
   &lt;FORM NAME = "frmInfo" ACTION="UserInfo2.ASP" 
         METHOD = "POST"&gt;
   First Name:  &lt;INPUT TYPE="text" NAME="txtFirstName"&gt;&lt;BR&gt;
   Last Name:   &lt;INPUT TYPE="text" NAME="txtLastName"&gt;&lt;BR&gt;

   &lt;INPUT TYPE = "Submit" VALUE = "Submit User Info"&gt;
   
   &lt;/FORM&gt;
   &lt;/BODY&gt;
   &lt;/HTML&gt;
&lt;%
End If

%&gt;</pre></span>




<p>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.</p>




<p>If your HTML form contains <!--<primary>ActiveX controls, HTML
forms with</primary>-->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:</p>




<span class="PROGRAMLISTING"><pre>&lt;FORM NAME = "frmInfo" ACTION="UserInfo.ASP" 
      METHOD = "POST"&gt;
First Name:   
&lt;OBJECT NAME = "txtFirstName" WIDTH=211 HEIGHT=20
   CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3"&gt;
   &lt;PARAM NAME="VariousPropertyBits" VALUE="746604571"&gt;
   &lt;PARAM NAME="BackColor" VALUE="16777215"&gt;
   &lt;PARAM NAME="MaxLength" VALUE="255"&gt;
   &lt;PARAM NAME="Size" VALUE="5574;529"&gt;
   &lt;PARAM NAME="Value" VALUE="&gt;
   &lt;PARAM NAME="BorderColor" VALUE="0"&gt;
   &lt;PARAM NAME="FontCharSet" VALUE="0"&gt;
   &lt;PARAM NAME="FontPitchAndFamily" VALUE="2"&gt;
   &lt;PARAM NAME="FontWeight" VALUE="0"&gt;
&lt;/OBJECT&gt;
&lt;INPUT TYPE = "Submit" VALUE = "Submit User Info"&gt;

&lt;/FORM&gt;</pre></span>




<p>You could refer to the value entered into the textbox from
<filename>UserInfo.ASP</filename> using the following line of code:</p>




<span class="PROGRAMLISTING"><pre>strFirstName = Request.Form("txtFirstName")</pre></span>




<p>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.</p>




<p>Remember that data in the Form collection represents only that data
in the HTTP request body. You also can use the HTTP
<span class="LITERAL">Get</span> method to send data from the client to the
server. Using <span class="LITERAL">Get</span> results in the information being
sent from the client in the HTTP request header. To retrieve this
data, you must use the Request object's QueryString
collection. </p>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="QueryString">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
QueryString</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><span class="PROGRAMLISTING"><pre>strKeyName = Request.QueryString.Key(3)
strKeyValue = Request.QueryString.Item(strKeyName)</pre></span></td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p>The <!--<primary>QueryString collection
(Request)</primary>--> <!--<primary>GET request
type</primary><secondary>retrieving data sent
with</secondary>-->QueryString collection allows you to
retrieve the information sent by the client using the HTTP
<span class="LITERAL">Get</span> 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 characters. More characters
than this, sent as part of the QueryString, will not be processed,
although the script still executes.</p>




<p>The QueryString collection, like the other ASP collections, has the
following properties:</p>




<dl>
<dt>Item</dt>
<dd><p><!--<primary>Item property</primary><secondary>QueryString
collection</secondary>-->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
<span class="LITERAL">GET</span> method is used to send the data). If the
<span class="LITERAL">POST</span> 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.</p></dd>




<dt>Key</dt>
<dd><p><!--<primary>Key property</primary><secondary>QueryString
collection</secondary>-->Returns the name of a specific
element in the QueryString collection. Just as each element's
value is represented by the Item property, each element's name
is represented by its Key property.</p>




<p>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 element's value. You could use the following
code:</p>




<span class="PROGRAMLISTING"><pre>strKeyName = Request.QueryString.Key(3)
strKeyValue = Request.QueryString.Item(strKeyName)</pre></span>




<p>If, on the other hand, you know that the third element's key
name is "STATE," you could simply use the following code
to retrieve the value of that element:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = Request.QueryString.Item("STATE")</pre></span></dd>




<dt>Count</dt>
<dd><p><!--<primary>Count property</primary><secondary>QueryString
collection</secondary>-->The number of elements in the
collection.</p></dd>

</dl>




<p>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:</p>




<span class="PROGRAMLISTING"><pre>strFirstName = Request.QueryString("FirstName")</pre></span>




<p>is only an abbreviated form of:</p>




<span class="PROGRAMLISTING"><pre>strFirstName = Request.QueryString.Item("FirstName")</pre></span>




<tip id="ch07-32-fm2xml" role="ora">
<p>For more information on the Item, Key, and Count properties of a
collection, see the discussion in the <link linkend="ch04-3-fm2xml">Section 4.2</link> in <link linkend="ch04-40130">Chapter 4</link>.</p>



</tip>
</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<span class="PROGRAMLISTING"><pre>&lt;% 
' 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
%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>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:</p>




<span class="PROGRAMLISTING"><pre>&lt;FORM NAME = "frmInfo" ACTION="UserInfo2.ASP" 
      METHOD = "GET"&gt;
Below, select all the peripherals you have: 
&lt;INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE = 
   "Joystick"&gt;Joystick&lt;BR&gt;
&lt;INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE=
   "GraphicsAccel"&gt;3D Graphics Card&lt;BR&gt;
&lt;/FORM&gt;</pre></span>




<p>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:</p>




<span class="PROGRAMLISTING"><pre>UserInfo2.ASP?chkPeriph=Joystick&amp;chkPeriph=GraphicsAccel</pre></span>




<p>To refer to the first element, you could use the following code (note
that like other ASP collections, the elements start at 1):</p>




<span class="PROGRAMLISTING"><pre>strFirstOption = Request.QueryString("chkPeriph")(1)</pre></span>




<p>If you do not specify a subkey, as in:</p>




<span class="PROGRAMLISTING"><pre>strOptions = Request.QueryString("chkPeriph")</pre></span>




<p>then <var class="replaceable">strOptions</var> would have the following
value:</p>




<span class="PROGRAMLISTING"><pre>Joystick, GraphicsAccel</pre></span>




<p>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 <span class="LITERAL">Get</span> method.</p>




<p><!--<primary>size</primary><secondary>QueryString collection
length limit</secondary>--> <!--<primary>QueryString
collection (Request)</primary><secondary>length
limit</secondary>--> <!--<primary>comments and
troubleshooting</primary><secondary>QueryString collection
length</secondary>-->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 the 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.</p>




<p>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
<!--<primary>Count property</primary><secondary>QueryString
collection</secondary>-->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.</p>




<p>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 comma-delimited string containing only the values
from the element being addressed.</p>




<p>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.</p>




<p>The data in the QueryString collection is also accessible from the
ServerVariables collection of the Request object, using the
<span class="LITERAL">HTTP_QUERYSTRING</span><!--<primary>HTTP_QUERYSTRING
parameter</primary>--> <!--<primary>ServerVariables
collection (Request)</primary><secondary>accessing QueryString
collection data</secondary>-->
<!--<primary>QueryString collection
(Request)</primary><secondary>accessing data with
ServerVariables</secondary>--> parameter. This is covered in
more depth in the section on the ServerVariables collection.</p>




<p>Finally, note that you must encode several special characters when
used in the QueryString:</p>




<dl>
<dt><span class="LITERAL">&amp;</span></dt>
<dd><p>The ampersand is used by ASP to delineate separate parameter/value
pairs that have been added to the QueryString collection.</p></dd>




<dt><span class="LITERAL">?</span></dt>
<dd><p>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.</p></dd>




<dt><span class="LITERAL">%</span></dt>
<dd><p>The percentage symbol is used in the encoding of other special
characters.</p></dd>




<dt><span class="LITERAL">+</span></dt>
<dd><p>The plus sign is recognized in the QueryString as representing a
space.</p></dd>

</dl>




<p>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. </p>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="ServerVariables">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
ServerVariables</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><span class="PROGRAMLISTING"><pre>strKeyName = Request.ServerVariables.Key(3)
strKeyValue = Request.ServerVariables.Item(strKeyName)</pre></span></td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p>The <!--<primary>ServerVariables collection
(Request)</primary>--> <!--<primary>web
servers</primary><secondary>environment variables
for</secondary>--> <!--<primary>environment
variables</primary><secondary sortas="web servers">for web
servers</secondary>--> <!--<primary>variables</primary><secondary>web
server environment</secondary>-->ServerVariables collection
contains several predefined environment variables in the context of
the client's specific HTTP request of the web server.</p>




<p>The ServerVariables collection, like the other ASP collections, has
the following properties:</p>




<dl>
<dt>Item</dt>
<dd><p><!--<primary>Item property</primary><secondary>ServerVariables
collection</secondary>-->The value of a specific element in
the collection. To specify an item, you can use an index number or a
key.</p></dd>




<dt>Key</dt>
<dd><p><!--<primary>Key property</primary><secondary>ServerVariables
collection</secondary>-->Returns the name of a specific
element in the ServerVariables collection. Just as each
element's value is represented by the Item property, each
element's name is represented by its Key property.</p>




<p>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 element's value. You could use the following
code:</p>




<span class="PROGRAMLISTING"><pre>strKeyName = Request.ServerVariables.Key(3)
strKeyValue = Request.ServerVariables.Item(strKeyName)</pre></span>




<p>If, on the other hand, you know that the third element's key
name is "QUERY_STRING," you could simply use the
following code to retrieve the value of that element:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = _
          Request.ServerVariables.Item("QUERY_STRING")</pre></span>




<p>Or, simply:</p>




<span class="PROGRAMLISTING"><pre>strKeyValue = Request.ServerVariables("QUERY_STRING")</pre></span></dd>




<dt>Count</dt>
<dd><p><!--<primary>Count
property</primary><secondary>ServerVariables
collection</secondary>-->The number of elements in the
collection.</p></dd>

</dl>




<p>As with other ASP collections, you can retrieve the value of any
field of the ServerVariables collection through the use of the Item
property. Note that in the following examples and explanations (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:</p>




<span class="PROGRAMLISTING"><pre>strRemoteAddr = Request.ServerVariables("REMOTE_ADDR")</pre></span>




<p>is only an abbreviated form of:</p>




<span class="PROGRAMLISTING"><pre>strRemoteAddr = Request.ServerVariables.Item("REMOTE_ADDR")</pre></span>




<tip id="ch07-36-fm2xml" role="ora">
<p>For more information on the Item, Key, and Count properties of a
collection, see the discussion in <link linkend="ch04-3-fm2xml">Section 4.2</link> in <link linkend="ch04-40130">Chapter 4</link>.</p>



</tip>

<p>The possible values for <var class="replaceable">Key</var> are in the
following list. Although they typically appear in uppercase,
<var class="replaceable">Key</var> 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.</p>



<!--<primary>ALL_HTTP element (ServerVariables)</primary>-->
<dl>
<dt>ALL_HTTP</dt>
<dd><p><!--<primary>headers,
HTTP</primary><secondary>ServerVariables elements
for</secondary>--> <!--<primary>HTTP (Hypertext Transfer
Protocol)</primary><secondary>ServerVariables elements for
headers</secondary>-->One long string containing all the
HTTP headers sent by the client's browser. Each of the
following elements can be parsed from this element.</p></dd>




<dt>ALL_RAW</dt>
<dd><p><!--<primary>ALL_RAW element
(ServerVariables)</primary>-->One long string containing all
the HTTP headers in their original state as sent by the client
browser. The primary difference between the
<span class="LITERAL">ALL_RAW</span> and the <span class="LITERAL">ALL_HTTP</span> values
is that the values of the <span class="LITERAL">ALL_HTTP</span> element are all
prefixed with <span class="LITERAL">HTTP_</span> and the header name is always
capitalized. Each of the following elements can be parsed from this
element.</p></dd>



<!--<primary>APPL_MD_PATH element (ServerVariables)</primary>-->
<dt>APPL_MD_PATH</dt>
<dd><p>Internally, the IIS <!--<primary>metabase,
IIS</primary>--> <!--<primary>IIS
metabase</primary>-->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.</p>




<p>The <span class="LITERAL">APPL_MD_PATH</span> element of the ServerVariables
collection represents the metabase-specific path for the
<!--<primary>ISAPI DLL, metabase-specific path
for</primary>-->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:</p>




<span class="PROGRAMLISTING"><pre>/LM/W3SVC/1/ROOT</pre></span></dd>




<dt>APPL_PHYSICAL_PATH</dt>
<dd><p><!--<primary>APPL_PHYSICAL_PATH element
(ServerVariables)</primary>-->The physical path of the
<span class="LITERAL">APPL_MD_PATH</span> element. This value is retrieved from
the conversion of <span class="LITERAL">APPL_MD_PATH</span> by IIS. For
example, on my system this translates to
<span class="LITERAL">C:\Inetpub\wwwroot\</span>.</p></dd>




<dt>AUTH_PASSWORD</dt>
<dd><p><!--<primary>AUTH_PASSWORD element
(ServerVariables)</primary>-->If IIS security is set to
Basic Authentication, <span class="LITERAL">AUTH_PASSWORD</span> represents the
<!--<primary>password for authentication</primary>-->
<!--<primary>authentication information in HTTP
request</primary>-->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.</p></dd>




<dt>AUTH_TYPE</dt>
<dd><p><!--<primary>AUTH_TYPE element
(ServerVariables)</primary>-->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.</p></dd>




<dt>AUTH_USER</dt>
<dd><p><!--<primary>AUTH_USER element
(ServerVariables)</primary>-->The raw username entered upon
authentication of the client by the web server.</p></dd>




<dt>CERT_COOKIE</dt>
<dd><p><!--<primary>CERT_COOKIE element
(ServerVariables)</primary>--> <!--<primary>digital
certificates</primary><secondary>information in HTTP
requests</secondary>-->A unique ID for the client's
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
<!--<primary>ClientCertificate collection
(Request)</primary>-->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 <span class="LITERAL">CERT_</span> elements still exist in
the ServerVariables collection, but they are empty (i.e., they have
no value).</p></dd>




<dt>CERT_FLAGS</dt>
<dd><p><!--<primary>CERT_FLAGS element
(ServerVariables)</primary>--><span class="LITERAL">CERT_FLAGS</span>
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
certificate's 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
<span class="LITERAL">ceCertPresent</span> and
<span class="LITERAL">ceUnrecognizedIssuer</span> constants for the Flags
element of the ClientCertificate collection.</p></dd>




<dt>CERT_ISSUER</dt>
<dd><p><!--<primary>CERT_ISSUER element
(ServerVariables)</primary>-->The
<!--<primary>digital certificates</primary><secondary>issuer
information</secondary>-->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.</p></dd>




<dt>CERT_KEYSIZE</dt>
<dd><p><!--<primary>CERT_KEYSIZE element
(ServerVariables)</primary>-->The number of bits used in the
Secure Sockets Layer connection key size (for example, 64 or 128).</p></dd>




<dt>CERT_SECRETKEYSIZE</dt>
<dd><p><!--<primary>CERT_SECRETKEYSIZE element
(ServerVariables)</primary>-->The number of bits in the
secret server certificate private key (for example, 1024).</p></dd>




<dt>CERT_SERIALNUMBER</dt>
<dd><p><!--<primary>CERT_SERIALNUMBER element
(ServerVariables)</primary>-->The value of the
client's certificate serial number.</p></dd>




<dt>CERT_SERVER_ISSUER</dt>
<dd><p><!--<primary>CERT_SERVER_ISSUER element
(ServerVariables)</primary>-->The issuer of the server
certificate.</p></dd>




<dt>CERT_SERVER_SUBJECT</dt>
<dd><p><!--<primary>CERT_SERVER_SUBJECT element
(ServerVariables)</primary>-->The subject field of the
server certificate. Like the Subject field of the client certificate,
this element's value is a comma-delimited string containing the
subfields described in the Subject element section of the
ClientCertificate collection description.</p></dd>




<dt>CERT_SUBJECT</dt>
<dd><p><!--<primary>CERT_SUBJECT element
(ServerVariables)</primary>-->The subject field of the
client certificate. This element's value is a comma-delimited
string containing the subfields described in the Subject element
section of the ClientCertificate collection description.</p></dd>




<dt>CONTENT_LENGTH</dt>
<dd><p><!--<primary>CONTENT_LENGTH element
(ServerVariables)</primary>-->
<!--<primary>size</primary><secondary>HTTP
requests</secondary>-->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 client's
HTTP request. This value does not include the length of any data
presented through the request header (i.e., information sent with a
<span class="LITERAL">GET</span> method), only that information in the request
body.</p></dd>




<dt>CONTENT_TYPE</dt>
<dd><p><!--<primary>CONTENT_TYPE element
(ServerVariables)</primary>-->This is the
<!--<primary>MIME type</primary>-->MIME type of the
content sent by the client. When used with HTTP queries that contain
attached information (such as HTTP <span class="LITERAL">GET</span>,
<span class="LITERAL">POST</span>, and <span class="LITERAL">PUT</span> actions), this
can allow you to determine the data type of the client's HTTP
request content data. The most common value for this element is
<span class="LITERAL">application/x-www-form-urlencoded</span>. If you were to
include a file element in your HTML form, you would set the
<!--<primary>ENCTYPE parameter</primary>-->ENCTYPE
parameter (and thus the CONTENT_TYPE header in your request) to
<span class="LITERAL">multipart/form-data</span>.</p></dd>




<dt>GATEWAY_INTERFACE</dt>
<dd><p><!--<primary>GATEWAY_INTERFACE element
(ServerVariables)</primary>-->The revision of the
<!--<primary>Common Gateway Interface
(CGI)</primary><secondary>version used by web
server</secondary>--> <!--<primary>CGI
applications</primary><secondary>version used by web
server</secondary>-->Common Gateway Interface that is used
by the web server. This string value is in the format
<span class="LITERAL">CGI/</span><var class="replaceable">revision</var>
<var class="replaceable">#</var>. For example, if you were connected to
an IIS 4.0 web server, the value of this item would be CGI/1.1.</p></dd>




<dt>HTTP_ [<var class="replaceable">HeaderName</var>]</dt>
<dd><p><!--<primary>HTTP_... elements
(ServerVariables)</primary>-->The value sent in the HTTP
header called <var class="replaceable">headername</var>. 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:</p>




<ul>

<li>HTTP_ACCEPT</li>

<li>HTTP_AUTHORIZATION (same as the AUTH_TYPE element)</li>

<li>HTTP_ACCEPT-LANGUAGE</li>

<li>HTTP_CONNECTION</li>

<li>HTTP_HOST</li>

<li>HTTP_REFERER</li>

<li>HTTP_USER-AGENT </li>

</ul>



<p>requires code resembling the following to receive its value:</p>




<span class="PROGRAMLISTING"><pre>strUserAgent = _
         Request.ServerVariables("HTTP_USER_AGENT")
</pre></span>
</dd>





<dt>HTTPS</dt>
<dd><p><!--<primary>HTTPS element
(ServerVariables)</primary>-->This element's value is
the string "ON" if the client's HTTP request was
sent using SSL. It is "OFF" otherwise.</p></dd>




<dt>HTTPS_KEYSIZE</dt>
<dd><p><!--<primary>HTTPS_KEYSIZE element
(ServerVariables)</primary>-->The same as
<span class="LITERAL">CERT_KEYSIZE</span> described earlier.</p></dd>




<dt>HTTPS_SECRETKEYSIZE</dt>
<dd><p><!--<primary>HTTPS_SECRETKEYSIZE element
(ServerVariables)</primary>-->The same as
<span class="LITERAL">CERT_SECRETKEYSIZE</span> described earlier.</p></dd>




<dt>HTTPS_SERVER_ISSUER</dt>
<dd><p><!--<primary>HTTPS_SERVER_ISSUER element
(ServerVariables)</primary>-->The same as
<span class="LITERAL">CERT_SERVER_ISSUER</span> described earlier.</p></dd>




<dt>HTTPS_SERVER_SUBJECT</dt>
<dd><p><!--<primary>HTTPS_SERVER_SUBJECT element
(ServerVariables)</primary>-->The same as
<span class="LITERAL">CERT_SERVER_SUBJECT</span> described earlier.</p></dd>




<dt>INSTANCE_ID</dt>
<dd><p><!--<primary>INSTANCE_ID element
(ServerVariables)</primary>-->The ID of the current IIS
instance specified in textual format. If this element evaluates to 1,
then the value is a string. The <span class="LITERAL">INSTANCE_ID</span>
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.</p></dd>




<dt>INSTANCE_META_PATH</dt>
<dd><p><!--<primary>INSTANCE_META_PATH element
(ServerVariables)</primary>-->The path in the
<!--<primary>metabase, IIS</primary>-->
<!--<primary>IIS metabase</primary>-->metabase for
the instance of IIS to which the client's HTTP request is sent.
As discussed in the earlier section on the
<span class="LITERAL">APPL_MD_PATH</span> 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
<span class="LITERAL">/LM/W3SVC/1</span>.</p></dd>




<dt>LOCAL_ADDR</dt>
<dd><p><!--<primary>LOCAL_ADDR element
(ServerVariables)</primary>-->The TCP/IP address of the
<!--<primary>web servers</primary><secondary>TCP/IP address
for</secondary>--> <!--<primary>TCP/IP address for
web servers</primary>--> <!--<primary>IP
address</primary><secondary>server accepting
requests</secondary>-->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
<em>localhost</em>, its value is
127.0.0.1.</p></dd>




<dt>LOGON_USER</dt>
<dd><p><!--<primary>LOGON_USER element
(ServerVariables)</primary>-->The Windows NT
<!--<primary>user account
information</primary>-->user account with which the user has
logged onto the system if security is set to basic or Windows NT
challenge/response. For anonymous security, it returns an empty
string.</p></dd>




<dt>PATH_INFO</dt>
<dd><p><!--<primary>PATH_INFO element
(ServerVariables)</primary>-->The virtual path of the
<!--<primary>web pages</primary><secondary>determining paths
for</secondary>--> <!--<primary>virtual
paths</primary><secondary>determining for web
pages</secondary>-->
<!--<primary>paths</primary><secondary>determining for web
pages</secondary>-->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.</p></dd>




<dt>PATH_TRANSLATED</dt>
<dd><p><!--<primary>PATH_TRANSLATED element
(ServerVariables)</primary>-->The virtual-to-physical
mapping of the value of the <span class="LITERAL">PATH_INFO</span> element of
the ServerVariables collection.</p></dd>




<dt>QUERY_STRING</dt>
<dd><p><!--<primary>QUERY_STRING element
(ServerVariables)</primary>-->The values sent by the client
after the question mark (<span class="LITERAL">?</span>) at the end of the HTTP
request URL. This element also contains the information sent to the
web server using the HTTP <span class="LITERAL">GET</span> method. All the
information in this element is also available via the
<!--<primary>QueryString collection
(Request)</primary>-->QueryString collection (which is
easier to utilize, as it does not require parsing).</p></dd>




<dt>REMOTE_ADDR</dt>
<dd><p><!--<primary>REMOTE_ATTR element
(ServerVariables)</primary>-->The TCP/IP address of the
client.</p></dd>




<dt>REMOTE_HOST</dt>
<dd><p><!--<primary>REMOTE_HOST element
(ServerVariables)</primary>-->The <!--<primary>IP
address</primary><secondary>server making
requests</secondary>-->IP address from which the web server
receives the client's HTTP request. If the HTTP request does
not include this information, the <span class="LITERAL">REMOTE_ADDR</span>
element's value will be set and this value will be empty.</p></dd>




<dt>REQUEST_METHOD</dt>
<dd><p><!--<primary>REQUEST_METHOD element
(ServerVariables)</primary>-->The method by which the client
made the HTTP request (<span class="LITERAL">GET</span>,
<span class="LITERAL">POST</span>, <span class="LITERAL">HEAD</span>, etc.).</p></dd>




<dt>SCRIPT_NAME</dt>
<dd><p><!--<primary>SCRIPT_NAME element
(ServerVariables)</primary>-->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 ServerVariables
collection. It is used (largely internally) for self-referencing
URLs. This is equivalent to the value of the
<span class="LITERAL">PATH_INFO</span> element.</p></dd>




<dt>SERVER_NAME</dt>
<dd><p><!--<primary>SERVER_NAME element
(ServerVariables)</primary>-->The web server's TCP/IP
address, its DNS or hostname as it would appear in a self-referencing
URL.</p></dd>




<dt>SERVER_PORT</dt>
<dd><p><!--<primary>SERVER_PORT element
(ServerVariables)</primary>-->The server
<!--<primary>port, web server</primary>-->port to
which the client's HTTP request is sent. This is typically 80
or 8080 for most web servers.</p></dd>




<dt>SERVER_PORT_SECURE</dt>
<dd><p><!--<primary>SERVER_PORT_SECURE element
(ServerVariables)</primary>-->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.<!--<primary>security</primary><secondary>identifying secure
ports</secondary>--></p></dd>




<dt>SERVER_PROTOCOL</dt>
<dd><p><!--<primary>SERVER_PROTOCOL element
(ServerVariables)</primary>-->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."</p></dd>




<dt>SERVER_SOFTWARE</dt>
<dd><p><!--<primary>SERVER_SOFTWARE element
(ServerVariables)</primary>-->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.</p></dd>




<dt>URL</dt>
<dd><p><!--<primary>URL element
(ServerVariables)</primary>-->The base URL requested by the
client in its HTTP request.</p></dd>

</dl>



</td>
</tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td></tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<span class="PROGRAMLISTING"><pre>&lt;% 

' 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")

%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>As the list earlier in this section illustrates, the ServerVariables
collection contains many very useful pieces of information regarding
the client's 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.</p>




<p>Also, many of the Request object's other collections'
data can be obtained through the ServerVariables collection (usually
with more effort,    however).</p>



</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
<div id="BinaryRead">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME">
BinaryRead</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2"><var class="replaceable">MySafeArray</var><span class="LITERAL">=Request.BinaryRead(</span><var class="replaceable">ByteCount</var>)
</td></tr>
<tr><td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr><td colspan="2" class="description">
<p><!--<primary>Request
object</primary><secondary>BinaryRead method</secondary>-->
<!--<primary>BinaryRead method
(Request)</primary>--> <!--<primary>requests,
HTTP</primary><secondary>reading bytes from</secondary>-->
<!--<primary>HTTP
(Hypertext Transfer
Protocol)</primary><secondary>requests</secondary><tertiary>reading
bytes from</tertiary>--> <!--<primary>reading</primary><secondary sortas="HTTP requests">from HTTP requests</secondary>-->The
BinaryRead method reads a number of bytes directly from the HTTP
request body sent by the client as part of an HTTP
<span class="LITERAL">Post</span>. The data read from an HTTP request using the
BinaryRead method is returned into a SafeArray. A
<em>SafeArray</em><!--<primary>SafeArray
variant</primary>--> 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.</p>




<tip id="ch07-41-fm2xml" role="ora">
<p>In actuality, a SafeArray is not an array at all. It's 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.</p>



</tip>
</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Parameters</td>
</tr>
<tr>
<td colspan="2" class="description">




<dl>
<dt><var class="replaceable">MySafeArray</var></dt>
<dd><p>The name of a SafeArray used to store the information returned from a
BinaryRead.</p></dd>




<dt><var class="replaceable">ByteCount</var></dt>
<dd><p>The number of bytes read using the BinaryRead method. Typically, this
variable's value evaluates to the number of bytes returned
using the TotalBytes property of the Request object described
previously.</p></dd>

</dl>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description">




<span class="PROGRAMLISTING"><pre>&lt;% 

' 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 <link linkend="ch08-1-fm2xml">Chapter 8</link>.
   ' For now, suffice it to say the following code sends
   ' information to the client.
   Response.Clear
   Response.Write lngTotalByteCount &amp; _
                  " bytes successfully read.&lt;BR&gt;"
   Response.End
End If 

%&gt;</pre></span>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Notes</td>
</tr>
<tr>
<td colspan="2" class="description">




<p>If your web application's 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 <span class="LITERAL">Post</span> 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.</p>




<p>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.  </p>




</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
</table>
</div>
</body>
</html>