Config - Locations
A "Location" is a part of the site which matches specific attributes in the incoming request - it can be e.g. a specific hostname (virtual host), it can be based upon URL path, or even user ID or group.
For a particular location you specify how the gateway should react - should it modify the request or responses ? should it add/remove headers or cookies, and should it forward/proxy the request to one of the configured Destinations or should it respond with a specific response or a dynamic one created by a script.
Refer to Locations in the concepts guide for more information about what locations are.
Locations
Locations are stored as separate JSON objects in the locationsarray in the gateway JSON configuration.
Example locations:
{ "session": {}, "destinations": ], "locations": [ { "location.enabled": true, "location.enabled": true, "plugin": {}, "session.needed": false, "response.compress": true, "response.redirect": "https://%{HTTP_HOST}:8443%{PATH_WITH_QUERY}", "name": "Unsecured requests", "action": "respond", "description": "Redirect http to https", "conditions": [ { "values": ["http"], "type": "scheme" }, { "deny": true, "values": [ "127.0.0.1", "localhost", "::1", "0:0:0:0:0:0:0:1" ], "type": "remoteip" } ], "response.status": 307, "cookiesnapper": {} }, { "name": "OpenID Connect Google", "description": "OpenID Connect authorization code flow example using Google", "conditions": [{ "deny": false, "values": ["/openid"], "type": "path" }], "authentication": { "plugins": ["io.ceptor.authentication.AuthenticatorOpenIDConnect"], "openidconnect": { "response.contenttype": "text/html", "identityprovider.name": "google", "authenticationplugin": 48, "redirecturl": "https://%{HTTP_HOST}/openid", "scope": "openid email profile", "authorize.url": "https://accounts.google.com/o/oauth2/auth", "response.status": 200, "response.content": "<html>\n<head><title>Success<\/title>\n<body>\n<h1>Success<\/h1>\nWelcome %{statevariable:email} - authentication succeeded using google.\n<\/body>\n<\/html>", "parameters": "access_type=online", "client.id": "371213948273-79eceu24cm64ft69pln0hk2lfapok1bq.apps.googleusercontent.com" } } }, { "name": "OpenID Connect Microsoft", "description": "OpenID Connect authorization code flow example using Microsoft", "conditions": [{ "deny": false, "values": ["/openidmicrosoft"], "type": "path" }], "authentication": { "plugins": ["io.ceptor.authentication.AuthenticatorOpenIDConnect"], "openidconnect": { "response.contenttype": "text/html", "identityprovider.name": "microsoft", "authenticationplugin": 48, "redirecturl": "https://%{HTTP_HOST}/openidmicrosoft", "scope": "openid email profile", "authorize.url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", "response.status": 200, "response.content": "<html>\n<head><title>Success<\/title>\n<body>\n<h1>Success<\/h1>\nWelcome %{REMOTE_USER} - authentication succeeded using Microsoft Online.\n<\/body>\n<\/html>", "client.id": "317190f9-efec-4307-beb9-7f8380a8ae16" } } }, { "authorization": { "roles": [], "authorization.script": "state.agent.logoff(state.id);\ntrue;" }, "response.contenttype": "text/html", "content.preload": false, "plugin": {}, "session.needed": true, "session.afterconditionsmatch": false, "name": "Logoff", "description": "Logs off the session", "action": "respond", "conditions": [{ "deny": false, "values": ["/logoff"], "type": "path" }], "response.status": 200, "response.content": "<html><body>You are now logged off.<\/body><\/html>", "cookiesnapper": {} }, { "response.contenttype": "text/html", "plugin": {}, "session.needed": true, "name": "WebSSO", "description": "WebSSO / ADFS Example", "action": "respond", "response.reason": "OK", "response.status": 200, "response.content": "<html>\n<body>Hello... %{REMOTE_USER}\n<\/body>\n<\/html>", "cookiesnapper": {}, "conditions": [{ "deny": false, "values": ["/adfs"], "type": "path" }], "authentication": { "websso": { "response.contenttype": "text/html", "identityprovider.name": "%{script}var name=state.getQueryOrPostParam(\"idpname\");\nif (name === null) name = 'microsoft';\nname;", "redirecturl": "%{REQUEST_URL}", "serviceprovider.name": "%{script}state.getQueryOrPostParam(\"spname\");", "failure": { "response.contenttype": "text/html", "action": "respond", "response.status": 403, "response.content": "<html><body>Authentication failed<p/>\nDetails:<\/br>\n<pre>\n%{htmlencode:EXCEPTION_LOG}\n<\/pre>\n<\/body><\/html>" }, "response.status": 200, "response.content": "<html><body>Success %{REMOTE_USER}<\/body><\/html>", "federation.enabled": true }, "plugins": ["io.ceptor.authentication.AuthenticatorWebSSO"] } }, { "content.preload": false, "description": "Every single request", "request.concurrent.max": 0, "cookiesnapper": { "classifier": "%{HTTP_HOST}", "pattern": "JSESSIONID" }, "request.queue.size": 10000, "valid.methods": "GET|POST|OPTIONS|HEAD", "noauthentication.for.options": false, "authorization": { "noauthorization.for.options": false, "roles": [], "server.identifier": "none" }, "proxy.destination": "demoapp", "request.headers": [ { "name": "X-Forwarded-Proto", "value": "%{HTTP_SCHEME}" }, { "name": "X-Forwarded-For", "value": "%{REMOTE_ADDR}" }, { "name": "X-Forwarded-Port", "value": "%{REMOTE_PORT}" }, { "name": "X-Forwarded-Server", "value": "%{SERVER_NAME}" } ], "plugin": {"classifier": "%{HTTP_HOST}"}, "request.persecond.max": 0, "response.maxbytes.persecond": 0, "urlrewrite": [{ "newurl": "/secret/$1", "last": true, "pattern.flags": "CASE_INSENSITIVE", "decode.before.match": true, "name": "TOPSECRET to secret", "pattern": "^/TOPSECRET/(.*)", "redirect": false, "clear.query.params": false, "conditions": [{ "deny": false, "values": [ "localhost*", "{regex:IGNORE_CASE}LoCaLhOsT.*" ], "type": "host" }] }], "session.needed": false, "response.compress": true, "name": "All requests", "response.cookies": [{ "path": "/stuff", "discard": false, "name": "IWasHere", "httponly": true, "samesite": lax, "secure": true, "value": "%{GEOIP_ISP}" }], "action": "continue", "response.headers": [ { "name": "Via", "value": "ceptor.io" }, { "name": "Server", "value": null }, { "name": "Location", "value": "%{rewrite:responseheader:location;\"http\\:\\/\\/(.*)$\";\"CASE_INSENSITIVE\";\"https://$1\"}" } ], "conditions": [], "request.cookies": [ { "name": "sessionid", "value": null }, { "name": "sslsessionid", "value": null } ] }, { "request.attributes": [{ "name": "NotAGif", "value": "true" }], "plugin": {}, "response.hooks": [ { "expected.response.status": "404", "respond": true, "response.headers": [{ "name": "X-Content", "value": "WasNotFound" }], "response.status": 404, "response.reason": "Sorry, not found", "response.contenttype": "text/plain", "response.content": "Oh no, I did not find that" }, { "expected.response.status": "401", "respond": false, "response.status": 302, "response.redirect": "https://somewhere.else", "script": "%{script}// Example javascript that simply sends the response configured in the response hook\r\n\r\ncontext.gateway.sendResponse(context, context.currentResponseHook.response);" } ], "session.notvalid.action": "continue", "url.validator": { "verify.encoding": true, "verify.fullurl": true, "maxlength": 32768, "query.key.maxlength": 1024, "query.value.maxlength": 8192, "enabled": true, "authority.regex": null }, "session.needed": false, "name": "All requests except jpg,png,gif,css", "action": "continue", "conditions": [ { "values": ["*"], "type": "path" }, { "deny": true, "values": ["*.jpg|*.png|*.gif|*.css"], "type": "path" } ], "param.validator": { "verify.pathparams": true, "verify.params": [{ "value.lowercase": true, "key.lowercase": true, "value": "*abc*1", "key": "test*" }], "failure": { "response.contenttype": "text/html", "action": "respond", "response.headers": [], "response.reason": "Invalid parameter", "response.status": 400, "response.content": "<html><body><h1>Invalid parameter<\/h1><\/body><\/html>" }, "verify.postparams": false, "verify.params.required": true, "verify.params.extra.allowed": true, "verify.queryparams": true }, "cookiesnapper": {}, "authentication": { "ntlm": { "authenticationplugin": 35, "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.reason": "Invalid userid/password", "response.status": 403, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}" }, "required": false, "allow.anonymous": true }, "plugins": [ "io.ceptor.authentication.AuthenticatorSSLClientCert", "io.ceptor.authentication.AuthenticatorBasicAuth" ], "spnego": { "authenticationplugin": 26, "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.reason": "Invalid userid/password", "response.status": 403, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}" }, "allow.ntlm.fallback": true }, "basicauth": { "authenticationplugin": 9, "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.headers": [{ "name": "WWW-Authenticate", "value": "Basic realm=\"ceptor.io\"" }], "response.reason": "Invalid userid/password", "response.status": 401, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}" }, "realm": "ceptor.io", "required": false }, "ssl": { "authenticationplugin": 18, "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.reason": "Invalid client cert", "response.status": 401, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid client certificate<\/h1><\/body><\/html>';}" }, "required": false } }, "ip.restriction": { "ranges": [ { "values": [ "127.0.0.1-127.0.0.255", "::1" ], "name": "local" }, { "values": ["192.168.1.0/24"], "name": "intranet" }, { "values": ["{file}${portalprotect.home}/config/iprange1.txt"], "name": "range1" } ], "allowchange": true, "action.invalid": { "response.redirect": "/invalid?originalUrl=%{urlencode:REQUEST_URL}", "action": "respond", "response.reason": "Invalid IP", "response.status": 302 }, "ip.address.maxcount": 32, "geoip.type": "complex", "geoip.distance": 100, "geoip.complexrules": [ "ip1=ip2", "country1=country2&country2=\"DK\"", "distance=300" ], "script": "if (input == '127.0.0.1') true; else false;" } }, { "plugin": { "response.wrapper.script": "%{file}/responsedumper.js", "response.wrapper.class": "io.ceptor.gateway.plugin.ResponseDumper", "request.wrapper.class": "io.ceptor.gateway.plugin.RequestDumper", "XXXrequest.wrapper.script": "%{file}/requestdumper.js" }, "session.needed": false, "name": "JSP response dumper", "conditions": [{ "values": ["*.jsp"], "type": "path" }], "cookiesnapper": {} }, { "proxy.destination": "google", "plugin": {}, "urlrewrite": [{ "newurl": "https://www.google.com/search?q=$1", "last": true, "decode.before.match": true, "name": "googl", "pattern": "^/search/(.*)$" }], "session.needed": false, "roles": ["pp_everyone"], "name": "Google", "action": "proxy", "conditions": [{ "values": ["/search*"], "type": "path" }], "cookiesnapper": {} }, { "authorization": { "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.reason": "No access", "response.status": 403, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>403 No Access<\/h1><\/body><\/html>';}" }, "roles": [ "staff", "pp_identifiedusers" ], "server.identifier": "default" }, "request.headers": [ { "name": "authorization", "value": null }, { "name": "x-user", "value": null }, { "name": "x-forwarded-server", "value": null }, { "name": "user-agent", "value": null }, { "name": "Host", "value": "ekstrabladet.dk" }, { "name": "Referer", "value": null } ], "name": "Secret Destination", "action": "continue", "locations": [ { "proxy.destination": "ekstrabladet", "name": "EB", "action": "proxy", "conditions": [{ "values": ["localhost*"], "type": "host" }] }, { "proxy.destination": "google", "name": "Google", "action": "proxy", "conditions": [] } ], "conditions": [ { "ignorecase": true, "values": [ "/secret/*", "/secret", "{regex}^/verysecret.*$" ], "type": "path" }, { "values": ["*"], "type": "host" } ], "request.cookies": [{ "name": "pp_jsessionid", "value": null }], "ip.restriction": { "ranges": [{ "values": ["192.168.1.0/30"], "name": "Internal" }], "allowchange": false }, "authentication": { "plugins": [ "io.ceptor.authentication.AuthenticatorScript", "io.ceptor.authentication.AuthenticatorForms", "io.ceptor.authentication.AuthenticatorBasicAuth" ], "basicauth": { "realm": "ceptor", "required": false }, "forms": { "redirect": { "response.redirect": "/login.jsp", "action": "respond" }, "authenticationplugin": 9, "failure": { "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}", "action": "respond", "response.reason": "Invalid userid/password", "response.status": 403, "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}" }, "required": false }, "script": { "content.preload": false, "authentication.script": "authenticate();\r\n\r\nfunction authenticate() {\r\n // If already authenticated, just continue\r\n if (state.agent.isLoggedOn(state.id))\r\n return 'CONTINUE';\r\n \r\n try {\r\n var user = state.httpExchange.getRequestHeaders().getFirst('X-User');\r\n var pass = state.httpExchange.getRequestHeaders().getFirst('X-Password');\r\n if (user === null) {\r\n user = state.httpExchange.getQueryParameters().get('X-User').getFirst();\r\n }\r\n if (pass === null) {\r\n pass = state.httpExchange.getQueryParameters().get('X-Password').getFirst();\r\n }\r\n \r\n if (user === null || pass === null) {\r\n // Ignore if user or password is not supplied - making this type of authentication optional\r\n return 'CONTINUE';\r\n } else {\r\n state.trace.trace('About to logon from script with user: ' + user);\r\n // 9 is authentication plugin type\r\n state.agent.logon(state.id, 9, user, pass, null);\r\n return 'SUCCESS';\r\n }\r\n } catch(err) {\r\n state.gateway.sendAndLogError(state, 401, 'Authentication Required', err);\r\n return 'RESPOND';\r\n }\r\n}" } } }, { "proxy.destination": "demoapp", "roles": ["pp_everyone"], "name": "Local", "action": "proxy", "conditions": [{ "values": ["/*"], "type": "path" }], "request.cookies": [{ "name": "ppSessionId", "value": "%{REQUEST_ID}" }] }, { "response.contenttype": "text/html", "#description": "Deny access to everything, by default if no other rule is matching", "name": "Default", "action": "respond", "response.headers": [{ "name": "X-Access", "value": "Denied" }], "response.reason": "No access", "conditions": [{ "values": ["/*"], "type": "path" }], "response.status": 403, "response.content": "<html><head><title>No access<\/title><body><h1>403 No Access<\/h1><\/body><\/html>" } ], "gateway": {}, "listen": [] }
Locations configuration
Each location is stored in its own JSON object within the locations array.
You can add/remove and reorder Locations - they are processed in the order they appear. When the conditions for a location matches the request, the location will be processed - if its action is RESPOND or PROXY no further locations will be processed.
If a matched location has any nested locations defined, they will be processed before going down to the next location in the list.
When you press Add to add a new location, you get this prompt:
You should enter the unique name of the location, and optionally a description of it - it is often useful to enter a reason for its existence here - even if it might be obvious at first it is likely not so obvious in a few years.
Configuration for Each Specific Location
The configuration for each specific location looks like the screenshot below.
It has many sections below it - note that they are marked with a blank circle if no values are defined for that particular section, and a cog if something is defined for this section. This makes it easy to see if you need to look at a particular session when going through the configuration to view the settings for a particular location.
Location configuration
Name
Name of location - used for logging/tracing and diagnostics
Default: none, a unique name is required
JSON key: name
Description
Description of this location
Default: blank
JSON key: description
Location is enabled
If unchecked, This location is ignored and not processed - it is treated like it did not exist.
Default: true
JSON key: location.enabled
Session is needed
If unchecked, no session is needed, so no request ID, session ID etc. will be available for this location unless a previous location has retrieved the session. Note that authentication and IP checking will not be done if there is no session present.
You can turn this off if you want anonymous, unauthenticated access to parts of your site, e.g. if you have a publicly available static part that you have no interest in authenticating users, doing IP checking etc. - this will ensure as fast performance as possible, since the overhead is kept to a bare minimum.
JSON key: session.needed
Default: true
Session will only be established if conditions match
If checked, and if session is needed, a session will not be established before conditions are checked, so it will only be done if conditions match. Note that some conditions, such as those on user or group or some scripts/macros require a session so they will not work.
Default: false
JSON key: session.afterconditionsmatch
Override global session settings
If checked, this allows you to override the session settings per location - in that case, you will get a new screen as child of the location where you can specify session resolvers and settings. Note that unless "Session is needed" is checked, this option will not have any effect.
Also, bear in mind that once a location has obtained a session once during request processing, any subsequent resolvers are ignored since the session is already available.
JSON key: session.override
Default: false
Preload request content
If checked, request content will be preloaded into memory before processing this location this is required (and automatically enabled if conditions contain postparam values) for processing POST'ed request content.
Using this allows you to access request body in plugins / scripts for this or subsequently processed locations. Note that it affects performance slightly, and it requires increased memory use to store the request contents until the request is done.
Default: false
JSON key: content.preload
Valid HTTP Methods
Valid HTTP methods - default is OPTIONS|HEAD|GET|POST, you can specify a pattern with wildcards or use {regex} prefix to create regular expression match. If the request method does not match this pattern, HTTP error 405 is immediately sent back.
Default: OPTIONS|HEAD|GET|POST
JSON key: valid.methods
Action
Action to take for this location, can continue to next location, respond by writing a response back to the browser, proxy to a destination server or serve static resources.
Default: continue
JSON key: action
Proxy Destination
Destination to forward request to, if action is proxy.
Default: blank
JSON key: proxy.destination
Compress proxied responses
If set, and client indicates support for it (gzip/deflate) then responses sent to the client are compressed unless the destination server has already done so itself.
Default: true
JSON key: response.compress
Limits
Can be used to limit the number of concurrent requests, or requests per second for this location.
Limit Qualifier
Qualifier for limiting requests per second or concurrent requests - if not set, those limits apply for all requests for the given location, but if set, limits can be specified per IP address, per client ID or any other parameter you wish to use as a qualifier.
As an example, you can use %{REMOTE_ADDR}
to limit requests per client IP, or e.g. %{statevariable:client_id}
to apply limits to the client_id attribute within the session.
Note that limits and qualifiers are per location, so any expression you choose will only affect this location and not others.
Default: Blank, no value
JSON key: requestlimit.qualifier
Max requests per second
Maximum number of requests per second, set to 0 for no limit.
Default: 0 (no limit)
JSON key: request.persecond.max
Maximum concurrent requests
Maximum number of concurrent requests for this location - any additional requests will be queued up, or 0 for no limit.
Default: 0 (no limit)
JSON key: request.concurrent.max
Request queue size
If too many concurrent requests, this is the maximum number of requests that can be queued up.
If number of requests in the queue exceeds this limit, new ones will be denied with HTTP 513 to indicate to the client that the server is overloaded with concurrent requests and its queue is full.
Default: 1000
JSON key: request.queue.size
Max response bytes/s
If set to nonzero, limits the number of response bytes sent per second (per connection) to the client.
Default: 0
JSON key: response.maxsize.persecond
Location Script
Script
Script to execute when this location is triggered.
Whenever this location is hit, this script will be executed which provides a simple method of adding functionality you would otherwise need to do in a pipeline or authorization/authentication script.
This is a useful place to e.g. manipulate with the contents of the users' session and/or the request before further processing is done.
Default: none
JSON key: location.script
Pipeline Settings
See Pipelines and Tasks for more information about pipelines.
Pipeline
Specify pipeline name. A pipeline allows advanced functionality, such as calling multiple remote services, validating JSON, running scripts etc. If a name of an existing pipeline is specified here, it is called immediately after processing limits.
A task within a pipeline might elect to send a response, or proxy a request - and in that case the action in this location has no effect - request processing will then never be given back to this location.
JSON key: pipeline
Default: none.
Response settings (when action is "respond")
If action is set to RESPOND, then a response will be sent to the client with the information below. Note that the HTTP Response headers and cookies will also be added, if any are configured.
Note that Scripts and Macros can be used to specify these values dynamically based upon request content.
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 500
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
CookieSnapper
Configuration is stored in the JSON object cookiesnapper.
Note that CookieSnappers can be configured both for locations and destinations - they serve the exact same functionality, but in some cases it is easier to define them on destinations so they have effect for all locations proxying to a certain destination - in other cases you only want this enabled for some locations - e.g. if you only want this for certain browsers or other things your location conditions can decide upon.
Cookies to snap
Pattern defining which cookies to remove from the response and place into the session. Any cookies matching this pattern will be moved from the response to the session, and added on future requests.
Default value: blank
JSON key: pattern
Classifier
Classifier to use - here you can use %{} variables, such as %{HTTP_HOST} or %{script:xxxx} to specify the classifier or scope to restrict these cookies too.
The classifier can ensure that the cookies are not forwarded on all requests, but only where the next request has the same classifier - so if it is e.g. set to %{HTTP_HOST} then the cookie will only be added to future requests, if these request has the exact same hostname as this one.
If the classifier is left as "default" then if the next request has a different hostname, e.g. app2.mydomain.com then the cookie will be added to the request again, which is usually what you want.
Default value: "default"
JSON key: classifier
Plugins
Plugins are java or script code that can process request or response bodies - they can e.g. transform contents from one format to another, e.g. add encryption, verify signatures etc.
Plugin configuration is stored in the JSON Object plugin within the location JSON Object.
Request wrapper java class
Java class implementing ConduitWrapper<StreamSourceConduit> to process request body - see Plugins#JavaRequestWrapper for more information.
Default: none
JSON key: request.wrapper.class
Response wrapper java class
Java class implementing ConduitWrapper<StreamSinkConduit> to process response body - see Plugins#JavaResponseWrapper for more information.
Default: none
JSON key: response.wrapper.class
Request wrapper script
Script that processes request body - see Plugins#ScriptRequestWrapper for more information.
Default: none
JSON key: response.wrapper.script
Response wrapper script
Script that processes response body see Plugins#ScriptResponseWrapper for more information.
Default: none
JSON key: response.wrapper.script
Session
If "Override global session settings" is checked, you can configure the session settings specifically for this location. The same fields as in the global session configuration are available. JSON configuration is stored in a JSON Object called "session" inside the location JSON.
Invalid Session Action
If a session is not valid, you can specify what action to take - and decide to either respond/redirect to another page, or continue with a new anonymous session.
These configuration entries are stored in the JSON Object action.session.notvalid within the location.
Action if request contained invalid or timed out session ID
Action
Action to take for this location, if request had an invalid or timed out session ID. continue=go on without authenticating, respond=respond with configured response or redirect
If action is set to RESPOND, then a response will be sent to the client with the information below.
Note that Scripts and Macros can be used to specify these values dynamically based upon request content.
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 500
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Response Headers
Response headers can also be added to the response, if any are specified, they are in an JSON array called response.headers within the action.session.notvalid JSON object.
You can add headers by clicking "Add", then you get a popup where you can set the name and value of the header.
Once created, they are added to the JSON Array response.headers within the action.session.notvalid JSON object, as a new object with the attributes name and value set to the entered name and value.
Conditions
List of conditions required to match for this location - if no conditions, all requests will match.
You can add/remove and move conditions up and down - they will be checked in the order listed.
Conditions are stored in the JSON array conditions within the location object.
When you add a new condition, you need to fill out this dialog:
When you edit each specific condition, you do it in this dialog:
Here, you can edit the type, name and add/remove/edit values - a condition can have multiple values.
Condition match
Type
Type of condition.
You can select between these types:
- path
Request URI / Path - e.g. /*, /secret/* or *.png - host
Hostname of the request, e.g. app.*, *.my.domain or login.ceptor.io - cookie
Request cookie value (name must contain the name of cookie). - query
Request query parameter - /?param=value (name must be query parameter name). - postparam
A request POST parameter sent in a URL form-encoded POST request. (name must be post parameter name). - pathparam
A request path parameter - similar to query parameters, but separated with semicolon instead of question mark - e.g. /somepath;param=value;param2=value2 (name must be path parameter name). - method
Request HTTP method, e.g. GET, HEAD, POST, PUT etc. - scheme
Request scheme - either http or https. - header
The value of a specific HTTP request header, e.g. the Accept header (name must be HTTP request header name). - remoteip
The remote IP address the request originated from. - attribute
A request attribute - not part of the request, but can be the result of an earlier location - request attributes can be created by a location and reused in conditions for later locations. (name must contain the name of the attribute). - geoip
A specific Geo IP attribute, such as a country, ISP or city. (name must be set to isp, organization, countrycode, countryname, city, postalcode or region). - userid
A specific user ID (note that for this information to be available, the location needs to have the "Session is needed" flag set). - usergroup
A specific user group (note that for this information to be available, the location needs to have the "Session is needed" flag set). - script
This allows you to create a script which can use any means to decide what conditions are required to match, it could, for example, check a time interval or do complex validation of multiple session attributes and request content. - macro
Allows you to check the value of a macro, e.g. check if %{SERVER_ADDR} matches a specific IP address. - probability
Specify a percentage probability of match - this enables a condition that matches a percentage of the requests, e.g. 10% - use this to send e.g. 10 or 20% of requests to a different version than the rest to allow gradual upgrades that do not affect all users.
Default: none - must be selected.
JSON key: type
Name
For some types, a name is required. For query/pathparam/postparam it is the name of the query parameter. For header, it is the name of the request header. For attribute it is the name of the request attribute. For GeoIP, it is one of [isp, organization, countrycode, countryname, city, postalcode, region]
Default: none
JSON key: name
Values must NOT match
Reverse the check, so if one of the values match, the condition is NOT met.
Default: false
JSON key: deny
Lowercase before checking against value
If set, the attribute (e.g. path, query parmeter or username) will be converted to lowercase before being matched to one of the specified values.
Default: false
JSON key: lowercase
Values
List of possible values that this condition can match. The value is a pattern, where wildcards can be used and you can separate multiple entries with | - if prefixed with {regex} you can use a regular expression, and you can use {uripath} to make wildcards match all characters except forward slash.
If the type is set to script then the value contains a script which will be executed to check for a match. Note that it is very important that this script performs extremely well since it will be executed for all requests and might risk blocking other requests.
Default: none
JSON key: values is an array of strings, where each string is a single value.
Response Hooks
Configuration for response hooks are in the form of a JSON Array response.hooks
containing a number of JSON response hook objects inside a location.
Here, you can add Response Hooks, which are activated once the HTTP response header is read from a response proxied from the backend server. This gives you a chance to hook into the response and take another action, such as returning another response, changing headers or response code etc.
When adding an new Response Hook, you must type in the HTTP status code it should match - note that you can use wildcard characters to match, e.g. 302|307 or 3* or just 401
Response hooks are only triggered on responses coming back from requests having been proxied to backend servers.
As locations are processed, response hooks are added to a list in the request context - ready for processing once the response is retrieved.
A location's response hooks are always added to the beginning of this list - this makes it possible to create multiple response hooks for the same HTTP response codes, e.g. by adding generic handling first and then later override with more specialized handling for specific locations.
Below is an example of editing a single response hook.
Response Hook configuration
HTTP Response Status code
The HTTP response code that this hook is valid for - can contain wildcards or multiple status codes separated by pipe sign.
Default: none
JSON key: expected.response.status
Script
Script
Script to be executed once HTTP response header is read. This script can manipulate the contents of the headers and status code, or send another response instead.
The relevant variables in the context that can be used modified are:
/** This is meant for use by response hooks - The response status - only available after reading response headers */ public int proxyResponseStatusCode; /** This is meant for use by response hooks - The response headers read from the server we proxied to */ public HeaderMap proxyResponseHeaders; /** This is meant for use by response hooks - the connection to the server */ public ClientExchange proxyClientExchange; /** This is meant for use by response hooks - the currently executing response hook */ public Config.ResponseHook currentResponseHook;
The script can modify the HTTP response code, or the headers before they are processed by the rest of the gateway - the script is called immediately after retrieving the response from the backend, before any other actions are done.
The script can choose to create and send a response itself, or it can use the one defined in its response hook, by calling:
context.gateway.sendResponse(context, context.currentResponseHook.response);
Default: none
JSON key: script
Response settings
Send this response instead of proxied response
If checked, the defined response is sent instead of the response from the backend server, if not the response is defined and can be sent by the script, but it is not sent automatically.
Default: false
JSON key: respond
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 400
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Response Headers
Response headers can also be added to the response, if any are specified, they are in an JSON array called response.headers within the individual response hook JSON object.
You can add headers by clicking "Add", then you get a popup where you can set the name and value of the header.
Once created, they are added to the JSON Array response.headers within the response hook JSON object, as a new object with the attributes name and value set to the entered name and value.
URL Validation
URL Validation
Configuration for URL validation is stored in the JSON object url.validator
Enable URL validation
Enable or disable this URL validator
Default: false
JSON key: enabled
Verify URL Encoding
If set, verifies that URL Encoding is valid.
Default: true
JSON key: verify.encoding
Query param name max length
Max length of query parameter name, or 0 to disable validation.
Default: 1024
JSON key: query.key.maxlength
Query param value max length
Max length of query parameter value, or 0 to disable validation.
Default: 8192
JSON key: query.value.maxlength
URL max length
Max length of entire URL, or 0 to disable validation.
Default: 32768
JSON key: maxlength
Additional validation
Verify Full URL
If set (and if "Enable URL validation" is checked), verifies the full URL for validity using Apache URL Validator, this includes checking domain name for validity against whitelist of IANA validated top-level domains.
Default: true
JSON key: verify.fullurl
Authority Regex validation pattern
If specified, authority (first part of the url until the path starts) this pattern allows adding non IANA approved domain names, such as <b>.local</b> - here, you need a regular expression so make sure your expesssion only matches the minimum you need.
Default: null
JSON key: authority.regex
Parameter Validation
Parameter Validation allows you to validate path, POST and/or query parameters - you can use this to ensure that only valid characters are present in the parameters.
If you set the key to * and the value to
{regex}^[a-zA-Z0-9_]*$
Then you can ensure that all input only contains alphanumeric characters or underscore - any other content and the validation fails and the failure action will be executed (which usually means returning an error message to the client).
Parameter Validation configuration is stored in a JSON object called param.validator inside the location.
Parameter Validation
Require specified parameters
Determines if the specified parameters are required to be present in the request or not - if required, at least one parameter matching each specified key must be present or the request will fail. If not checked, the parameters are not required, but if they are present, they must have a value matching the pattern/regex in the value for the matching parameters.
Default: false
JSON Key: verify.params.required
Allow additional parameters
If checked, additional parameters not matching the ones specified in the parameter list are allowed - these additional parameters will not have their value checked.
Default: true
JSON Key: verify.params.extra.allowed
Verify query parameters
If checked, query parameters are validated, otherwise they are ignored.
Default: true
JSON Key: verify.queryparams
Verify POST parameters
If checked, POSTbparameters are validated, otherwise they are ignored.
Default: true
JSON Key: verify.postparams
Verify path parameters
If checked, path parameters are validated, otherwise they are ignored.
Default: true
JSON Key: verify.pathparams
Parameters
Contains a list of valid parameter key/values which are used in validating the input parameters.
You can add new parameters, remove or edit existing ones - if editing you get this dialog:
- Name Pattern
Specify a pattern or prefix with {regex} to specify a regular expression - used to specify the key/name of parameters to match. - Value Pattern
Specify a pattern or prefix with {regex} to specify a regular expression - used to specify the valid value of parameters matching the name pattern. - Lowercase name before comparing
Check to lowercase parameter name before comparing with the pattern. - Lowercase value before comparing
Check to lowercase parameter value before comparing with pattern.
JSON Key: verify.params - Contains an array of JSON Objects, each parameter object has these values;
- key - Key pattern - can optionally be prefixed by {regex} to specify a regular expression instead of a pattern with wildcards.
- value - Value pattern, can also be prefixed with {regex} to specify a regular expression.
- key.lowercase - If true, the key will be lowercased before comparing to the key pattern, essentially making the comparison case insensitive as long as the key is specified in lowercase in this parameter.
- value.lowercase - If true, the value will be lowercased before comparing to the pattern to check for a match.
Failure Action
Specifies what action to take if input parameter validation fails - usually you want to return an error response here.
JSON Configuration for this is stored within the failure JSON Object inside the param.validator object.
Action
Action to take for this location, if parameter validation fails, Either respond=respond with configured response or redirect, or proxy=forward request to a configured destination.
Default: respond
JSON key: action
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 400
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Response Headers
Response headers can also be added to the response, if any are specified, they are in an JSON array called response.headers within the failure JSON object.
You can add headers by clicking "Add", then you get a popup where you can set the name and value of the header.
Once created, they are added to the JSON Array response.headers within the failure JSON object, as a new object with the attributes name and value set to the entered name and value.
URL Rewrite
URL Rewrite allows you to rewrite URLs and change them.
URL Rewrite configuration is stored in a JSON object called urlrewrite within the location. This is an array of multiple JSON object, where each rule is its own object.
You can add, remove and reorder the rewrite rules.
When you press "Add" you get this screen where you can fill out the values.
When later editing the values, the screen looks like this:
URL Rewrite configuration
Name
Name of URL rewrite rule
Default: none
JSON key: name
Regex pattern
Regular expression pattern
Default: none - must be specified
JSON key: pattern
Regex flags
Flags are one or more regular expression flags separated by comma, semicolon or pipe sign.
The flags can be UNIX_LINES, CASE_INSENSITIVE, COMMENTS, LITERAL, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ,UNICODE_CHARACTER_CLASS - see javadoc for java.util.regex.Pattern for details
Default: blank
JSON key: pattern.flags
New URL
New URL to rewrite to - URL can include $<n> where <n> is the number matching the reqular expression group in the pattern - e.g. /abc/(.*)/def/(.*) can be rewritten to /ABC123/$1/DEF123/$2 where $1 and 2 are replaced with the value in the appropriate group.
Default: none
JSON key: newurl
Decode URL before matching
If set, URL will be decoded before matching - if not, URL will be encoded exactly as received from client.
Default: true
JSON key: decode.before.match
Remove all query params from request
If set, all query parameters will be removed from the request, if rewriting the URL - if false, query parameters are kept.
Default: false
JSON key: clear.query.params
Redirect
If set, redirect immediately (HTTP 302) to the new URL instead of continuing processing the next locations with the rewritten URL.
Default: false
JSON key: redirect
Last rule
If pattern matches and URL is rewritten, no more rewrite rules for this location will be executed - remaining ones will be skipped
Default: false
JSON key: last
Conditions
Like a location has conditions, the URL Rewrite rule also has conditions for when it will be triggered. You can add the same kind of conditions with the same rules as for locations.
These conditions are stored in the conditions JSON object within the specific URL Rewrite rule. See conditions above for explanation about each field.
IP Restriction
IP Restriction allows you to specify under which conditions the client is allowed to change IP address.
IP Restriction information is stored in a JSON Object called ip.restriction within the location.
IP Change Restriction configuration
Allow client to change IP address
Set to allow clients to change IP addresses during a session - when not set, clients are not allowed to change IP address.
Default: false
JSON key: allowchange
Max IPs in session
Max. number of IP address changes allowed within a session - all the IP addresses the client has used during the session are stored within it for audit logging purposes.
Default: 32
JSON key: ip.address.maxcount
GeoIP Type
GeoIP Type: One of: [none, isp, organization, country, city, distance, complex] - none means no GeoIP checking done, complex means complex GeoIP rules are run, and ISP, organization, country, city means change is allowed with the same country, ISP etc... - distance allows change within a max. distance in kilometres.
Note that setting this to anything other than NONE requires that the GeoIP databases are loaded by the session controller – see geoip.database setting for the session controller for details.
Also note that GeoIP data are not entirely accurate, depending on which level you look at. The Country and ISP data are fairly accurate, but organization, city and location accuracy is not as good.
If the client switches IP address, the state variable “clientipaddresslist” will contain the list of IP addresses (other than the one embedded in the session ID) that the client has used previously. Note that this state variable is only updated if it is less than 2048 characters to ensure a client cannot flood the session size by changing IPs.
Ceptor does not guarantee the accuracy of the GeoIP data. You can purchase more accurate databases directly from MaxMind.
Default: none
JSON key: geoip.type
GeoIP Distance
When GeoIP type is set to distance, this specifies max. kilometers allowed in distance.
Default: 100
JSON key: geoip.distance
GeoIP Complex Rules
List of complex GeoIP rules.
If type is set to COMPLEX, then these rules are enabled – here you can specify rules that allow very detailed control over which IP addresses it is possible for a user to switch between.
The format is: keyword=keyword OR keyword=”string pattern” or distance=km – multiple conditions can be added separated by &
These keywords exists: ip1, ip2, country1, country2, isp1, isp2, organization1, organization2, city1, city2,postal1, postal2, region1, region2, distance
The ones ending with “1” represent the original IP address and the ones with “2” represent the new IP that the user is switching to.
Let’s take a few simple rules….
country1=country2
Here, there is a match if both IP addresses are in the same country.
isp1=isp2
Here, there is a match if both IP addresses are behind the same ISP.
Now a little more complex…
country1=country2&country1=”SE|DK|FI|NO”
Here, switch is allowed within the same country, but ONLY if the country is Sweden, Denmark, Finland or Norway – users in other countries cannot switch IP.
country1=country2&country1=”SE|DK|FI|NO”&distance=200
Same as before, but only within a distance of 200 kilometres.
ip1=”2.104.*”&ip2=”2.104.*”&isp1=”Tele*|Telia”
Here, switch is allowed for IP addresses 2.104.xxx.xxx but only if the original ISP matches the pattern “Tele*” or “Telia”.
So, as you can see you can create some quite powerful and details rules to control exactly when switching is allowed.
If a single rule in the list matches, access is allowed and no further checking is done against the other rules in the list. The log ins contains detailed information when IP switching was allowed, including the name of the rule that allowed access.
After changing these rules (especially the more complex ones), it is a good idea to monitor the logs to verify that they work as intended.
Default: none
JSON key: geoip.complexrules is an JSON Array containing a number of strings, where each string is a GeoIP Complex rule.
IP Checking script
Script code runs to check if IP change is allowed.
See Plugins#IPcheckerscript for more information and samples.
Default: none
JSON key: script
IP Ranges
IP change can also be restricted to specific ranges - you can specify multiple different ranges of IP addresses and allow switching from one address within a range to another in the same range.
IP Ranges are stored within the ip.restriction JSON object as ranges which is an array of JSON Objects, one for each range.
Here, you can add and remove ranges.When pressing "Add" you need to type in a name for a range.
When editing a range, you have these attributes:
IP Range
Name
Name of IP Range
Default: none
JSON key: name
IPs
List of values in range, prefix with {file} to read from a file.
Can be specified in the following formats
- Single IP Address - e.g. 127.0.0.1
- IP Range - e.g. 192.168.1.1-192.168.1.16
- CIDR bits notation - e.g. 192.168.1.0/30
- CIDR netmask notation - e.g. 192.168.1.0/255.255.255.0
File containing ranges - e.g. {file}/filename.txt
Default: none
JSON key: values which are an array of strings - each string an entry in the list.
Failure Action
If the IP change was not allowed, this specifies what happens.
Action when IP is not valid
JSON Configuration is stored within a JSON object named action.invalid within the ip.restriction object.
Action
Action to take for this location, if IP change was not valid. continue=go on without authenticating, respond=respond with configured response or redirect, and proxy=proxy onwards to destination (you rarely want this).
If action is set to RESPOND, then a response will be sent to the client with the information below.
Note that Scripts and Macros can be used to specify these values dynamically based upon request content.
Default: respond
JSON key:
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 500
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Response Headers
Response headers can also be added to the response, if any are specified, they are in an JSON array called response.headers within the action.invalid JSON object.
You can add headers by clicking "Add", then you get a popup where you can set the name and value of the header.
Once created, they are added to the JSON Array response.headers within the action.invalid JSON object, as a new object with the attributes name and value set to the entered name and value.
Authentication
Authentication configuration is described here: Location - Authentication
Authorization
You can specify authorization checking for a location - which is used to check if the authenticated user has access to the location or not.
Configuration is stored within the JSON Object authorization within the location.
Authorization
OPTIONS method bypasses authorization
Check this if you do not want to attempt authorization for OPTIONS requests - this is required for CORS preflight requests to work in most browsers. Do take care to ensure you are not allowing access to anything you do not mean to, although the OPTIONS method in itself should be perfectly safe.
Default: false
JSON Key: noauthorization.for.options
Required roles
List of roles/groups - if any roles are specified, at least one of them is required to access the resources.
Default: none
JSON key: roles which are an JSON Array of strings, each string is a role name.
Server Identifier
Server identifier - used for additional role checking where an authorization plugin in the session controller might specify additional protected URLs that require other roles than those listed above. - set to "none" to disable.
An Authorization plugin in the session controller keeps track of protected URLs for different identifiers, so it might be configured with other protected resources than you have here - if the server id is not set to "none" then the authorization plugin is consulted too.
Default: default
JSON key: server.identifier
Permission Name
Specify a permission that you need to have to get access to this location. See Authorization for more information.
Permissions and ACLs can contain very advanced functionality, such as ABAC (Attribute Based Access Control) - see Authorization for more information. Note that some of these might result in a performance overhead.
You can always check the Gateway Tracing to see the details about each request and diagnose any performance issues.
Default: none
JSON key: permission.name
Scope name
Name of scope that the user needs to successfully complete authorization.
Note that scope is only available when authenticating using OpenID Connect, API Key or bearer token related authentication methods - the scope is part of the OAuth2 / OpenID Connect protocols.
Default: none
JSON key: scope.name
IP Range
Name of IP Range to require for successful authorization - the callers remote IP must be in the configured range, or authorization will fail.
Default:none
JSON key: iprange
Authorization script
Script which can do custom authorization - the script must return true or false.
See Plugins - AuthorizationScript for an example.
Default: none
JSON key: authorization.script
Authorization Failure
If authorization fails, you can specify what response to send back to the client.
The configuration is stored in the JSON Object failure within the authorization object.
Action when authorization fails
Action
Action to take for this location, if authorization fails. continue=go on without authenticating, respond=respond with configured response or redirect, or proxy=forward request to a configured destination.
Default: respond
JSON key: action
Canned Response
Specify the name of a "canned" response here to reuse it - when set, the response sent back will be the one defined in the canned response - if any other values are specified here, HTTP response code, reason etc. then these values overwrite what was specified in the canned response. Any headers defined will complement the ones specified for the canned response.
Default: none
JSON key: response.name
HTTP Response code
HTTP Response code to send back to client.
Default: 500
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Response Headers
Response headers can also be added to the response, if any are specified, they are in an JSON array called response.headers within the failure JSON object.
You can add headers by clicking "Add", then you get a popup where you can set the name and value of the header.
Once created, they are added to the JSON Array response.headers within the failure JSON object, as a new object with the attributes name and value set to the entered name and value.
Request Attributes
Request Attributes can be set by specific locations, and used later by conditions in other locations, or by scripts. They can be useful for chaining locations, or extracting information once from e.g. a query / header parameter, and making it available for other locations/scripts.
If you click "Add" to add a new attribute, you can enter its name and value here:
Note that you can use Scripts and Macros to obtain the value.
Request attributes are stored in a JSON Array: request.attributes which contain an array of JSON Objects. Each object contains an attribute (name and value).
Attribute configuration
Name
Name of request attribute.
Default: none, must be entered
JSON key: name
Value
Value of the attribute - can be obtained using Scripts and Macros
Default: blank
JSON key: value
Request Headers
Here, you can modify the request headers that will later be sent to a target server when proxied to it.
Normally, you want to use this to add headers to the request, e.g. containing information about the user, attributes from the session, or the IP address / TCP Port of the client.
Configuration for request headers is stored in the JSON array request.headers within the location - each element in the array is a JSON Object containing a name and value.
If the value is an empty string, or null then the corresponding header will be removed from the request in case it was present already.
When you click Add, you get a dialog where you can enter a name and value:
You can edit the header name/value after adding it on this screen:
HTTP Header configuration
Name
Name of HTTP Request header to add or replace
Default: none, must be specified
JSON key: name
Value
Value of the HTTP Request header - set to an empty string or null to remove the header instead of adding it.
You can use Scripts and Macros to generate the value.
Default: blank
JSON key: value
Request Cookies
Like with HTTP Headers, you can also add cookies to the request.
Configuration for request cookies is stored in an array of JSON Objects, called request.cookies - each element in the array contains the details for a single cookie.
Click "Add" to add a new cookie.
Here, you must enter only the name and value of the request cookie you wish to add.
Once entered, you can edit it where you get a chance to change all the available attributes for the cookie:
Cookie configuration
Please note that for request cookies, the only real relevant values here are name and value. The rest makes more sense for response cookies.
Name
Name of cookie
Default: none
JSON key: name
Value
HTTP Cookie value
Default: none
JSON key: value
Path
HTTP Cookie path
Default: none
JSON key: path
Domain
HTTP Cookie domain
Default: none
JSON key: domain
Max Age (seconds)
Max-Age in seconds - beware of Internet Explorer which does not support this setting properly
Default: null
JSON key: maxage
Secure
Cookie is secure, meaning it will only be sent via encrypted https connections
Default: false
JSON key: secure
Http only
Cookie is marked as http only, meaning it will not be visible to javascript running in the browser
Default: false
JSON key: httponly
Discard
Instruct browser to discard cookie when browser terminates
Default: false
JSON key: discard
Version
Cookie version
Default: null
JSON key: version
Expires
Date/time when cookie expires
Default: null
JSON key: expires
Comment
Cookie comment - rarely used
Default: null
JSON key: comment
Response Headers
You can configure HTTP Response Headers that are added to the response before sending it.
Response headers are stored in a JSON Array called response.headerswithin the location.
When you click "Add", you get the dialog below, where you can specify the name and value of the response header to add:
Once a header is added, you can edit it on this screen:
HTTP header configuration
Name
Name of HTTP Header
Default: none, must be specified
JSON key: name
Value
Value of HTTP Header
You can use macros to change the value of a header from one thing to another - e.g. with this example:
%{rewrite:responseheader:location;"http\:\/\/(.*)$";"CASE_INSENSITIVE";"https://$1"}
Here, if the Location header starts with http:// then its value is changed to https:// and then the rest of the header.
Default: empty
JSON key: value
Response Cookies
Like with response headers, you can add cookies
Configuration for response cookies is stored in a JSON Array called response.cookies in the location object. Each element in the array is a JSON object with the individual cookie configuration.
When clicking "Add", you can enter the cookie name and value.
After adding a cookie, you can edit the details to provide the remaining information.
Cookie configuration
Name
Name of cookie
Default: none
JSON key: name
Value
HTTP Cookie value
Default: none
JSON key: value
Path
HTTP Cookie path
Default: none
JSON key: path
Domain
HTTP Cookie domain
Default: none
JSON key: domain
Max Age (seconds)
Max-Age in seconds - beware of Internet Explorer which does not support this setting properly
Default: null
JSON key: maxage
Secure
Cookie is secure, meaning it will only be sent via encrypted https connections
Default: false
JSON key: secure
Http only
Cookie is marked as http only, meaning it will not be visible to javascript running in the browser
Default: false
JSON key: httponly
SameSite
If set to lax or scrict, the cookie attribute SameSite=Strict or SameSite=Lax is added to the session cookies. This enables CSRF/XSRF attack protection - see https://tools.ietf.org/html/draft-west-first-party-cookies-07 for details.
Default: none
JSON key: samesite
Discard
Instruct browser to discard cookie when browser terminates
Default: false
JSON key: discard
Version
Cookie version
Default: null
JSON key: version
Expires
Date/time when cookie expires
Default: null
JSON key: expires
Comment
Cookie comment - rarely used
Default: null
JSON key: comment
WebServer
WebServer configuration is available if action is set to serve and is stored in the JSON object webserver within the location object.
If the location's action is set to serve then static resources are served for this location.
WebServer - Serve static resources
Path
Path to the directory on the gateway machine where files are served from.
Default: none, must be specified
JSON key: path
Case sensitive filenames
If checked, file and directory names are considered case sensitive
Default: false
JSON key: case.sensitive
Directory listing enabled
If checked, directory listing is allowed - note that this will reveal all files in the path and subdirectories to the caller
Default: false
JSON key: directory.listing.enabled
Canonicalize paths
If checked, paths are canonicalized, meaning .. and . are resolved before attempting to read the file.
Default: true
JSON key: paths.canonicalize
Follow symbolic links
If checked, symbolic links are resolved if they exist in the base path - note that "Safe paths" can be used to limit the safe paths that are valid for any eventual links.
Default: false
JSON key: follow.links
Safe paths
If "Follow symbolic links" is checked, this can limit the safe paths that files can be served from.
If left empty, all symlinks in the base path and in the paths the symlinks point to are allowed to serve files from.
Use semicolon or comma to separate pathnames.
Default: blank, meaning no limits defined if "Follow symbolic links" is checked.
JSON key: safe.paths
Minimum filesize to enable OS transfer
Size in bytes to use direct FS to network transfer (if supported by OS/JDK) instead of read/write.
For smaller files, the overhead of using the OS to transfer the files is larger, but for larger files the overall performance is better.
Default: 1024
JSON key: transfer.minsize
Cache settings
Enable caching of files
If checked, files are cached instead of loading them from disk on every access. If not checked none of the remaining options in this section are used.
Default: true
JSON key: cache.enabled
Monitor changes in base path
If checked, we attempt to ask the OS to listen for changes to files in the path and invalidate cache entries if a file is updated.
Note that on network drives this can lead to some overhead.
Default: false
JSON key: cache.changelistener
File count
Maximum number of files to cache at one time.
Default: 1024
JSON key: cache.item.count
File max size
Maximum size in bytes of a file to place in the cache.
Default: 1048576 (1mb)
JSON key: cache.file.maxsize
Age in seconds
"Time in seconds to cache a single file for - note that if "Monitor changes in base path" is checked and if the OS/JVM supports it then we will detect and invalidate the cache if a file has changed on disk
Default: 300
JSON key: cache.age.seconds
Cache memory limit
Memory limit for the disk cache - default is set to 10mb to conserve memory. Note that the cache is in native memory so java heap size is not affected
Default: 10485760 (10mb)
JSON key: cache.memory.bytes
404 Not Found Response
This response will be sent if the browser requests a resource which was not found. If not defined, a simple html page containing only the words "Not found" in the body will be returned.
This section is stored in a JSON object response.notfound inside the webserver JSON object.
HTTP Response code
HTTP Response code to send back to client, should be 404
Default: 500
JSON key: response.status
HTTP Response reason
HTTP response reason text
Default: No additional information
JSON key: response.reason
Redirect Location
Response Redirect Location URL - if set, a redirect will be sent instead of a normal response, the Location header in the response will be set to this value.
Default: none
JSON key: response.redirect
Content-Type
HTTP Response content-type
Default: none
JSON key: response.contenttype
Response Body
Response body contents
Default: none
JSON key: response.body
Nested Locations
Nested locations are stored in the JSON object locations within the location object.
Nested locations can be added/removed and reordered just like regular locations.
A nested configuration is checked and processed only if the parent location conditions match and only when the action of the parent is set to CONTINUE - meaning only when the request has not already been proxied to somewhere else and when no response has been sent back to the client yet.
© Ceptor ApS. All Rights Reserved.