Using HTTP Headers

Overview of HTTP Headers in Stored Processes

Stored process streaming output is always accompanied by an HTTP header. The HTTP header consists of one or more header records that identify the content type of the output and can provide other information such as encoding, caching, and expiration directives. A streaming stored process client can use or ignore the HTTP header. The SAS Stored Process Web Application forwards the HTTP client to the Web browser (or other HTTP client).
HTTP headers are defined by the HTTP protocol specification (RFC 2616), which can be found at http://www.w3.org. Each header record is a single text line consisting of a name and a value separated by a colon (:). The following example shows records in an HTTP header:
 Content-type: text/html; encoding=utf-8
 Expires: Wed, 03 Nov 2004 00:00:00 GMT
 Pragma: nocache
You can set any HTTP record for your stored process output by calling the STPSRV_HEADER function. For more information, see STPSRV_HEADER Function. Typically, you must call STPSRV_HEADER before the %STPBEGIN statement. The following DATA step function calls generate the previous example header records:
 old = stpsrv_header("Content-type", 
 "text/html; encoding=utf-8");
 old = stpsrv_header("Expires", 
 "Wed, 03 Nov 2004 00:00:00 GMT");
 old = stpsrv_header("Pragma", "nocache");
You can also call this function directly from SAS macro code outside a DATA step. Note that string parameters are not enclosed in quotation marks, and macro characters such as semicolon (;) must be masked in this case:
 %let old = %sysfunc(stpsrv_header(Content-type, 
 text/html%str(;) encoding=utf-8);
 %let old = %sysfunc(stpsrv_header(Expires, 
 Wed, 03 Nov 2004 00:00:00 GMT));
 %let old = %sysfunc(stpsrv_header(Pragma, nocache));
Headers must be set before _WEBOUT is opened. There are several ways that _WEBOUT can be opened. Here are some examples:
  • data _null_;
    file _webout;
    ...;
    run;
  • %STPBEGIN; *  if the stored process creates streaming output;
  • ods html body=_webout ... ;

Commonly Used Headers

The following are a few commonly used HTTP header records:
  • Content-type
  • Expires
  • Location
  • Pragma
  • Set-Cookie
  • Status-Code

Content-type

The Content-type header record is generated automatically. The value is set based on the ODS destination that you use in your stored process. The value is determined by looking up the ODS destination in the file types section of the SAS registry and, if appropriate, the Windows registry. If you do not use ODS to generate the output, then Content-type defaults to text/html. Use the STPSRV_HEADER function if you want to override the default value. Override the value of Content-type when you want to do any of the following:
  • specify the encoding of the data. This might be important in Web applications where the client (typically a Web browser) might expect a different encoding than the stored process output. Examples:
    Content-type: text/xml; encoding=utf-8
     Content-type: text/plain; encoding=iso-8859-1
     Content-type: text/html; encoding=windows-1252
  • direct the output to a specific content handler. For example, HTML output can be directed to Microsoft Excel (in later versions of Microsoft Office) by setting the Content-type to application/vnd.ms-excel.
  • override the default text/html value. Overriding this value typically occurs if you are using ODS custom tagsets or you are not using ODS at all to generate the output.
The following table shows commonly used Content-type values.
Content Types
Content-type
Description
application/octet-stream
Unformatted binary data.
image/gif
GIF (Graphics Interchange Format) images.
image/jpeg
JPEG (Joint Photographic Expert Group) format images.
image/png
PNG (Portable Network Graphics) format images.
text/html
HTML (Hypertext Markup Language).
text/plain
Plain unformatted text.
text/xml
XML (eXtensible Markup Language).
text/x-comma-separated-values
Spreadsheet data.
Content-type values are also known as MIME types. For a list of all official MIME types, see the IANA registry at http://www.iana.org/assignments/media-types/. An unregistered MIME type or subtype can be used; the value should be preceded by x-.

Expires

Web clients frequently cache HTML and other content. Accessing the same URL might return the cached content instead of causing the output to be regenerated by the server. Accessing the cached content is often desirable and reduces server and network loads, but can lead to unexpected or stale data. The Expires header record enables you to control how long a Web client caches the content.
The Expires header record requires that the expiration time be specified in Greenwich Mean Time (GMT) and in a particular format. A SAS picture format can be used to create this value. Use PROC FORMAT to create a custom format as shown in the following example:
 proc format;
 picture httptime (default=29)
 other='%a, %0d %b %Y %0H:%0M:%0S GMT' 
 (datatype=datetime);
 run;
This format can be created one time and saved in a global format library, or you can create it dynamically as needed in your stored process. The format generates a date in this form:
 Sun, 24 AUG 2003 17:13:23 GMT
DATA step functions can then be used to set the desired expiration time, adjust to GMT, and format, as shown in the following examples:
 /* Expire this page in six hours */
 data _null_;
 exptime = datetime() + '6:00:00't;
 old = stpsrv_header('Expires', 
 put(exptime - gmtoff(), httptime. ));
 run;
 /* Expire this page at the beginning of next 
 week (Sunday, 00:00 local time) */
 data _null_;
 exptime = intnx('dtweek', datetime(), 1);
 old = stpsrv_header('Expires', 
 put(exptime - gmtoff(), httptime. ));
 run;
Specifying an expiration time in the past causes caching to be disabled for your output. It is recommended that you also use the Pragma header record in this case. For more information, see Pragma. Specify an expiration time far in the future if you want your content to be cached indefinitely.

Location

The Location header record is unlike other header records. It redirects the Web client immediately to a different URL. Generally all other header records and content are ignored when this header record is used. Use this header to redirect the client to another location for special conditions. For example, a stored process might redirect a client to a Help URL if an invalid input or other error condition is detected. For example, the following stored process redirects the Web client to a static Help page when an error condition is detected:
 %macro doSomething;

 ...

 %if error-condition %then %do;
 %let old = %sysfunc(stpsrv_header(Status-Code,300));
 %let old = %sysfunc(stpsrv_header(Location, 
 http://myserv.abc.com/myapp/help.html));
 %goto end_processing;
 %end;

 ... normal processing ...

 %end_processing:
 %mend;

 %doSomething;
The URL that is specified in the Location header is not limited to a static URL. It might be a SAS Stored Process Web Application or JSP URL, and it might contain parameters. In the preceding example, the erroneous request, complete with input parameters, can be redirected to an error handling stored process. The error handling stored process can examine the input parameters and generate specific error messages and context-sensitive Help. This is one method to avoid replicating error handling or Help material across multiple stored processes.
Note: The Status-Code header must be used to set the HTTP status before the Location header can be used.

Pragma

The Pragma header record is used to specify information not formally defined in the HTTP specification. The most commonly used value is nocache. This value disables Web client caching of content for most Web browsers. Some Web browsers require that other headers be set in order to prevent caching. For example:
old = stpsrv_header('Expires','Thu, 18 Nov 1999 12:23:34 GMT');  
old = stpsrv_header('Cache-Control','no-cache,no-store');
old = stpsrv_header('Pragma','no-cache');

Set-Cookie

The Set-Cookie header record sends a cookie to the Web client to maintain client-side state. Here is the format:
 Set-Cookie: name=value; name2=
 value2; ...; expires=date;
 path=path; domain=domain_name; secure
where EXPIRES, PATH, DOMAIN, and SECURE are all optional. The date must be specified in the HTTP GMT format that is described in Expires.
For example:
 old = stpsrv_header("Set-Cookie",
 "CUSTOMER=WILE_E_COYOTE; path=/SASStoredProcess/do; " ||
 "expires=Wed, 06 Nov 2002 23:12:40 GMT");
The next time your application is run, any matching cookies are returned in the _HTCOOK environment variable, assuming that this variable has been enabled in your SAS Stored Process Web Application environment. You must parse the cookie string to retrieve the information that you saved in the cookie. Use the scan DATA step function to split the name/value pairs on the semicolon (;) delimiters. Then split the name/value pairs on the equal sign (=) delimiter.
Most Web browsers support cookies, but some users disable them due to privacy concerns, site policies, or other issues. If you use cookies, explain to your users why you need them and if they must be enabled in order to use your application. Some Web clients might not support cookies at all.

Status-Code

The Status-Code header record is used by Web applications to set the HTTP status for every page that is returned to the Web browser. For information about status code definitions, see http://www.w3.org.