Skip to main content

URL Connections

A connection configuration specifies how the rendering service will handle outgoing HTTP requests on behalf of the project. This encompasses all situations when the cloud service acts as an HTTP client calling external servers to achieve its tasks. There are four main cases of this:

  • /mediaproxy/config.ion
    • rendering service must read image files from remote systems to integrate them into the PDF, e.g., from a MAM system or from the image folder of the public web shop of a company.
  • /upload/config.ion
    • rendering service must upload the generated PDF to a remote server (http or ftp)
  • /callback/config.ion
    • rendering service must notify the originating server about the success of a rendering
    • this will include the URL where the PDF can be downloaded
  • /error/config.ion
    • rendering service must notify the originating server about the failure of a rendering
    • this will include a detailed error message
  • /config.ion
    • [deprecated] please use /mediaproxy/config.ion instead

All these cases have in common that the service will use only URLs that are explicitly configured. If a request does not match any defined base URI in the configuration ion file, it will not be executed.

General Structure​

  • Config files supporting URL connection configuration contain a root property called connections.
  • The "connections" property is an (optionally empty) array of Connection objects.
  • A connection object is identified by its URI, which is matched against real URIs as used by mediaproxy or webhook workers. The best matching connection configuration for a real uri is defined as the connection with the longest matching path from the start of the URI.
  • If a connection matches for a real URI, the request headers, authorization and other settings from the configuration are applied to that URI call.

Typical example from "/config.ion" for mediaproxy​

{
connections: [
{
method: "GET",
url: "https://example.com/protected/images",
header: {
"x-useragent": "mypriintcloudproject",
"content-type": "application/x-test",
},
authentication: {
type: "Bearer",
value: "eyJmb28iOiJiYXIifQ==",
},
cache: {
"max-duration": 600,
// 1 h
"ignore-cache-control": true,
},
},
],
}

This defines one connection configuration.

Read this as follows:

  • If a request is made to a URL starting with https://example.com/protected/images then
    • add the content type "application/x-test" to the request
    • and use bearer token authentication, i.e., in this case add a header "Authorization: Bearer eyJmb28iOiJiYXIifQ=="
    • cache the results for a maximum of 10 minutes
    • ignore the Cache-Control headers as sent from the server (e.g., because that server wrongly sends "Expires: now" always).

This is typical for mediaproxy configuration where only GET requests are used.

Complex Example from "callback/config.ion"​

{
"connections": [
{
"method": "POST",
"url": "https://example.com/priint-cloud-connector/v1/callback",
"header": {
"x-useragent": "mypriintcloudproject",
"content-type": "application/json"
},
"authentication": {
"type": "OAuth2",
"grantType": "Password",
"clientId": "ce129d64e40d47fa48ddad7c70b1dcd9",
"clientSecret": "Y2UxMjlkNjRlNDBkNDdmYTQ4ZGMjlkNjRlNDBkRhZDdjNzBiMWRjZDk",
"username": "priintcloud-worker",
"password": "S*meS*cr*tCh*rs",
"scope": "readwrite"
},
"payload": [
{
"value": "{\"refkey\":\"{refkey}\",\"pdfUrl\":\"{location}\"}"
}
]
}
]
}
  • This only allows POST requests to the "callback" endpoint.
  • It will send a custom header always to identity the agent to the callback service. This might be used for logging on the callback server side.
  • The endpoint requires OAuth2 authentication using the OAuth2 password flow.
  • It will send a JSON request built from the payload value.
  • The placeholder {location} will be replaced by the actual url where to download the PDF.
  • The placeholder {refkey} points to a custom parameter that was sent with the original request that triggered the rendering.

Basic Request Properties​

url​

Full qualified base URI for this connection.

method​

HTTP method to be used for queries to the endpoint.

  • Data Type: String (any of GET, POST, PUT, PATCH)
  • Default: (depends on worker)
    • GET (mediaproxy)
    • PUT (upload)
    • POST (callback, error)

Map of request headers

  • Data Type: object
  • Default: null

NOTE: These headers will be set before applying computed headers like Content-Length, Authorization, etc.

HINT: Headers allow variable expansion. Variable names must be enclosed by curly brackets. Which variables are available for expansion depends on the processing steps and may differ between, say, the mediaproxy and the upload process. Please refer to the documentation of the worker.

Example
{
url: "https://example.com/protected/images",
method: "PUT",
authentication: {
type: "Bearer",
value: "eyJmb28iOiJiYXIifQ==",
},
header: {
"Content-Type": "application/octet-stream",
"x-ticket-id": "priintcloud ticket is {ticket}",
},
}

After variable expansion this may lead to a request like this

PUT /protected/images HTTP/1.1
Host: https://example.com
Content-Type: application/octet-stream
x-ticket-id: priintcloud ticket is u6g3fzzv36nzswjdb6dzdiuvpy
Authorization: Bearer eyJmb28iOiJiYXIifQ==

HTTP Client Configuration​

allow-insecure​

  • Do not use this setting for priint cloud connections.
  • All connections to outbound services MUST be secure (i.e., https_only).

connect-timeout​

Connection timeout in seconds.

This is the time to wait for the connection to be established.

  • Data Type: int
  • Default: 5 (5 sec)

follow-redirects​

Automatically redirect to a URI declared in 3xx responses.

  • Data Type: boolean
  • Default: false

request-timeout​

Request timeout in seconds.

This is the time to wait for the response after the connection has been established.

  • Data Type: int
  • Default: 60 (1 min)

Caching Configuration​

Clientside HTTP caching for GET requests.

NOTE: Cache configuration is specific to mediaproxy.

cache​

  • Data Type: Object
  • Default: null

Example

{
cache: {
"max-duration": 600,
// 1 h
"ignore-cache-control": true,
},
}

cache.max-duration​

Max age of an entry in the cache in seconds.

This is applied even if the Cache-Control headers of the response allow for more.

  • Data Type: int (seconds)
  • Default: 0 (no caching)

cache.max-object-size​

Objects exceeding this threshold will never be cached.

  • Data Type: long (number of bytes)
  • Default: 10485760 (10 MB)

cache.heuristic​

Allow HttpClient to cache values without Cache-Control headers using the rules given in RFC-2616.

  • Data Type: boolean
  • Default: true

cache.revalidate-after​

Currently not supported

cache.keys​

currently not supported

cache.ignore-cache-control​

Ignore the RFC-2616 standards compliant mode for caching.

Data will be cached regardless of the caching headers send by the client only on the base of the max-duration setting.

  • Data Type: boolean
  • Default: false

Authentication Configuration​

priint cloud supports the following authentication types.

NameDescription
-public access - no authentication necessary
BasicProtected by username and password.
BearerA token of type bearer is expected as HTTP Authorization Header. A static token is applied.
OAuth2A token of type bearer is expected as HTTP Authorization Header. The token is dynamically retrieved via a special request from an authorization server. Server endpoint, clientId and clientSecret must be defined in the configuration
ApiKeyAn API Key is expected in an HTTP Header. Header name and key are static values read from the configuration
AWSS3 authorization token is expected. This is a special variant of OAuth2 used by Amazon Web Services but also by Google Cloud Storage and other S3 compatible services. Dynamic headers are computed differing from chunk to chunk as the input it send to the receiving S3 server

Basic​

Configuration example:

// "authentication":
{
type: "Basic",
username: "foo",
password: "bar",
}

Adding a header to all requests:

Authorization: Basic Zm9vOmJhcg

Supported properties are

  • type (must be Basic)
  • username (required)
  • password (required)

Bearer​

Configuration example:

// "authentication":
{
type: "Bearer",
value: "eyJmb28iOiJiYXIifQ==",
}

Adding a header to all requests:

Authorization: Bearer eyJmb28iOiJiYXIifQ==

Supported properties are

  • type (must be Bearer)
  • value (required)

OAuth2​

Configuration example:

{
authentication: {
type: "OAuth2",
grantType: "Password",
accessTokenUrl: "https://iam.com/realms/example/oauth/v1/token",
clientId: "wzJ5ge9v5LSUEv6nM8MeQEaFu4TxnaNe",
clientSecret: "YjhNbkVGSlBxVEtmQXBYZzJzOVE4cUhVd2p5WTh2UGRjRlFGWTlkUHVMaDZqRXF0",
username: "priintcloud-worker",
password: "S*meS*cr*tCh*rs",
scope: "readwrite",
},
}

If a valid token is already cached, then a header is added to all requests like this:

Authorization: Bearer ValueOfMyOAuth2AccessToken

If there is no valid token yet, a sub-request is posted to the accessTokenUrl using the standard OAuth2 "password" flow to retrieve an OAuth2 token as a JSON object.

# >>> request
POST {accessTokenUrl}
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic base64({clientId}:{clientSecret})

grant_type = password &
username = {username} &
password = {password} &
scope = {scope}

# <<< response
Content-Type: application/json

{
"access_token" : "Y2MyY2MxMjcxMDU5MDMxZWZiNWM1ODZiMTA5ZGE0NzZmZTk5NmJjMTFlOTg0NjFhYg",
"expires_in" : 3600,
"token_type" : "bearer",
"scope" : "readwrite",
"refresh_token" : "MxMjcxMDhNDNiMzMyZTNmZDMyZWEyOGEyYzFiN2M0NjBlNzAzMzhkYTMwYzU4ZTlhe"
}

Supported properties are

  • type (must be OAuth2)
  • grantType (must be ClientCredentials or Password)
    • ClientCredentials expects that clientId and clientSecret are set
    • Password expects that username and password are set - most often additionally to clientId and clientSecret
  • accessTokenUrl (required, full qualified URI)
  • clientId (optional)
  • clientSecret (optional)
  • username (optional)
  • password (optional)
  • scope (optional)

ApiKey​

Configuration example:

{
authentication: {
type: "ApiKey",
key: "MyFooApi",
value: "eyJmb28iOiJiYXIifQ==",
},
}

Adding a header to all requests:

MyFooApi: eyJmb28iOiJiYXIifQ==

Supported properties are

  • type (must be ApiKey)
  • key (optional, defaults to ApiKey)
  • value (required)

AWS​

Supporting S3 storage servers.

Configuration example:

{
authentication: {
type: "AWS",
accessKey: "changeme",
secretKey: "changeme",
},
}

Supported properties are

  • type (must be AWS)
  • accessKey (required, consult your S3 documentation)
  • secretKey (required, consult your S3 documentation)

NOTE: AWS authentication is currently only supported for the upload step,

Request Payload Configuration​

NOTE: Payload configuration is specific to webhooks.

payload​

Payloads of HTTP requests can be configured via one payload template (standard single-part case) and multiple payloads templates (for multipart/form-data).

  • Data Type: Array of Payload objects
  • Default: null

In a multipart/form-data request, each part must be represented as a separate payload object.

In all other cases, a single payload object with just a value property is required.

Example for a simple JSON POST for callback worker

{
"header": {
"Content-Type": "application/json"
},
"payload": [
{
"value": "{\"status\":\"success\",\"location\":\"{location}\"}"
}
]
}

Example for multipart/form-data POST for upload worker

{
header: {
"Content-Type": "multipart/form-data",
},
payload: [
{
mediaType: "application/json",
fieldName: "input",
value: '{"status":"success","ticketId":"{ticket}"}',
},
{
mediaType: "application/pdf",
fieldName: "file",
filename: "datasheet-{foreignKey}.pdf",
},
],
}

payload.mediaType​

Content type of the request body (or body part).

  • Data Type: String
  • Default: null

payload.fieldName​

Name of the body part.

Only used for content-type=multipart/form-data.

  • Data Type: String
  • Default: null

payload.filename​

Set the filename in the content disposition header of the body part.

Only used for content-type=multipart/form-data.

In upload case, the PDF will be attached as the content of the body part.

ADVICE: The payload for the file upload part should be the last one in the array of payloads.

  • Data Type: String
  • Default: null

For more details see https://datatracker.ietf.org/doc/html/rfc7578#section-4.2.

HINT: If the filename of the payload is set, then the value property will be ignored.

payload.value​

String containing a template for the payload.

NOTE: Payload configuration is specific to webhooks.

HINT: Payload values allow variable expansion. Variable names must be enclosed by curly brackets. Which variables are available for expansion depends on the processing steps and may differ between say callback and upload process. Please refer to the documentation of the worker.

  • Data Type: String
  • Default: null

use-chunked-transfer​

Deactivate chunked-transfer as the default streaming procedure for uploads.

The default http exchange method of the upload process is 'chunked transfer' (see https://en.wikipedia.org/wiki/Chunked_transfer_encoding).

Not all receiving servers will support chunked transfer for uploads. Many blob stores, e.g., require knowing the total size of the upload in advance (which is not supported with chunked transfer).

  • Data Type: boolean
  • Default: true

Export Parameters​

NOTE: Export parameters configuration is specific to webhooks, especially the upload worker.

See Upload documentation.

FAQs​

How to upload to Azure Blog Store?​

Hint: set use-chunked-transfer to false.

Upload to Google Cloud Storage​

Use AWS authorization with clientId and clientSecret are created via Google console.