&ANALYZE-SUSPEND _VERSION-NUMBER WDT_v2r12 Method-Library &ANALYZE-RESUME &ANALYZE-SUSPEND _CODE-BLOCK _CUSTOM Definitions /********************************************************************* * Copyright (C) 2005,2009-2011 by Progress Software Corporation. All rights * * reserved. Prior versions of this work may contain portions * * contributed by participants of Possenet. * * * *********************************************************************/ /*-------------------------------------------------------------------------- Library : cgiutils.i Purpose : Utility runtime functions and procedures Syntax : { src/web/method/cgiutils.i } Notes : This file must be included after both cgidefs.i and cgiarray.i which define a number of variables used by these functions and procedures. This file is for internal use by WebSpeed runtime procedures ONLY. Applications should not include this file. Updated : 01/07/1997 billb@progress.com Initial version 10/16/2001 adams@progress.com Added codepage support ------------------------------------------------------------------------*/ /* This .i file was created with WebSpeed WorkShop. */ /*------------------------------------------------------------------------*/ /* Only define things if this file has not yet been included */ &IF DEFINED(CGIUTILS_I) = 0 &THEN &GLOBAL-DEFINE CGIUTILS_I = TRUE /* *************************** Definitions ************************** */ /* Make sure cgiarray.i is included */ &IF DEFINED(CGIARRAY_I) = 0 &THEN {src/web/method/cgiarray.i} &ENDIF /* Variables used only by cgiutils.i */ /* TEMPORARY VARIABLE TO SET CGI MODE. [billb] TRUE = API calls core WEB-CONTEXT: methods FALSE = API calls use existing 4GL implementation This is set in the procedure init-session in web-util.p. */ DEFINE NEW GLOBAL SHARED VARIABLE use-core-api AS LOGICAL NO-UNDO INITIAL TRUE. /* Exclusive Web User variables. */ DEFINE VARIABLE wseu-cookie AS CHAR NO-UNDO. /* E-mail address of application maintainer */ DEFINE VARIABLE HelpAddress AS CHARACTER NO-UNDO FORMAT "x(40)":U. /* Unsafe characters that must be encoded in URL's. See RFC 1738 Sect 2.2. */ DEFINE VARIABLE url_unsafe AS CHARACTER NO-UNDO INITIAL " <>~"#%~{}|~\^~~[]`". /* Reserved characters that normally are not encoded in URL's */ DEFINE VARIABLE url_reserved AS CHARACTER NO-UNDO INITIAL "~;/?:@=&". &ANALYZE-RESUME /* *********************** Procedure Settings ************************ */ &ANALYZE-SUSPEND _PROCEDURE-SETTINGS /* Settings for THIS-PROCEDURE Other Settings: INCLUDE-ONLY */ &ANALYZE-RESUME _END-PROCEDURE-SETTINGS &ANALYZE-SUSPEND _INCLUDED-LIBRARIES /* ************************* Included-Libraries *********************** */ &ANALYZE-RESUME _END-INCLUDED-LIBRARIES /* *************************** Functions **************************** */ &IF DEFINED(EXCLUDE-convert-datetime) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION convert-datetime FUNCTION convert-datetime RETURNS CHARACTER (INPUT p_conversion AS CHARACTER, INPUT p_idate AS DATE, INPUT p_itime AS INTEGER, OUTPUT p_odate AS DATE, OUTPUT p_otime AS INTEGER) : /**************************************************************************** Description: Performs conversions of date and time between local time and UTC time. In addition, an option is supported to normalize a date and time ensuring the value of time is legal between zero and the number of seconds per day. The normalizing step is also performed for either the local to UTC or UTC to local conversions. Parameters: Input: Conversion option: "UTC" - Converts date and time from local to UTC time. "LOCAL" - Converts date and time from UTC to local time. "NORMALIZE" - Normalize date and time so the value of time is legal between zero and the number of seconds per day. Input: Date to convert. Uses the DATE data type. Input: Time to convert. Seconds since midnight (see TIME function). Output: Converted date. Output: Converted time. Returns: Global Variables: utc-offset ****************************************************************************/ DEFINE VARIABLE seconds-per-day AS INTEGER NO-UNDO INITIAL 86400. /* Default option is to normalize */ IF p_conversion = "" OR p_conversion = ? THEN ASSIGN p_conversion = "NORMALIZE":U. /* If date is ? ... */ IF p_idate = ? THEN RETURN "". IF p_itime = ? THEN ASSIGN p_itime = 0. /* Set time adjustment depending on conversion option */ CASE p_conversion: WHEN "LOCAL":U THEN ASSIGN p_itime = p_itime - utc-offset. WHEN "UTC":U THEN ASSIGN p_itime = p_itime + utc-offset. END CASE. /* Normalize if time is too large */ DO WHILE p_itime >= seconds-per-day: ASSIGN p_itime = p_itime - seconds-per-day p_idate = p_idate + 1. /* tomorrow */ END. /* Normalize if time is too small */ DO WHILE p_itime < 0: ASSIGN p_itime = p_itime + seconds-per-day p_idate = p_idate - 1. /* yesterday */ END. ASSIGN p_odate = p_idate p_otime = p_itime. RETURN "". END FUNCTION. /* convert-datetime */ &ANALYZE-RESUME &ENDIF &IF DEFINED(EXCLUDE-format-datetime) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION format-datetime FUNCTION format-datetime RETURNS CHARACTER (INPUT p_format AS CHARACTER, INPUT p_date AS DATE, INPUT p_time AS INTEGER, INPUT p_options AS CHARACTER) : /**************************************************************************** Description: Returns a date and time string formatted for Internet use. Currently, the formats "COOKIE" and "HTTP" are supported. The HTTP format is useful for the Expires: or other headers. The Cookie format is used by the set-cookie() function when an expiration date is specified. Parameters: Input: Date format. Supported are "COOKIE" and "HTTP". Input: Date as a DATE data type. Input: Time as an integer (See TIME function). Input: Options. "LOCAL" - indicates the specified date and time are local time such as returned by the TODAY and TIME functions. The date and time are converted to UTC before formatting. "UTC" - The specified date and time are already in UTC time. The date and time are normalized to ensure the value of time is between zero and the number of seconds in one day. Returns: Formatted date Global variables: References: Cookie Date format: Netscape Cookie Spec: http://home.netscape.com/newsref/std/cookie_spec.html HTTP Date format: RFC 2068, 3.3 Date/Time Formats: http://ds.internic.net/rfc/rfc2068.txt ****************************************************************************/ DEFINE VARIABLE p_rfcdate AS CHARACTER NO-UNDO. /* Does RFC 850/822 allow translated days and months? Think not. */ DEFINE VARIABLE weekday-list AS CHARACTER NO-UNDO INITIAL "Sun,Mon,Tue,Wed,Thu,Fri,Sat":U. DEFINE VARIABLE month-list AS CHARACTER NO-UNDO INITIAL "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec":U. /* If date is ?, return a blank date */ IF p_date = ? THEN RETURN "". IF p_time = ? THEN ASSIGN p_time = 0. /* If no options are specified, LOCAL is the default */ IF p_options = "" OR p_options = ? THEN ASSIGN p_options = "LOCAL":U. /* If Local was specified and the format is Cookie or HTTP, convert date and time to UTC. */ IF CAN-DO(p_options, "LOCAL":U) AND (p_format = "COOKIE":U OR p_format = "HTTP":U) THEN /* Convert date and time from Local to UTC */ convert-datetime("UTC":U, p_date, p_time, OUTPUT p_date, OUTPUT p_time). /* Otherwise, just normalize */ ELSE /* Normalize date and time */ convert-datetime("NORMALIZE":U, p_date, p_time, OUTPUT p_date, OUTPUT p_time). /* Output the formatted date */ CASE p_format: WHEN "COOKIE":U THEN DO: /* Cookie format based on RFC-1123: Wdy, DD-Mon-YYYY HH:MM:SS GMT */ ASSIGN p_rfcdate = ENTRY(WEEKDAY(p_date), weekday-list) + ", ":U + STRING(DAY(p_date),"99":U) + "-":U + ENTRY(MONTH(p_date), month-list) + "-":U + STRING(YEAR(p_date), "9999":U) + " ":U + STRING(p_time,"HH:MM:SS":U) + " GMT":U. END. WHEN "HTTP" THEN DO: /* HTTP format based on RFC-1123: Wdy, DD Mon YYYY HH:MM:SS GMT */ ASSIGN p_rfcdate = ENTRY(WEEKDAY(p_date), weekday-list) + ", ":U + STRING(DAY(p_date),"99":U) + " ":U + ENTRY(MONTH(p_date), month-list) + " ":U + STRING(YEAR(p_date), "9999") + " ":U + STRING(p_time,"HH:MM:SS") + " GMT":U. END. OTHERWISE queue-message("WebSpeed":U, "format-datetime: ":U + "format '" + p_format + "' is not supported"). END CASE. RETURN p_rfcdate. END FUNCTION. /* format-datetime */ &ANALYZE-RESUME &ENDIF &IF DEFINED(EXCLUDE-get-binary-data) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION get-binary-data FUNCTION get-binary-data RETURNS MEMPTR (INPUT p_name AS CHARACTER) : /**************************************************************************** Description: Retrieves a MEMPTR with the contents of a file posted with a multipart/form-data form Input Parameter: Name of variable (a field of type 'file' from the form) Returns: MEMPTR or ? (which means the file was too big). ****************************************************************************/ RETURN WEB-CONTEXT:GET-BINARY-DATA(p_name). END FUNCTION. /* get-binary-data */ &ANALYZE-RESUME &ENDIF &IF DEFINED(EXCLUDE-get-cgi) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION get-cgi FUNCTION get-cgi RETURNS CHARACTER (INPUT p_name AS CHARACTER) : /**************************************************************************** Description: Retrieves the value for the specified CGI variable Input Parameter: Name of variable or ? Returns: Value or blank if invalid name. If ? was specified for the name, the list of variables is returned. ****************************************************************************/ DEFINE VARIABLE v-value AS CHARACTER NO-UNDO. DEFINE VARIABLE i AS int NO-UNDO. IF p_name = ? THEN RETURN WEB-CONTEXT:GET-CGI-LIST("ENV":U). ELSE RETURN WEB-CONTEXT:GET-CGI-VALUE("ENV":U, p_name). END FUNCTION. /* get-cgi */ &ANALYZE-RESUME &ENDIF &IF DEFINED(EXCLUDE-get-cgi-long) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION get-cgi-long FUNCTION get-cgi-long RETURNS LONGCHAR (INPUT p_name AS CHARACTER) : /**************************************************************************** Description: Retrieves the LONGCHAR value for the specified CGI variable Input Parameter: Name of variable or ? Returns: Value or blank if invalid name. ****************************************************************************/ IF p_name = ? THEN RETURN WEB-CONTEXT:GET-CGI-LIST("ENV":U). ELSE RETURN WEB-CONTEXT:GET-CGI-LONG-VALUE("ENV":U, p_name). END FUNCTION. /* get-cgi-long */ &ANALYZE-RESUME &ENDIF &IF DEFINED(EXCLUDE-get-field) = 0 &THEN &ANALYZE-SUSPEND _CODE-BLOCK _FUNCTION get-field FUNCTION get-field RETURNS CHARACTER (INPUT p_name AS CHARACTER) : /**************************************************************************** Description: Retrieves the associated value for the specified form field. Input Parameter: Name of field or ? Returns: Value of field or blank if invalid field name. If ? was specified for the name, the list of fields is returned. Global Variables: FieldList ****************************************************************************/ DEFINE VARIABLE v-value AS CHARACTER NO-UNDO. DEFINE VARIABLE i AS int NO-UNDO. DEFINE VARIABLE j AS int NO-UNDO. DEFINE VARIABLE v-form AS CHARACTER NO-UNDO. DEFINE VARIABLE v-query AS CHARACTER NO-UNDO. DEFINE VARIABLE v-name AS CHARACTER NO-UNDO. DEFINE VARIABLE cTmp AS CHARACTER NO-UNDO. /* Get list of fields? */ IF p_name = ? THEN DO: /* If the field list was already computed for this request, return it */ IF FieldList <> "" THEN RETURN FieldList. ASSIGN v-form = WEB-CONTEXT:GET-CGI-LIST("FORM":U) v-query = WEB-CONTEXT:GET-CGI-LIST("QUERY":U) /* Combine form input and query string */ v-value = v-form + (IF v-form <> "" AND v-query <> "" THEN ",":U ELSE "") + v-query j = NUM-ENTRIES(v-value). /* If returning a field list, eliminate dupes */ DO i = 1 TO j: ASSIGN v-name = ENTRY(i, v-value). IF LOOKUP(v-name, cTmp) = 0 THEN ASSIGN cTmp = cTmp + (IF cTmp = "" THEN "" ELSE ",":U) + v-name. END. ASSIGN FieldList = cTmp. /* save it away */ RETURN FieldList. END. /* Else, get a field value */ ELSE DO: /* Return the output directly to maximize the allowable length. Replace all CF/LF's with with an LF so when an HTML