HTTP Headers

What Are HTTP Headers?

All output that is created by Application Dispatcher programs must contain an abbreviated HTTP header. This header is everything from the beginning of the output up to the first null line. Here is some example output, including the header:
Content-type: text/html
Pragma: nocache
<HTML>
<HEAD><TITLE>Application Server Administrative Program</TITLE></HEAD>
<BODY>
<H1>Administrative Program</H1>
<P>The application server has been shut down.</P>
<HR>
</BODY>
</HTML>
In this example, the HTTP header contains two lines. The minimal requirements for Application Dispatcher output are that the header contain Content-type or Location. The null line that terminates the HTTP header is important. You can create the null line with a PUT statement:
put ;
This, however, is incorrect because it produces a line containing one blank followed by carriage control:
put " ";
A line with one blank is not a null line and is not recognized as terminating the header.
The output that follows the HTTP header depends on the content type. If Location is used, then no output follows the header because this header triggers the Web browser to redirect to another page. The most common type of output is, of course, HTML. The HTML source for the Web page follows the header when the content type is text/html.
No matter whether the program output is plain text, binary graphics, HTML code, or any other content type, all output intended for the Web browser should be sent to the fileref _WEBOUT. This special fileref is actually a TCP/IP socket connection to the Application Broker. Sending output to this socket streams it back to the Web browser. The socket is like a pipe through which data flows. Because it behaves in this way, the fileref _WEBOUT is in a permanent append mode. It is not possible to write something to _WEBOUT and then reopen the fileref and overwrite the previous output. It all gets appended. Therefore, the mod parameter should not be used (and is not allowed) in any FILE _WEBOUT statements. Before Version 7 of SAS, an additional fileref _GRPHOUT was necessary on z/OS systems because of translation issues from EBCDIC to ASCII. The two filerefs _GRPHOUT and _WEBOUT were synonyms on all hosts except for z/OS under Version 6 of SAS. In SAS, Version 7 and later, these two filerefs are synonyms for all platforms including z/OS. Though no longer needed, the fileref _GRPHOUT is still present for compatibility reasons.

Automatic Header Generation

Using Automatic Header Generation

Starting with Version 8.1, the Application Server provides Automatic Header Generation. The default header is Content-type: text/html.
To add a header to the default header list or to modify a header already in the list, use the DATA step function APPSRV_HEADER.
The Application Server detects whether the user application is writing its own headers. Preexisting applications that write their own headers continue to work as before. New applications that do not write output headers have default headers generated for them.
Applications that want to use the default headers but also want to modify them or add to them can use the APPSRV_HEADER DATA step function. For example,
old = appsrv_header('Header name', 'Header value');
Calls to the APPSRV_HEADER function adds headers to the list of default headers when the header name does not already exist in the list of default headers. In this case, the return value of the function call is an empty string.
If the header name passed into the APPSRV_HEADER function already exists in the list of default headers, the header value of the existing header is replaced with the new value passed in, and the old value of the header is returned as the return value of the function. If the header value passed in is an empty string, then the header is removed from the list of default headers. The old value of the header is returned as the return value of the function.

Example

With default headers of Content-type: text/html, the following calls to the APPSRV_HEADER function modify the default headers as shown:
rc = appsrv_header('Expires','Thu, 18 Nov 1999 12:23:34 GMT');
results in
  • Content-type: text/html
  • Expires: Thu, 18 Nov 1999 12:23:34 GMT
rc = appsrv_header('Pragma','nocache');
results in
  • Content-type: text/html
  • Expires: Thu, 18 Nov 1999 12:23:34 GMT
  • Pragma: nocache
rc = appsrv_header('Expires','');
results in
  • Content-type: text/html
  • Pragma: nocache
rc = appsrv_header('Pragma','nocache');
results in
  • Content-type: text/html
  • Pragma: nocache

Disabling Automatic Header Generation

To disable Automatic Header Generation completely for a request, call the APPSRVSET DATA step function, as follows:
data _NULL_;
rc = appsrvset("automatic headers", 0);
run;

HTTP Output Reference

All Application Dispatcher output must be in the format of an HTTP header that is followed by a blank line and optional data. This section provides introductory technical information about the most common headers. For detailed information about HTTP, see W3C's HTTP Protocol Area at www.w3.org/Protocols.

Content-type

The most basic HTTP header that you can send is the Content-type header, for example:
Content-type: text/html
If you use ODS to generate content that is not HTML, then the header is defined based on information from the SAS registry or the Windows registry. For example, if you use ODS PDF to generate content, the header looks like
Content-type: Application/PDF
This informs the Web browser what type of output follows by specifying it the Internet Media type (also called MIME type). An unregistered MIME type can be used; just precede it with x-. Some of the more important types are listed in the table below.
Content-type
Description
application/octet-stream
Unformatted binary data.
image/gif
Image in the GIF (Graphics Interchange Format) format.
image/jpeg
Image in the JPEG (Joint Photographic Expert Group) format.
text/html
Regular HTML (Hypertext Markup Language).
text/plain
Preformatted text.
text/x-comma-separated-values
Spreadsheet data.
multipart/x-mixed-replace
Differently formatted blocks of data (used for Netscape server push).

Expires

Sometimes Web browsers cache results when you intend for the Application Dispatcher to be reinvoked, and sometimes they reinvoke when it is unnecessary. Setting the Expires header gives you control over these conditions by specifying the date/time after which the response should be considered stale, for example:
Expires: Thu, 01 Dec 1994 16:00:00 GMT
To mark a response as already expired, use an Expires date that is equal to or earlier than the current date. To mark a response as never expires, use an Expires date approximately one year or more from the time the response is sent. The date format should be followed exactly as given above.

Location

The Location header redirects the Web browser immediately to a different URL. Use this as an alternative to the Content-type header. There is no data after a header containing Location: but you still need the blank line at the end.
Location: http://support.sas.com
Note: When setting the Location header, you must also set the Status header.

Pragma

This header informs the Web browser and proxy servers to not cache the results of your program. It is similar to using the Expires header with a date in the past but might be somewhat better supported, for example:
Pragma: nocache

Set-Cookie

The header sends a cookie to the Web browser to maintain the client-side state. The format is
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
For example:
Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/cgi-bin/broker;
expires=Wednesday, 09-Nov-1999 23:12:40 GMT
The next time your application is run, any matching cookies are returned in HTTP_COOKIE environment variable (use Export directive to pass to application). You must parse them out in order to retrieve the information that you save. The names and values can be anything you like, but you must devise a method to encode special characters such as the equal sign (=) and the semicolon (;). The date format should be followed exactly as above, with only the GMT time zone allowed, and hyphens between the day, month, and year (this is different from Expires).
Most new Web browsers support cookies, but studies show that approximately 10% of users disable or disallow them. Some users are concerned about the privacy considerations of using cookies. If you use cookies, be sure to explain to your users why you need them and that they should let them pass through.