WSAttachment

Defines file attachments in the REST message.

Syntax

WSAttachment [= "regexp_pattern"]
Where:
  1. WSAttachment is an ATTRIBUTES() clause of an input parameter or return value of the function defining a file attached in the REST message.
  2. regexp_pattern is a regular expression value that the filename must match. It is used to limit filenames to a set of valid characters to protect against code injection. Using a regex pattern is optional.

WSAttachment is an optional attribute.

Usage

You can attach files using the WSAttachment attribute. Files may be sent in either the request or the response. To receive files in a request, include one or more input parameters with the WSAttachment attribute. The client must provide an absolute path for each file parameter when calling the function.

To reduce the risk of code injection, you may provide a regular expression that restricts allowed filenames. For example, a simple filename with extension (letters, digits, underscore, and dash only): WSAttachment = "[a-zA-Z0-9_]*\.[a-zA-Z0-9_]*".

The GWS validates the filename against the given pattern, and raises error-42 if the regex pattern is incorrect or the validation fails. The WSAttachment attribute expects a regular expression that follows libxml2/POSIX syntax. For more information on using regular expressions, see the XML Schema specification.

The file attachment MIME type can be set by the WSMedia attribute. If WSMedia is not specified, the engine accepts it as the OpenAPI specification for all file types, "*/*" .

Example WSAttachment with WSMedia

In this sample REST function a text file is returned as an attachment. In the return clause of the function a STRING is defined with the WSAttachment attribute. The WSMedia attribute specifies the MIME type as "text/plain". The absolute path to the file is set on the return string.

The REST engine copies the file to the temporary directory defined by the TMP environment variable. The file is removed from the temporary directory at the end of the REST operation to avoid a build-up of files on your disk.

IMPORT com
IMPORT os

PUBLIC DEFINE userError RECORD ATTRIBUTE(WSError = "User error")
  message STRING
END RECORD

PUBLIC FUNCTION GetReadme() 
   ATTRIBUTES(WSGet,
              WSPath = "/file/README",
              WSDescription = "Returns a text file",
              WSThrows = "404:@userError") 
   RETURNS (STRING ATTRIBUTES(WSAttachment, WSMedia = "text/plain") )
     DEFINE ret, fname STRING
     DEFINE ok INTEGER

     LET fname = "/myservice/files/README"
     LET ok = os.Path.exists(fname)
     IF ok THEN
       LET ret = fname
     ELSE
       LET userError.message = SFMT("File (%1) does not exist", fname)
       CALL com.WebServiceEngine.SetRestError(404,userError)
     END IF
     RETURN ret
END FUNCTION

Attaching files in request and response

In this sample REST function, an image file is sent to the server in the request and another image is returned to the client. The wildcard (image/*) in WSMedia allows for all image types. If the file can be any type, WSMedia is not specified with WSAttachment.

The format is chosen according to that specified in the Accept or Content-Type headers. You code in your function to replace the image/* placeholder in the Accept or Content-Type header with the actual value. This can also be done using the WSContext attribute to set the header.

IMPORT os

PUBLIC FUNCTION EchoFile( input STRING ATTRIBUTES (WSAttachment,WSMedia = "image/*") )
  ATTRIBUTES(WSPost)
  RETURNS STRING ATTRIBUTES (WSAttachment, WSMedia = "image/*")
    DEFINE ok INTEGER
    LET ok = os.path.rename(input, "MyFile.png")
    RETURN "/usr/local/MyOtherFile.jpg"
END FUNCTION

Attaching a file and validating the filename against a regular expression pattern

In this REST sample, the input parameter uses WSAttachment="[a-zA-Z0-9_]*\.[a-zA-Z0-9_]*" to declare an attachment. The GWS validates the received filename against that regular expression, allowing only the listed characters in the name and extension. Any character outside the class [a-zA-Z0-9_] in the filename or extension will cause validation to fail.

Note:

The dot (.) matches any character in regex, so it must be escaped as (\.) to match a literal period.

If the regular expression on the WSAttachment attribute is invalid, the server will raise error-42 and respond with the HTTP error:
400 Regex syntax error
If the filename of the received file does not match the defined pattern (regexp), the server will raise error-42 and respond with the HTTP error:
400 File name does not match template
PUBLIC FUNCTION simpleFile(
    in STRING ATTRIBUTES(WSAttachment = "[a-zA-Z0-9_]*\.[a-zA-Z0-9_]*"))
    ATTRIBUTES(WSPost, WSPath = "/simple/txt")
    RETURNS()
END FUNCTION