Working with HTTP headers

Server side

When creating HTTP web service client procedures, use this clause to add, modify, or delete HTTP request header entries. The specification of headers closely resembles the format specified in RFC2616 Hypertext Transfer Protocol — HTTP/1.1, and RFC822 Standard for ARPA Internet Text Messages, including the fact that only printable ASCII characters can be specified for HTTP headers, and they are case-insensitive. Following are a few key points regarding HTTP header specification:

  • Header/value pairs can be delimited by \n or \x0d\n, specifying Line Feed (<LF>), or Carriage Return and Line Feed(<CR><LF>), respectively.

  • A header is delimited from its value using a colon (:), and therefore cannot contain a colon.

  • A header followed by :\n, or an end of line, specifies a header with no value, as does a header with no colon or value after it. For example, HEADER 'Date', specifies that the Date header should not be included. Suppressing headers, or their values, can cause unexpected results. See Modifying HTTP headers.

  • Folding of long header values is supported, provided one or more white spaces immediately follow the \n. For example, the following HEADER specification, and resulting HTTP output, are semantically equivalent:

    HEADER 'heading1: This long value\n is a really long value for heading1\n
    heading2:shortvalue'
    HEADER 'heading1:This long value is a really long value for heading1<CR><LF>
    heading2:shortvalue<CR><LF>'
  • Multiple contiguous white spaces, including folding, results in a single white space.

  • Parameter substitution is supported for this clause.

This example shows how to add static user-defined headers:

CREATE PROCEDURE http_client() 
  URL 'http://localhost/getdata' 
  TYPE 'http:get' 
  HEADER 'UserHeader1:value1\nUserHeader2:value2';

This example shows how to add parameter-substituted user-defined headers:

CREATE PROCEDURE http_client( headers LONG VARCHAR )
  URL 'http://localhost/getdata' 
  TYPE 'http:get' 
  HEADER '!headers';

CALL http_client( 'NewHeader1:value1\nNewHeader2:value2' );
Client side

Headers in HTTP requests can be obtained using a combination of the NEXT_HTTP_HEADER and HTTP_HEADER functions. The NEXT_HTTP_HEADER function iterates through the HTTP headers included within a request and returns the next HTTP header name. Calling it with NULL causes it to return the name of the first header. Subsequent headers are retrieved by passing the function the name of the previous header. This function returns NULL when called with the name of the last header.

Calling this function repeatedly returns all the header fields exactly once, but not necessarily in the order that they appear in the HTTP request.

The HTTP_HEADER function returns the value of the named HTTP header field, or NULL if not called from an HTTP service. It is used when processing an HTTP request via a web service. If a header for the given field name does not exist, the return value is NULL.

Here is a table of some typical HTTP headers and values.

Header Name Header Value
Accept image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language en-us
UA-CPU x86
Accept-Encoding gzip, deflate
User-Agent Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; WOW64; SV1; .NET CLR 2.0.50727)
Host localhost
Connection Keep-Alive
@HttpMethod GET
@HttpURI /demo/ShowHTTPHeaders
@HttpVersion HTTP/1.1

To get the value of each header, use the NEXT_HTTP_HEADER function to get the name of the header and then use the HTTP_HEADER function to get its value. The following example illustrates how to do this.

CREATE PROCEDURE HTTPHeaderExample()
RESULT ( html_string LONG VARCHAR )
BEGIN
    declare header_name long varchar;
    declare header_value long varchar;
    declare table_rows XML;
    set header_name  = NULL;
    set table_rows = NULL;
header_loop:        
    LOOP
        SET header_name = NEXT_HTTP_HEADER( header_name );
        IF header_name IS NULL THEN 
            LEAVE header_loop 
        END IF;
        SET header_value = HTTP_HEADER( header_name );
        -- Format header name and value into an HTML table row
        SET table_rows = table_rows || 
            XMLELEMENT( name "tr", 
                XMLATTRIBUTES( 'left' AS "align", 
                                'top' AS "valign" ),
                XMLELEMENT( name "td", header_name ),
                XMLELEMENT( name "td", header_value ) );
                        
    END LOOP;
    SELECT XMLELEMENT( name "table",
                XMLATTRIBUTES( '' AS "BORDER", 
                             '10' AS "CELLPADDING", 
                              '0' AS "CELLSPACING" ),
                XMLELEMENT( name "th", 
                    XMLATTRIBUTES( 'left' AS "align", 
                                   'top'  AS "valign" ),
                                   'Header Name' ), 
                XMLELEMENT( name "th", 
                    XMLATTRIBUTES( 'left' AS "align", 
                                   'top'  AS "valign" ),
                                   'Header Value' ),
                table_rows );
END;

This example formats the header names and values into an HTML table. The following service can be defined to show how this sample procedure works.

CREATE SERVICE ShowHTTPHeaders
TYPE 'RAW'
AUTHORIZATION OFF 
USER DBA
AS CALL HTTPHeaderExample();

To test the service, open a web browser and supply the following URL:

[external link] http://localhost:80/demo/ShowHTTPHeaders

To set the status code (or response code) of the request being processed, use the @HttpStatus special header. See sa_set_http_header system procedure.

For more information about header processing, see Web services functions.