-- Copyright 2014-2015 Christian Schoenebeck -- Licensed under the Apache License, Version 2.0 local NXFS = require "nixio.fs" local SYS = require "luci.sys" local UTIL = require "luci.util" local DISP = require "luci.dispatcher" local DTYP = require "luci.cbi.datatypes" local CTRL = require "luci.controller.privoxy" -- this application's controller local HELP = [[%s]] -- Error handling if wrong privoxy version installed -- ######################## if not CTRL.service_ok() then local f = SimpleForm("_sf") f.title = CTRL.app_title_main() f.description = CTRL.app_description() f.embedded = true f.submit = false f.reset = false local s = f:section(SimpleSection) local v = s:option(DummyValue, "_dv") v.titleref = DISP.build_url("admin", "system", "packages") v.rawhtml = true v.value = CTRL.service_update() return f end -- ################################################################################################# -- Error handling if no config, create an empty one -- ######################### if not NXFS.access("/etc/config/privoxy") then NXFS.writefile("/etc/config/privoxy", "") end -- cbi-map -- ################################################################## local m = Map("privoxy") m.title = CTRL.app_title_main() m.description = CTRL.app_description() function m.commit_handler(self) if self.changed then -- changes ? os.execute("/etc/init.d/privoxy reload &") -- reload configuration end end -- cbi-section -- ############################################################## local ns = m:section( NamedSection, "privoxy", "privoxy") function ns.cfgvalue(self, section) if not self.map:get("system") then -- section might not exist self.map:set("system", nil, "system") end if not self.map:get(section) then -- section might not exist self.map:set(section, nil, self.sectiontype) end return self.map:get(section) end ns:tab("sys", translate("System"), nil ) local function err_tab_sys(title, msg) return string.format(translate("System") .. " - %s: %s", title, msg ) end ns:tab("doc", translate("Documentation"), translate("If you intend to operate Privoxy for more users than just yourself, " .. "it might be a good idea to let them know how to reach you, what you block " .. "and why you do that, your policies, etc.") ) local function err_tab_doc(title, msg) return string.format(translate("Documentation") .. " - %s: %s", title, msg ) end ns:tab("filter", translate("Files and Directories"), translate("Privoxy can (and normally does) use a number of other files " .. "for additional configuration, help and logging. This section of " .. "the configuration file tells Privoxy where to find those other files.") ) local function err_tab_filter(title, msg) return string.format(translate("Files and Directories") .. " - %s: %s", title, msg ) end ns:tab("access", translate("Access Control"), translate("This tab controls the security-relevant aspects of Privoxy's configuration.") ) local function err_tab_access(title, msg) return string.format(translate("Access Control") .. " - %s: %s", title, msg ) end ns:tab("forward", translate("Forwarding"), translate("Configure here the routing of HTTP requests through a chain of multiple proxies. " .. "Note that parent proxies can severely decrease your privacy level. " .. "Also specified here are SOCKS proxies.") ) ns:tab("misc", translate("Miscellaneous"), nil) local function err_tab_misc(self, msg) return string.format(translate("Miscellaneous") .. " - %s: %s", self.title_base, msg ) end ns:tab("debug", translate("Logging"), nil ) ns:tab("logview", translate("Log File Viewer"), nil ) -- tab: local -- ############################################################### -- start/stop button ----------------------------------------------------------- local btn = ns:taboption("sys", Button, "_startstop") btn.title = translate("Start / Stop") btn.description = translate("Start/Stop Privoxy WEB Proxy") btn.template = "privoxy/detail_startstop" function btn.cfgvalue(self, section) local pid = CTRL.get_pid(true) if pid > 0 then btn.inputtitle = "PID: " .. pid btn.inputstyle = "reset" btn.disabled = false else btn.inputtitle = translate("Start") btn.inputstyle = "apply" btn.disabled = false end return true end -- enabled --------------------------------------------------------------------- local ena = ns:taboption("sys", Flag, "_enabled") ena.title = translate("Enabled") ena.description = translate("Enable/Disable autostart of Privoxy on system startup and interface events") ena.orientation = "horizontal" -- put description under the checkbox ena.rmempty = false function ena.cfgvalue(self, section) return (SYS.init.enabled("privoxy")) and "1" or "0" end function ena.write(self, section, value) if value == "1" then return SYS.init.enable("privoxy") else return SYS.init.disable("privoxy") end end -- boot_delay ------------------------------------------------------------------ local bd = ns:taboption("sys", Value, "boot_delay") bd.title = translate("Boot delay") bd.description = translate("Delay (in seconds) during system boot before Privoxy start") .. [[
]] .. translate("During delay ifup-events are not monitored !") bd.default = "10" bd.rmempty = false -- value is in a separate section so we need to do by hand function bd.cfgvalue(self, section) local value = tonumber(self.map:get("system", "boot_delay") ) if not value then return nil end return tostring(value) end function bd.validate(self, value) local val = tonumber(value) if not val then return nil, err_tab_sys(self.title, translate("Value is not a number") ) elseif val < 0 or val > 300 then return nil, err_tab_sys(self.title, translate("Value not between 0 and 300") ) end return value end function bd.write(self, section, value) local fvalue = self:formvalue(section) local cvalue = self:cfgvalue(section) if (fvalue ~= cvalue) then self.map:set("system", "boot_delay", value) end end -- hostname -------------------------------------------------------------------- local hn = ns:taboption("doc", Value, "hostname") hn.title = string.format(HELP, "HOSTNAME", "Hostname" ) hn.description = translate("The hostname shown on the CGI pages.") hn.placeholder = SYS.hostname() hn.optional = true hn.rmempty = true function hn.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- user-manual ----------------------------------------------------------------- local um = ns:taboption("doc", Value, "user_manual") um.title = string.format(HELP, "USER-MANUAL", "User Manual" ) um.description = translate("Location of the Privoxy User Manual.") um.placeholder = "http://www.privoxy.org/user-manual/" um.optional = true um.rmempty = true function um.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- admin-address --------------------------------------------------------------- local aa = ns:taboption("doc", Value, "admin_address") aa.title_base = "Admin Email" aa.title = string.format(HELP, "ADMIN-ADDRESS", aa.title_base ) aa.description = translate("An email address to reach the Privoxy administrator.") aa.placeholder = "privoxy.admin@example.com" aa.optional = true aa.rmempty = true function aa.validate(self, value) if not value or #value == 0 then return "" end if not (value:match("[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?")) then return nil, err_tab_doc(self.title_base, translate("Invalid email address") ) end return value end function aa.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- proxy-info-url -------------------------------------------------------------- local piu = ns:taboption("doc", Value, "proxy_info_url") piu.title = string.format(HELP, "PROXY-INFO-URL", "Proxy Info URL" ) piu.description = translate("A URL to documentation about the local Privoxy setup, configuration or policies.") piu.optional = true piu.rmempty = true function piu.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- trust-info-url -------------------------------------------------------------- local tiu = ns:taboption("doc", Value, "trust_info_url") tiu.title = string.format(HELP, "TRUST-INFO-URL", "Trust Info URLs" ) tiu.description = translate("A URL to be displayed in the error page that users will see if access to an untrusted page is denied.") .. [[
]] .. translate("The value of this option only matters if the experimental trust mechanism has been activated.") .. [[]] tiu.optional = true tiu.rmepty = true function tiu.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- tab: filter -- ############################################################## -- logdir ---------------------------------------------------------------------- local ld = ns:taboption("filter", Value, "logdir") ld.title_base = "Log Directory" ld.title = string.format(HELP, "LOGDIR", ld.title_base ) ld.description = translate("The directory where all logging takes place (i.e. where the logfile is located).") .. [[
]] .. translate("No trailing '/', please.") ld.default = "/var/log" ld.rmempty = false function ld.validate(self, value) if not value or #value == 0 then return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No Directory given!") ) elseif not NXFS.access(value) then return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") ) else return value end end function ld.parse(self, section, novld) CTRL.value_parse(self, section, novld) end -- logfile --------------------------------------------------------------------- local lf = ns:taboption("filter", Value, "logfile") lf.title_base = "Log File" lf.title = string.format(HELP, "LOGFILE", lf.title_base ) lf.description = translate("The log file to use. File name, relative to log directory.") lf.default = "privoxy.log" lf.rmempty = false function lf.validate(self, value) if not value or #value == 0 then return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No File given!") ) else return value end end -- confdir --------------------------------------------------------------------- local cd = ns:taboption("filter", Value, "confdir") cd.title_base = "Configuration Directory" cd.title = string.format(HELP, "CONFDIR", cd.title_base ) cd.description = translate("The directory where the other configuration files are located.") .. [[
]] .. translate("No trailing '/', please.") cd.default = "/etc/privoxy" cd.rmempty = false function cd.validate(self, value) if not value or #value == 0 then return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No Directory given!") ) elseif not NXFS.access(value) then return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") ) else return value end end -- templdir -------------------------------------------------------------------- local tld = ns:taboption("filter", Value, "templdir") tld.title_base = "Template Directory" tld.title = string.format(HELP, "TEMPLDIR", tld.title_base ) tld.description = translate("An alternative directory where the templates are loaded from.") .. [[
]] .. translate("No trailing '/', please.") tld.placeholder = "/etc/privoxy/templates" tld.rmempty = true function tld.validate(self, value) if not NXFS.access(value) then return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") ) else return value end end -- temporary-directory --------------------------------------------------------- local td = ns:taboption("filter", Value, "temporary_directory") td.title_base = "Temporary Directory" td.title = string.format(HELP, "TEMPORARY-DIRECTORY", td.title_base ) td.description = translate("A directory where Privoxy can create temporary files.") .. [[
]] .. translate("Only when using 'external filters', Privoxy has to create temporary files.") .. [[]] td.rmempty = true -- actionsfile ----------------------------------------------------------------- local af = ns:taboption("filter", DynamicList, "actionsfile") af.title_base = "Action Files" af.title = string.format(HELP, "ACTIONSFILE", af.title_base) af.description = translate("The actions file(s) to use. Multiple actionsfile lines are permitted, and are in fact recommended!") .. [[
match-all.action := ]] .. translate("Actions that are applied to all sites and maybe overruled later on.") .. [[
default.action := ]] .. translate("Main actions file") .. [[
user.action := ]] .. translate("User customizations") af.rmempty = false function af.validate(self, value) if not value or #value == 0 then return nil, err_tab_access(self.title_base, translate("Mandatory Input: No files given!") ) end local confdir = cd:formvalue(ns.section) local err = false local file = "" if type(value) == "table" then local x for _, x in ipairs(value) do if x and #x > 0 then if not NXFS.access(confdir .."/".. x) then err = true file = x break -- break/leave for on error end end end else if not NXFS.access(confdir .."/".. value) then err = true file = value end end if err then return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file) end return value end -- filterfile ------------------------------------------------------------------ local ff = ns:taboption("filter", DynamicList, "filterfile") ff.title_base = "Filter files" ff.title = string.format(HELP, "FILTERFILE", ff.title_base ) ff.description = translate("The filter files contain content modification rules that use regular expressions.") ff.rmempty = false function ff.validate(self, value) if not value or #value == 0 then return nil, err_tab_access(self.title_base, translate("Mandatory Input: No files given!") ) end local confdir = cd:formvalue(ns.section) local err = false local file = "" if type(value) == "table" then local x for _, x in ipairs(value) do if x and #x > 0 then if not NXFS.access(confdir .."/".. x) then err = true file = x break -- break/leave for on error end end end else if not NXFS.access(confdir .."/".. value) then err = true file = value end end if err then return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file ) end return value end -- trustfile ------------------------------------------------------------------- local tf = ns:taboption("filter", Value, "trustfile") tf.title_base = "Trust file" tf.title = string.format(HELP, "TRUSTFILE", tf.title_base ) tf.description = translate("The trust mechanism is an experimental feature for building white-lists " .."and should be used with care.") .. [[
]] .. translate("It is NOT recommended for the casual user.") .. [[]] tf.placeholder = "user.trust" tf.rmempty = true function tf.validate(self, value) local confdir = cd:formvalue(ns.section) local err = false local file = "" if type(value) == "table" then local x for _, x in ipairs(value) do if x and #x > 0 then if not NCFS.access(confdir .."/".. x) then err = true file = x break -- break/leave for on error end end end else if not NXFS.access(confdir .."/".. value) then err = true file = value end end if err then return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file ) end return value end -- tab: access -- ############################################################## -- listen-address -------------------------------------------------------------- local la = ns:taboption("access", DynamicList, "listen_address") la.title_base = "Listen addresses" la.title = string.format(HELP, "LISTEN-ADDRESS", la.title_base ) la.description = translate("The address and TCP port on which Privoxy will listen for client requests.") .. [[
]] .. translate("Syntax: ") .. "IPv4:Port / [IPv6]:Port / Host:Port" la.default = "127.0.0.1:8118" la.rmempty = false function la.validate(self, value) if not value or #value == 0 then return nil, err_tab_access(self.title_base, translate("Mandatory Input: No Data given!") ) end local function check_value(v) local _ret = UTIL.split(v, "]:") local _ip if _ret[2] then -- ip6 with port _ip = string.gsub(_ret[1], "%[", "") -- remove "[" at beginning if not DTYP.ip6addr(_ip) then return translate("Mandatory Input: No valid IPv6 address given!") elseif not DTYP.port(_ret[2]) then return translate("Mandatory Input: No valid Port given!") else return nil end end _ret = UTIL.split(v, ":") if not _ret[2] then return translate("Mandatory Input: No Port given!") end if #_ret[1] > 0 and not DTYP.host(_ret[1]) then -- :8118 is valid address return translate("Mandatory Input: No valid IPv4 address or host given!") elseif not DTYP.port(_ret[2]) then return translate("Mandatory Input: No valid Port given!") else return nil end end local err = "" local entry = "" if type(value) == "table" then local x for _, x in ipairs(value) do if x and #x > 0 then err = check_value(x) if err then entry = x break end end end else err = check_value(value) entry = value end if err then return nil, string.format(err_tab_access(self.title_base, err .. " - %s"), entry ) end return value end -- permit-access --------------------------------------------------------------- local pa = ns:taboption("access", DynamicList, "permit_access") pa.title = string.format(HELP, "ACLS", "Permit access" ) pa.description = translate("Who can access what.") .. [[
]] .. translate("Please read Privoxy manual for details!") .. [[]] pa.rmempty = true -- deny-access ----------------------------------------------------------------- local da = ns:taboption("access", DynamicList, "deny_access") da.title = string.format(HELP, "ACLS", "Deny Access" ) da.description = translate("Who can access what.") .. [[
]] .. translate("Please read Privoxy manual for details!") .. [[]] da.rmempty = true -- buffer-limit ---------------------------------------------------------------- local bl = ns:taboption("access", Value, "buffer_limit") bl.title_base = "Buffer Limit" bl.title = string.format(HELP, "BUFFER-LIMIT", bl.title_base ) bl.description = translate("Maximum size (in KB) of the buffer for content filtering.") .. [[
]] .. translate("Value range 1 to 4096, no entry defaults to 4096") bl.default = 4096 bl.rmempty = true function bl.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_access(self.title_base, translate("Value is not a number") ) elseif v < 1 or v > 4096 then return nil, err_tab_access(self.title_base, translate("Value not between 1 and 4096") ) elseif v == self.default then return "" -- don't need to save default end return value end -- toggle ---------------------------------------------------------------------- local tgl = ns:taboption("access", Flag, "toggle") tgl.title = string.format(HELP, "TOGGLE", "Toggle Status" ) tgl.description = translate("Enable/Disable filtering when Privoxy starts.") .. [[
]] .. translate("Disabled == Transparent Proxy Mode") tgl.orientation = "horizontal" tgl.default = "1" tgl.rmempty = false -- enable-remote-toggle -------------------------------------------------------- local ert = ns:taboption("access", Flag, "enable_remote_toggle") ert.title = string.format(HELP, "ENABLE-REMOTE-TOGGLE", "Enable remote toggle" ) ert.description = translate("Whether or not the web-based toggle feature may be used.") ert.orientation = "horizontal" ert.rmempty = true -- enable-remote-http-toggle --------------------------------------------------- local eht = ns:taboption("access", Flag, "enable_remote_http_toggle") eht.title = string.format(HELP, "ENABLE-REMOTE-HTTP-TOGGLE", "Enable remote toggle via HTTP" ) eht.description = translate("Whether or not Privoxy recognizes special HTTP headers to change toggle state.") .. [[
]] .. translate("This option will be removed in future releases as it has been obsoleted by the more general header taggers.") .. [[]] eht.orientation = "horizontal" eht.rmempty = true -- enable-edit-actions --------------------------------------------------------- local eea = ns:taboption("access", Flag, "enable_edit_actions") eea.title = string.format(HELP, "ENABLE-EDIT-ACTIONS", "Enable action file editor" ) eea.description = translate("Whether or not the web-based actions file editor may be used.") eea.orientation = "horizontal" eea.rmempty = true -- enforce-blocks -------------------------------------------------------------- local eb = ns:taboption("access", Flag, "enforce_blocks") eb.title = string.format(HELP, "ENFORCE-BLOCKS", "Enforce page blocking" ) eb.description = translate("If enabled, Privoxy hides the 'go there anyway' link. " .. "The user obviously should not be able to bypass any blocks.") eb.orientation = "horizontal" eb.rmempty = true -- tab: forward -- ############################################################# -- enable-proxy-authentication-forwarding -------------------------------------- local paf = ns:taboption("forward", Flag, "enable_proxy_authentication_forwarding") paf.title = string.format(HELP, "ENABLE-PROXY-AUTHENTICATION-FORWARDING", translate("Enable proxy authentication forwarding") ) paf.description = translate("Whether or not proxy authentication through Privoxy should work.") .. [[
]] .. translate("Enabling this option is NOT recommended if there is no parent proxy that requires authentication!") .. [[]] --paf.orientation = "horizontal" paf.rmempty = true -- forward --------------------------------------------------------------------- local fwd = ns:taboption("forward", DynamicList, "forward") fwd.title = string.format(HELP, "FORWARD", "Forward HTTP" ) fwd.description = translate("To which parent HTTP proxy specific requests should be routed.") .. [[
]] .. translate("Syntax: target_pattern http_parent[:port]") fwd.rmempty = true -- forward-socks4 -------------------------------------------------------------- local fs4 = ns:taboption("forward", DynamicList, "forward_socks4") fs4.title = string.format(HELP, "SOCKS", "Forward SOCKS 4" ) fs4.description = translate("Through which SOCKS proxy (and optionally to which parent HTTP proxy) specific requests should be routed.") .. [[
]] .. translate("Syntax:") .. " target_pattern socks_proxy[:port] http_parent[:port]" fs4.rmempty = true -- forward-socks4a ------------------------------------------------------------- local f4a = ns:taboption("forward", DynamicList, "forward_socks4a") f4a.title = string.format(HELP, "SOCKS", "Forward SOCKS 4A" ) f4a.description = fs4.description f4a.rmempty = true -- forward-socks5 -------------------------------------------------------------- local fs5 = ns:taboption("forward", DynamicList, "forward_socks5") fs5.title = string.format(HELP, "SOCKS", "Forward SOCKS 5" ) fs5.description = translate("Through which SOCKS proxy (and optionally to which parent HTTP proxy) specific requests should be routed.") .. [[
]] .. translate("Syntax:") .. " target_pattern [user:pass@]socks_proxy[:port] http_parent[:port]" fs5.rmempty = true -- forward-socks5t ------------------------------------------------------------- local f5t = ns:taboption("forward", DynamicList, "forward_socks5t") f5t.title = string.format(HELP, "SOCKS", "Forward SOCKS 5t" ) f5t.description = fs5.description f5t.rmempty = true -- tab: misc -- ################################################################ -- accept-intercepted-requests ------------------------------------------------- local air = ns:taboption("misc", Flag, "accept_intercepted_requests") air.title = string.format(HELP, "ACCEPT-INTERCEPTED-REQUESTS", "Accept intercepted requests" ) air.description = translate("Whether intercepted requests should be treated as valid.") air.orientation = "horizontal" air.rmempty = true -- allow-cgi-request-crunching ------------------------------------------------- local crc = ns:taboption("misc", Flag, "allow_cgi_request_crunching") crc.title = string.format(HELP, "ALLOW-CGI-REQUEST-CRUNCHING", "Allow CGI request crunching" ) crc.description = translate("Whether requests to Privoxy's CGI pages can be blocked or redirected.") crc.orientation = "horizontal" crc.rmempty = true -- split-large-forms ----------------------------------------------------------- local slf = ns:taboption("misc", Flag, "split_large_forms") slf.title = string.format(HELP, "SPLIT-LARGE-FORMS", "Split large forms" ) slf.description = translate("Whether the CGI interface should stay compatible with broken HTTP clients.") slf.orientation = "horizontal" slf.rmempty = true -- keep-alive-timeout ---------------------------------------------------------- local kat = ns:taboption("misc", Value, "keep_alive_timeout") kat.title_base = "Keep-alive timeout" kat.title = string.format(HELP, "KEEP-ALIVE-TIMEOUT", kat.title_base) kat.description = translate("Number of seconds after which an open connection will no longer be reused.") kat.rmempty = true function kat.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_misc(self.title_base, translate("Value is not a number") ) elseif v < 1 then return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") ) end return value end -- tolerate-pipelining --------------------------------------------------------- local tp = ns:taboption("misc", Flag, "tolerate_pipelining") tp.title = string.format(HELP, "TOLERATE-PIPELINING", "Tolerate pipelining" ) tp.description = translate("Whether or not pipelined requests should be served.") tp.orientation = "horizontal" tp.rmempty = true -- default-server-timeout ------------------------------------------------------ local dst = ns:taboption("misc", Value, "default_server_timeout") dst.title_base = "Default server timeout" dst.title = string.format(HELP, "DEFAULT-SERVER-TIMEOUT", dst.title_base) dst.description = translate("Assumed server-side keep-alive timeout (in seconds) if not specified by the server.") dst.rmempty = true function dst.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_misc(self.title_base, translate("Value is not a number") ) elseif v < 1 then return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") ) end return value end -- connection-sharing ---------------------------------------------------------- local cs = ns:taboption("misc", Flag, "connection_sharing") cs.title = string.format(HELP, "CONNECTION-SHARING", "Connection sharing" ) cs.description = translate("Whether or not outgoing connections that have been kept alive should be shared between different incoming connections.") cs.orientation = "horizontal" cs.rmempty = true -- socket-timeout -------------------------------------------------------------- local st = ns:taboption("misc", Value, "socket_timeout") st.title_base = "Socket timeout" st.title = string.format(HELP, "SOCKET-TIMEOUT", st.title_base ) st.description = translate("Number of seconds after which a socket times out if no data is received.") st.default = 300 st.rmempty = true function st.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_misc(self.title_base, translate("Value is not a number") ) elseif v < 1 then return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") ) elseif v == self.default then return "" -- don't need to save default end return value end -- max-client-connections ------------------------------------------------------ local mcc = ns:taboption("misc", Value, "max_client_connections") mcc.title_base = "Max. client connections" mcc.title = string.format(HELP, "MAX-CLIENT-CONNECTIONS", mcc.title_base ) mcc.description = translate("Maximum number of client connections that will be served.") mcc.default = 128 mcc.rmempty = true function mcc.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_misc(self.title_base, translate("Value is not a number") ) elseif v < 1 then return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") ) elseif v == self.default then return "" -- don't need to save default end return value end -- handle-as-empty-doc-returns-ok ---------------------------------------------- local her = ns:taboption("misc", Flag, "handle_as_empty_doc_returns_ok") her.title = string.format(HELP, "HANDLE-AS-EMPTY-DOC-RETURNS-OK", "Handle as empty doc returns ok" ) her.description = translate("The status code Privoxy returns for pages blocked with +handle-as-empty-document.") her.orientation = "horizontal" her.rmempty = true -- enable-compression ---------------------------------------------------------- local ec = ns:taboption("misc", Flag, "enable_compression") ec.title = string.format(HELP, "ENABLE-COMPRESSION", "Enable compression" ) ec.description = translate("Whether or not buffered content is compressed before delivery.") ec.orientation = "horizontal" ec.rmempty = true -- compression-level ----------------------------------------------------------- local cl = ns:taboption("misc", Value, "compression_level") cl.title_base = "Compression level" cl.title = string.format(HELP, "COMPRESSION-LEVEL", cl.title_base ) cl.description = translate("The compression level that is passed to the zlib library when compressing buffered content.") cl.default = 1 cl.rmempty = true function cl.validate(self, value) local v = tonumber(value) if not v then return nil, err_tab_misc(self.title_base, translate("Value is not a number") ) elseif v < 0 or v > 9 then return nil, err_tab_misc(self.title_base, translate("Value not between 0 and 9") ) elseif v == self.default then return "" -- don't need to save default end return value end -- client-header-order --------------------------------------------------------- local cho = ns:taboption("misc", Value, "client_header_order") cho.title = string.format(HELP, "CLIENT-HEADER-ORDER", "Client header order" ) cho.description = translate("The order in which client headers are sorted before forwarding them.") .. [[
]] .. translate("Syntax: Client header names delimited by spaces.") cho.rmempty = true -- "debug"-tab definition -- ################################################### -- single-threaded ------------------------------------------------------------- local st = ns:taboption("debug", Flag, "single_threaded") st.title = string.format(HELP, "SINGLE-THREADED", "Single Threaded" ) st.description = translate("Whether to run only one server thread.") .. [[
]] .. translate("This option is only there for debugging purposes. It will drastically reduce performance.") .. [[]] st.rmempty = true -- debug 1 --------------------------------------------------------------------- local d0 = ns:taboption("debug", Flag, "debug_1") d0.title = string.format(HELP, "DEBUG", "Debug 1" ) d0.description = translate("Log the destination for each request Privoxy let through. See also 'Debug 1024'.") d0.rmempty = true -- debug 2 --------------------------------------------------------------------- local d1 = ns:taboption("debug", Flag, "debug_2") d1.title = string.format(HELP, "DEBUG", "Debug 2" ) d1.description = translate("Show each connection status") d1.rmempty = true -- debug 4 --------------------------------------------------------------------- local d2 = ns:taboption("debug", Flag, "debug_4") d2.title = string.format(HELP, "DEBUG", "Debug 4" ) d2.description = translate("Show I/O status") d2.rmempty = true -- debug 8 --------------------------------------------------------------------- local d3 = ns:taboption("debug", Flag, "debug_8") d3.title = string.format(HELP, "DEBUG", "Debug 8" ) d3.description = translate("Show header parsing") d3.rmempty = true -- debug 16 -------------------------------------------------------------------- local d4 = ns:taboption("debug", Flag, "debug_16") d4.title = string.format(HELP, "DEBUG", "Debug 16" ) d4.description = translate("Log all data written to the network") d4.rmempty = true -- debug 32 -------------------------------------------------------------------- local d5 = ns:taboption("debug", Flag, "debug_32") d5.title = string.format(HELP, "DEBUG", "Debug 32" ) d5.description = translate("Debug force feature") d5.rmempty = true -- debug 64 -------------------------------------------------------------------- local d6 = ns:taboption("debug", Flag, "debug_64") d6.title = string.format(HELP, "DEBUG", "Debug 64" ) d6.description = translate("Debug regular expression filters") d6.rmempty = true -- debug 128 ------------------------------------------------------------------- local d7 = ns:taboption("debug", Flag, "debug_128") d7.title = string.format(HELP, "DEBUG", "Debug 128" ) d7.description = translate("Debug redirects") d7.rmempty = true -- debug 256 ------------------------------------------------------------------- local d8 = ns:taboption("debug", Flag, "debug_256") d8.title = string.format(HELP, "DEBUG", "Debug 256" ) d8.description = translate("Debug GIF de-animation") d8.rmempty = true -- debug 512 ------------------------------------------------------------------- local d9 = ns:taboption("debug", Flag, "debug_512") d9.title = string.format(HELP, "DEBUG", "Debug 512" ) d9.description = translate("Common Log Format") d9.rmempty = true -- debug 1024 ------------------------------------------------------------------ local d10 = ns:taboption("debug", Flag, "debug_1024") d10.title = string.format(HELP, "DEBUG", "Debug 1024" ) d10.description = translate("Log the destination for requests Privoxy didn't let through, and the reason why.") d10.rmempty = true -- debug 2048 ------------------------------------------------------------------ local d11 = ns:taboption("debug", Flag, "debug_2048") d11.title = string.format(HELP, "DEBUG", "Debug 2048" ) d11.description = translate("CGI user interface") d11.rmempty = true -- debug 4096 ------------------------------------------------------------------ local d12 = ns:taboption("debug", Flag, "debug_4096") d12.title = string.format(HELP, "DEBUG", "Debug 4096" ) d12.description = translate("Startup banner and warnings.") d12.rmempty = true -- debug 8192 ------------------------------------------------------------------ local d13 = ns:taboption("debug", Flag, "debug_8192") d13.title = string.format(HELP, "DEBUG", "Debug 8192" ) d13.description = translate("Non-fatal errors - *we highly recommended enabling this*") d13.rmempty = true -- debug 16384 ----------------------------------------------------------------- --[[ TODO ??? local d14 = ns:taboption("debug", Flag, "debug_16384") d14.title = string.format(HELP, "DEBUG", "Debug 16384" ) d14.description = translate("") d14.rmempty = true ]]-- -- debug 32768 ----------------------------------------------------------------- local d15 = ns:taboption("debug", Flag, "debug_32768") d15.title = string.format(HELP, "DEBUG", "Debug 32768" ) d15.description = translate("Log all data read from the network") d15.rmempty = true -- debug 65536 ----------------------------------------------------------------- local d16 = ns:taboption("debug", Flag, "debug_65536") d16.title = string.format(HELP, "DEBUG", "Debug 65536" ) d16.description = translate("Log the applying actions") d16.rmempty = true -- tab: logview -- ############################################################# local lv = ns:taboption("logview", DummyValue, "_logview") lv.template = "privoxy/detail_logview" lv.inputtitle = translate("Read / Reread log file") lv.rows = 50 function lv.cfgvalue(self, section) local lfile=self.map:get(ns.section, "logdir") .. "/" .. self.map:get(ns.section, "logfile") if NXFS.access(lfile) then return lfile .. "\n" .. translate("Please press [Read] button") end return lfile .. "\n" .. translate("File not found or empty") end return m