LOAD_FILE_CONTENTS

Load a file, or part of a file, into the body of an HTTP request in preparation for uploading to a REST-compliant API.

LOAD_FILE_CONTENTS(LocalFilePath,OptionList)

vUhttp->LOAD_FILE_CONTENTS("mydocs.zip", "segm=10k")

Parameters

Parameter

Type

Direction

Description

LocalFilePath

string

INOUT

Name of the file whose contents will be the HTTP request body. Uniface syntax for (zip) files can be used but no assignment file redirection is supported.

OptionList

string

OUT

Associative list of name-value pairs

Options

Parameter

Description

SEGM=Size

Specifies the number of bytes read in one go from the file into the request body. A number of reads may be required to read the whole file or chunk.

It is used for both chunked and simple transfers. It does not affect memory allocation as this is determined by the total file size or the chunk size.

For simple (non-chunked) transfers only, specify the size of the file to be downloaded.

Size is expressed as Num{k | m}

Thus, 4096 is the same as 4k, and 1048576 is the same as 1m.

The limits are:

  • Default: 256k
  • Minimum: 4k
  • Maximum: 1024m

The default is the file size or chunk size. It provides a mechanism to balance the number of times the file is read with the amount that is read.

CHUNK=Size

Use a chunked file transfer to upload the file of the specified size.

Size is expressed as Num{k | m}

Each REST API has its own size limits, but for Uniface, the limits are:

  • Minimum: 4k
  • Maximum: 1024m

STARTAT=Num

For chunked file transfer only, resets the file position in order to resend lost chunks.

TCPRCVBUF=Size

Specifies the size of the TCP Receive Buffer. It can be used to improve performance when downloading large files or chunks.

Size is expressed as Num{k | m}

  • Minimum: 4k
  • Maximum: None.

The maximum buffer size depends on the local TCP stack. Normally, if a value is specified that is larger than the maximum, then the maximum value is used.

TCPSNDBUF=Size

Specifies the size of the TCP Send Buffer. It can be used to improve performance when uploading large files or chunks.

  • Minimum: 4k
  • Maximum: None.

Size is expressed as Num{k | m}

The maximum buffer size depends on the local TCP stack. Normally, if a value is specified that is larger than the maximum, then the maximum value is used.

Return Values

If errors occur, the file is closed, irrespective of its state.

Values Returned in $status

Value

Meaning

>=0

Successfully loaded, or the number of bytes loaded.

-1

Cannot open the specified file

-2

Cannot reposition to STARTAT in the file

-3

Problems reading file

-4

Invalid option in the OptionList

-5

Invalid value for option in the OptionList

-7

Not able to read the file size, try chunked transfer

-8

File is too large for single transfer, try chunked transfer

-10

Cannot allocate a buffer, try chunked transfer or a smaller chunk

-12

Internal error occurred

-14

The body of the request has not been completely read by a previous call

Description

When constructing a request, the LOAD_FILE_CONTENTS operation, reads the specified file and places its contents into the body of the request. You are not allowed to provide any other contents in the SEND operation.

For file uploads, you must include a header that sets the content type as application/octet-stream. For example:

putitem/id/case vHeaders, "Content-Type", " application/octet-stream "

To improve the speed of single or chunked uploads, you can specify a larger TCP Send Buffer using the TCSNDVBUF option. For example, on Windows the default buffer size is 8K. By setting it to 512K you can significantly improve performance.

Description

When constructing a request, the LOAD_FILE_CONTENTS operation, reads the specified file and places its contents into the body of the request. To ensure that the file can be uploaded to the specified URL, you are not allowed to provide any other contents in the SEND operation.

For file uploads, you must include a header that sets the content type as application/octet-stream. For example:

putitem/id/case vHeaders, "Content-Type", " application/octet-stream "

Chunked File Transfer

Many APIs impose an upper limit to the size of file that can be transfered in one request. They also set limits on the chunk size being a multiple of some size. There is a balance between the chunk size and how many chunks have to be sent, as a result of that. The chunk size is allocated as a single buffer. The larger it is the fewer repeat calls you need to make. The Uniface limit is for a file or chunk of a file is 2GB. The limits for most APIs is likely to be substantially smaller.

To transfer a file in chunks, you need to specify the CHUNK option. The number of bytes is read from the file and placed into the request body. The chunk is obtained from the file in steps as specified by the SEGM option. The SEND operation sends this chunk of the file to the REST API.

Repeated calls to LOAD_FILE_CONTENTS followed by SEND are required to transfer the complete file.

The last chunk to be transferred is usually smaller than the previous chunks, so you may need to use a Content-Range header to inform the API of which chunk is being sent. You must close the file with an explicit call to CLOSE_FILE. This operation can only handle one range at a time.

In chunked file transfers, REST APIs offer different methods of restarting a transfer continuing from the last successful chunk. You can use the STARTAT option to restart by repositioning the local file. You should maintain the restart position, possibly by extracting it from the range information.

Call Order for Uploading Files

The following code shows the call order when using the LOAD_FILE_CONTENTS operation to upload a file. It is assumed that the remote file path is specified in headers or the URL.

  • vUhttp is a handle to a UHTTP component instance
  • vInfo is a variable to hold returned string information
  • vLen is a variable to hold returned content length
  • vHeaders is a variable that holds headers
  • vResp is a variable to hold the response
Simple Upload
vUhttp->LOAD_FILE_CONTENTS("mydocs.zip", "segm=10k")
vUhttp->GET_INFO("length", vInfo)
vLen = $status

; build associative list of headers:
putitem/id/case vHeaders, "Content-Length", "%%vLen"
putitem/id/case vHeaders, "Content-Type”, “application/octet-stream”

vUhttp->SEND(vUrl, "PUT", "", "", vHeaders, "", vResp)
Chunked Upload
repeat
  vUhttp->LOAD_FILE_CONTENTS("mydocs.zip", "chunk=256k")
  vUhttp->GET_INFO("range", vInfo)

  ; build associative list of headers
  putitem/id/case vHeaders, "Content-Range", "%%vInfo%%%/%%vLen"
  putitem/id/case vHeaders, "Content-Type", "application/octet-stream"

  vUhttp->SEND(vUrl, "PUT", "", "", vHeaders, "", vResp)
until (<DefineCondition>) 
 
vUhttp->CLOSE_FILE()

Related Topics