HTTP Rules
You can define HTTP rules to control HTTP response headers for any requests received by the 4D web server, including REST requests. You can add, modify, or remove HTTP headers, send redirections or set the HTTP status. This feature is useful to implement security policies based upon the handling of headers.
To define HTTP rules, you just need to write some RegEx to declare the URL patterns you want to control, as well as how to modify response headers. You can set these rules using a HTTPRules.json
file stored in the project folder, or using the settings parameter start()
function of the web server object.
要件
HTTP rules are supported in the following contexts:
- scalable sessions or no sessions are enabled,
- a web server run locally by 4D or 4D Server, including those run by components.
How to set rules
You can declare HTTP response rules:
- in a configuration file named HTTPRules.json stored in the
Project/Sources
folder of the project. Rules are loaded and applied in the main Web server once it is started. - using a
.rules
property set in the settings parameter of thestart()
function, for any web server object:
WEB Server.start($settings.rules) //set rules at web server startup
If both a HTTPRules.json file and a call to the WEB Server
command with a valid $settings.rules
are used, the WEB Server
command has priority.
If the URI of the request does not match any of the RegEx patterns, the web server returns a default response.
Rules Definition
The HTTPRules.json file or the .rules
property must contain a collection of rule objects.
A rule object is defined by:
- a RegEx describing a URL pattern, e.g. "^(.*\.(jpg|jpeg|png|gif))"
- the name of the action to execute for the HTTP response, e.g. "removeHeaders"
- the value of the action, e.g. "X-Unwanted-Header1"
Other properties are ignored.
URL パターン
URL patterns are given using regular expressions. To declare a regular expression pattern, use the "RegExPattern" property name.
Ex: "RegExPattern": "/Test/Authorized/(.*)"
When the web server receives a request, all URL patterns are triggered sequentially in the given order, and all matching patterns are executed. In case of several actions modifying similar resources, the last executed action is taken into account.
アクション
The following action keywords are supported:
キーワード | 値の型 | 説明 |
---|---|---|
removeHeaders | Text or Collection of texts | Header(s) to remove from the HTTP responses. If a header to remove does not exist in the response header, it is ignored. |
addHeaders | Object | Name (text) and value (text) of header(s) to add to the HTTP responses. |
setHeaders | Object | Name (text) and value (text) of header(s) to modify in the HTTP responses. If a header to modify does not exist in the response header, it is added. |
denyAccess | Boolean | true to deny access to the resource, false to allow access. When the access to a resource is denied, the web server returns a 403 status by default |
redirect | Text | Redirection URL. When a redirection is triggered, the web server returns a 302 status by default |
status | Number | HTTP status |
Non-modifiable headers
The following headers could not be modified by the removeHeaders
, setHeaders
, or addHeaders
actions:
- "日付",
- "Content-Length"
Modifying these headers do not generate errors, however modifications will be ignored.
Current rules
You can know the current rules using the .rules
property of the Web Server object:
var $rules : Collection
$rules:=WEB Server.rules //current rules
例題
Rules can be set using a HTTPRules.json
file or the settings parameter of the .start()
web server function.
Using a HTTPRules.json file
[
{
"comment": "All requests: allow GET method for, remove 'Server' header and set security headers",
"regexPattern": "/(.*)",
"setHeaders": {
"Allow": "GET",
"X-Frame-Options": "SAMEORIGIN",
"Content-Security-Policy": "default-src 'self'"
},
"removeHeaders": [
"Server"
]
},
{
"comment": "REST requests: allow POST method",
"regexPattern": "/rest/(.*)",
"addHeaders": {
"Allow": "POST"
}
},
{
"comment": "HTML files in 'doc' folder: set cache control",
"regexPattern": "/docs/(.*).html",
"setHeaders": {
"Cache-Control": "max-age=3600"
},
"removeHeaders": [
"X-Powered-By"
]
},
{
"comment": "Status 503 on 'maintenance' page",
"regexPattern": "^/maintenance.html",
"status": 503
},
{
"comment": "Redirect CSS and JS files",
"regexPattern": "^(.*\\\\.(css|js))",
"redirect": "https://cdn.example.com/"
},
{
"comment": "Redirect images with permanent status code",
"regexPattern": "^(.*\\\\.(jpg|jpeg|png|gif))",
"redirect": "https://cdn.example.com/images/",
"status": 301
},
{
"comment": "Deny access for all resources placed in the 'private' folder",
"regexPattern": "/private/(.*)",
"denyAccess": true
},
{
"comment": "Allow access to all resources placed in the 'private/allowed' folder",
"regexPattern": "/private/allowed/(.*)",
"denyAccess": false
}
]
Using a settings parameter
var $rule:={}
var $settings:={}
$settings.rules:=[]
$rule:={}
$rule.comment:="All requests: allow GET method for, remove 'Server' header and set security headers"
$rule.regexPattern:="/(.*)"
$rule.setHeaders:={Allow: "GET"}
$rule.setHeaders["X-Frame-Options"]:="SAMEORIGIN"
$rule.setHeaders["Content-Security-Policy"]:="default-src 'self'"
$rule.removeHeaders:=["Server"]
$settings.rules.push($rule)
$rule:={}
$rule.comment:="REST requests: allow POST method"
$rule.regexPattern:="/rest/(.*)"
$rule.addHeaders:={Allow: "POST"}
$settings.rules.push($rule)
$rule:={}
$rule.comment:="HTML files in 'doc' folder: set cache control"
$rule.regexPattern:="/docs/(.*).html"
$rule.setHeaders:={}
$rule.setHeaders["Cache-Control"]:="max-age=3600"
$rule.removeHeaders:=["X-Powered-By"]
$settings.rules.push($rule)
$rule:={}
$rule.comment:="Status 503 on 'maintenance' page"
$rule.regexPattern:="^/maintenance.html"
$rule.status:=503
$settings.rules.push($rule)
$rule:={}
$rule.comment:="Redirect CSS and JS files"
$rule.regexPattern:="^(.*\\\\.(css|js))"
$rule.redirect:="https://cdn.example.com/"
$settings.rules.push($rule)
$rule:={}
$rule.comment:="Redirect images with permanent status code"
$rule.regexPattern:="^(.*\\\\.(jpg|jpeg|png|gif))"
$rule.redirect:="https://cdn.example.com/images/"
$rule.status:=301
$settings.rules.push($rule)
$rule:={}
$rule.comment:="Deny access for all resources placed in the 'private' folder"
$rule.regexPattern:="/private/(.*)"
$rule.denyAccess:=True
$settings.rules.push($rule)
$rule:={}
$rule.comment:="Allow access to all resources placed in the 'private/allowed' folder"
$rule.regexPattern:="/private/allowed/(.*)"
$rule.denyAccess:=False
$settings.rules.push($rule)
$return:=WEB Server.start($settings)