rest {
	#
	#  This subsection configures the tls related items
	#  that control how FreeRADIUS connects to a HTTPS
	#  server.
	#
	tls {
		#  Certificate Authorities:
		#  "ca_file" (libcurl option CURLOPT_ISSUERCERT).
		#    File containing a single CA, which is the issuer of the server
		#    certificate.
		#  "ca_info_file" (libcurl option CURLOPT_CAINFO).
		#    File containing a bundle of certificates, which allow to handle
		#    certificate chain validation.
		#  "ca_path" (libcurl option CURLOPT_CAPATH).
		#    Directory holding CA certificates to verify the peer with.
#		ca_file = ${certdir}/cacert.pem
#		ca_info_file = ${certdir}/cacert_bundle.pem
#		ca_path = ${certdir}

#		certificate_file        = /path/to/radius.crt
#		private_key_file        = /path/to/radius.key
#		private_key_password    = "supersecret"
#		random_file             = /dev/urandom

		#  Server certificate verification requirements.  Can be:
		#    "no"  (don't even bother trying)
		#    "yes" (verify the cert was issued by one of the
		#          trusted CAs)
		#
		#  The default is "yes"
#		check_cert = yes

		#  Server certificate CN verification requirements.  Can be:
		#    "no"  (don't even bother trying)
		#    "yes" (verify the CN in the certificate matches the host
		#          in the URI)
		#
		#  The default is "yes"
#		check_cert_cn = yes
	}

	# rlm_rest will open a connection to the server specified in connect_uri
	# to populate the connection cache, ready for the first request.
	# The server will not start if the server specified is unreachable.
	#
	# If you wish to disable this pre-caching and reachability check,
	# comment out the configuration item below.
	#
	connect_uri = "http://127.0.0.1"

	#
	# When set, connects to the server over a UNIX socket which may be
	# helpful for those with (pseudo)security constraints that make it
	# easier to use an UNIX socket than explain to an auditor the use of
	# non-TLS HTTP localhost connections.
	#
	# NOTE: This is not allowed to be an xlat as it can lead to security issues.
	#
#	connect_uri_socket = "/run/myprogram.sock"

	#
	# When set, connect_uri_socket is an abstract UNIX socket
	#
#	connect_uri_socket_abstract = "no"

	#
	#  How long before new connection attempts timeout, defaults to 4.0 seconds.
	#
#	connect_timeout = 4.0

	#
	# Specify HTTP protocol version to use. one of '1.0', '1.1', '2.0', '2.0+auto',
	# '2.0+tls' or 'default'. (libcurl option CURLOPT_HTTP_VERSION)
	#
#	http_negotiation = 1.1

	#
	#  The following config items can be used in each of the sections.
	#  The sections themselves reflect the sections in the server.
	#  For example if you list rest in the authorize section of a virtual server,
	#  the settings from the authorize section here will be used.
	#
	#  The following config items may be listed in any of the sections:
	#    uri          - to send the request to.
	#    method       - HTTP method to use, one of 'get', 'post', 'put', 'patch',
	#                   'delete' or any custom HTTP method.
	#    body         - The format of the HTTP body sent to the remote server.
	#                   May be 'none', 'post' or 'json', defaults to 'none'.
	#    attr_num     - If true, the attribute number is supplied for each attribute.
	#                   Defaults to false.
	#    raw_value    - If true, enumerated attribute values are provided as numeric
	#                   values. Defaults to false.
	#    data         - Send custom freeform data in the HTTP body. Content-type
	#                   may be specified with 'body'. Will be expanded.
	#                   Values from expansion will not be escaped, this should be
	#                   done using the appropriate xlat method e.g. %{urlencode:<attr>}.
	#    force_to     - Force the response to be decoded with this decoder.
	#                   May be 'plain' (creates reply:REST-HTTP-Body), 'post'
	#                   or 'json'.
	#    tls          - TLS settings for HTTPS.
	#    auth         - HTTP auth method to use, one of 'none', 'srp', 'basic',
	#                   'digest', 'digest-ie', 'gss-negotiate', 'ntlm',
	#                   'ntlm-winbind', 'any', 'safe'. defaults to 'none'.
	#    username     - User to authenticate as, will be expanded.
	#    password     - Password to use for authentication, will be expanded.
	#    require_auth - Require HTTP authentication.
	#    timeout      - HTTP request timeout in seconds, defaults to 4.0.
	#    chunk        - Chunk size to use. If set, HTTP chunked encoding is used to
	#                   send data to the REST server. Make sure that this is large
	#                   enough to fit your largest attribute value's text
	#                   representation.
	#                   A number like 8192 is good.
	#
	#  Additional HTTP headers may be specified with control:REST-HTTP-Header.
	#  The values of those attributes should be in the format:
	#
	#	control:REST-HTTP-Header := "<HTTP attribute>: <value>"
	#
	#  You should set this attribute before calling the rest module,
	#  via something like the following example.  Note that you MUST
	#  update the HTTP attribute and key value to whatever is needed on
	#  your local system.  The values given in this example are likely
	#  to not work for your system.
	#
	#	update control {
	#		&REST-HTTP-Header := "x-api-key: abcdefsupersecret"
	#	}
	#	rest
	#
	#  The control:REST-HTTP-Header attributes will be consumed
	#  (i.e. deleted) after each call to the rest module, and each
	#  %{rest:} expansion.  This is so that headers from one REST
	#  call do not affect headers from a different REST call.
	#
	#  Body encodings are the same for requests and responses
	#
	#  POST - All attributes and values are urlencoded
	#  [outer.][<list>:]<attribute0>=<value0>&[outer.][<list>:]<attributeN>=<valueN>
	#
	#  JSON - All attributes and values are escaped according to the JSON specification
	#  - attribute  Name of the attribute.
	#  - attr_num   Number of the attribute. Only available if the configuration item
	#               'attr_num' is enabled.
	#  - type       Type of the attribute (e.g. "integer", "string", "ipaddr", "octets", ...).
	#  - value      Attribute value, for enumerated attributes the human readable value is
	#               provided and not the numeric value (Depends on the 'raw_value' config item).
	#  {
	#      "<attribute0>":{
	#          "attr_num":<attr_num0>,
	#          "type":"<type0>",
	#          "value":[<value0>,<value1>,<valueN>]
	#      },
	#      "<attribute1>":{
	#          "attr_num":<attr_num1>,
	#          "type":"<type1>",
	#          "value":[...]
	#      },
	#      "<attributeN>":{
	#          "attr_num":<attr_numN>,
	#          "type":"<typeN>",
	#          "value":[...]
	#      },
	#  }
	#
	#  The response format adds three optional fields:
	#  - do_xlat    If true, any values will be xlat expanded. Defaults to true.
	#  - is_json    If true, any nested JSON data will be copied to the attribute
	#               in string form. Defaults to true.
	#  - op         Controls how the attribute is inserted into the target list.
	#               Defaults to ':='. To create multiple attributes from multiple
	#               values, this should be set to '+=', otherwise only the last
	#               value will be used, and it will be assigned to a single
	#               attribute.
	#  {
	#      "<attribute0>":{
	#          "is_json":<bool>,
	#          "do_xlat":<bool>,
	#          "op":"<operator>",
	#          "value":[<value0>,<value1>,<valueN>]
	#      },
	#      "<attribute1>":"value",
	#      "<attributeN>":{
	#          "value":[<value0>,<value1>,<valueN>],
	#          "op":"+="
	#      }
	#  }

	#
	#  Module return codes are determined by HTTP response codes. These vary depending on the
	#  section.
	#
	#  If the body is processed and found to be malformed or unsupported fail will be returned.
	#  If the body is processed and found to contain attribute updated will be returned,
	#  except in the case of a 401 code.
	#

	#  Authorize/Authenticate
	#
	#  Code   Meaning       Process body  Module code
	#  404    not found     no            notfound
	#  410    gone          no            notfound
	#  403    forbidden     no            userlock
	#  401    unauthorized  yes           reject
	#  204    no content    no            ok
	#  2xx    successful    yes           ok/updated
	#  5xx    server error  no            fail
	#  xxx    -             no            invalid
	#
	#  The status code is held in %{reply:REST-HTTP-Status-Code}.
	#
	authorize {
		uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=authorize"
		method = 'get'
		tls = ${..tls}
	}
	authenticate {
		uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=authenticate"
		method = 'get'
		tls = ${..tls}

		#
		#  Note that you CANNOT set 'username' or 'password'
		#  here.  When doing user authentication, the module
		#  uses the User-Name and User-Password.
		#
	}

	#  Preacct/Accounting/Post-auth/Pre-Proxy/Post-Proxy
	#
	#  Code   Meaning       Process body  Module code
	#  204    no content    no            ok
	#  2xx    successful    yes           ok/updated
	#  5xx    server error  no            fail
	#  xxx    -             no            invalid
	preacct {
		uri = "${..connect_uri}/user/%{User-Name}/sessions/%{Acct-Unique-Session-ID}?action=preacct"
		method = 'post'
		tls = ${..tls}
	}
	accounting {
		uri = "${..connect_uri}/user/%{User-Name}/sessions/%{Acct-Unique-Session-ID}?action=accounting"
		method = 'post'
		tls = ${..tls}
	}
	post-auth {
		uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=post-auth"
		method = 'post'
		tls = ${..tls}
	}
	pre-proxy {
		uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=pre-proxy"
		method = 'post'
		tls = ${..tls}
	}
	post-proxy {
		uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=post-proxy"
		method = 'post'
		tls = ${..tls}
	}

	#  Options for calling rest xlats
	#  uri and method will be derived from the string provided to the xlat
	xlat {
		#
		#  The whole string passed to a REST xlat is URI encoded.
		#  With body_uri_encode = yes, any body data will remain encoded.
		#  With body_uri_encode = no, the body data will be decoded and sent as provided.
		#
		body_uri_encode = yes
		tls = ${..tls}
	}

	#
	#  The connection pool is used to pool outgoing connections.
	#
	pool {
		#  Connections to create during module instantiation.
		#  If the server cannot create specified number of
		#  connections during instantiation it will exit.
		#  Set to 0 to allow the server to start without the
		#  web service being available.
		start = ${thread[pool].start_servers}

		#  Minimum number of connections to keep open
		min = ${thread[pool].min_spare_servers}

		#  Maximum number of connections
		#
		#  If these connections are all in use and a new one
		#  is requested, the request will NOT get a connection.
		#
		#  Setting 'max' to LESS than the number of threads means
		#  that some threads may starve, and you will see errors
		#  like 'No connections available and at max connection limit'
		#
		#  Setting 'max' to MORE than the number of threads means
		#  that there are more connections than necessary.
		max = ${thread[pool].max_servers}

		#  Spare connections to be left idle
		#
		#  NOTE: Idle connections WILL be closed if "idle_timeout"
		#  is set.  This should be less than or equal to "max" above.
		spare = ${thread[pool].max_spare_servers}

		#  Number of uses before the connection is closed
		#
		# 0 means "infinite"
		uses = 0

		#  The number of seconds to wait after the server tries
		#  to open a connection, and fails.  During this time,
		#  no new connections will be opened.
		retry_delay = 30

		#  The lifetime (in seconds) of the connection
		lifetime = 0

		#  idle timeout (in seconds).  A connection which is
		#  unused for this length of time will be closed.
		idle_timeout = 60

		#  NOTE: All configuration settings are enforced.  If a
		#  connection is closed because of "idle_timeout",
		#  "uses", or "lifetime", then the total number of
		#  connections MAY fall below "min".  When that
		#  happens, it will open a new connection.  It will
		#  also log a WARNING message.
		#
		#  The solution is to either lower the "min" connections,
		#  or increase lifetime/idle_timeout.
	}
}
