Add global reverse proxy timeout settings (fixes #74)
							parent
							
								
									0c61f2a87a
								
							
						
					
					
						commit
						13b5220b93
					
				|  | @ -24,12 +24,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
| THE SOFTWARE. | ||||
| */ | ||||
| 
 | ||||
| export default () => { | ||||
| export default global => { | ||||
|     const config = {}; | ||||
| 
 | ||||
|     config.proxy_http_version = '1.1'; | ||||
|     config.proxy_cache_bypass = '$http_upgrade'; | ||||
| 
 | ||||
|     config['# Proxy headers'] = ''; | ||||
|     config['proxy_set_header Upgrade'] = '$http_upgrade'; | ||||
|     config['proxy_set_header Connection'] = '"upgrade"'; | ||||
|     config['proxy_set_header Host'] = '$host'; | ||||
|  | @ -39,6 +40,11 @@ export default () => { | |||
|     config['proxy_set_header X-Forwarded-Host'] = '$host'; | ||||
|     config['proxy_set_header X-Forwarded-Port'] = '$server_port'; | ||||
| 
 | ||||
|     config['# Proxy timeouts'] = ''; | ||||
|     config['proxy_connect_timeout'] = global.reverseProxy.proxyConnectTimeout.computed; | ||||
|     config['proxy_send_timeout'] = global.reverseProxy.proxySendTimeout.computed; | ||||
|     config['proxy_read_timeout'] = global.reverseProxy.proxyReadTimeout.computed; | ||||
| 
 | ||||
|     // Done!
 | ||||
|     return config; | ||||
| }; | ||||
|  |  | |||
|  | @ -200,7 +200,7 @@ export default (domain, domains, global) => { | |||
|             locConf.push(['include', 'nginxconfig.io/proxy.conf']); | ||||
|         } else { | ||||
|             // Unified
 | ||||
|             locConf.push(...Object.entries(proxyConf())); | ||||
|             locConf.push(...Object.entries(proxyConf(global))); | ||||
|         } | ||||
| 
 | ||||
|         serverConfig.push(['# reverse proxy', '']); | ||||
|  |  | |||
|  | @ -70,7 +70,7 @@ export default (domains, global) => { | |||
| 
 | ||||
|         // Reverse proxy
 | ||||
|         if (domains.some(d => d.reverseProxy.reverseProxy.computed)) | ||||
|             files['nginxconfig.io/proxy.conf'] = toConf(proxyConf()); | ||||
|             files['nginxconfig.io/proxy.conf'] = toConf(proxyConf(global)); | ||||
| 
 | ||||
|         // WordPress
 | ||||
|         if (domains.some(d => d.php.wordPressRules.computed)) | ||||
|  |  | |||
|  | @ -40,4 +40,6 @@ export default { | |||
| 	magento: 'Magento', | ||||
| 	django: 'Django', | ||||
| 	logging: 'Logging', | ||||
|     reverseProxy: 'Reverse proxy', | ||||
|     reverseProxyLower: 'reverse proxy', | ||||
| }; | ||||
|  |  | |||
|  | @ -27,10 +27,9 @@ THE SOFTWARE. | |||
| import common from '../../common'; | ||||
| 
 | ||||
| export default { | ||||
|     reverseProxy: 'Reverse proxy', | ||||
|     reverseProxyIsDisabled: 'Reverse proxy is disabled.', | ||||
|     reverseProxyCannotBeEnabledWithPhp: `Reverse proxy cannot be enabled whilst ${common.php} is enabled.`, | ||||
|     reverseProxyCannotBeEnabledWithPython: `Reverse proxy cannot be enabled whilst ${common.python} is enabled.`, | ||||
|     enableReverseProxy: `${common.enable} reverse proxy`, | ||||
|     reverseProxyIsDisabled: `${common.reverseProxy} is disabled.`, | ||||
|     reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy} cannot be enabled whilst ${common.php} is enabled.`, | ||||
|     reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy} cannot be enabled whilst ${common.python} is enabled.`, | ||||
|     enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`, | ||||
|     path: 'Path', | ||||
| }; | ||||
|  |  | |||
|  | @ -30,7 +30,8 @@ import nginx from './nginx'; | |||
| import performance from './performance'; | ||||
| import php from './php'; | ||||
| import python from './python'; | ||||
| import reverseProxy from './reverse_proxy'; | ||||
| import security from './security'; | ||||
| import tools from './tools'; | ||||
| 
 | ||||
| export default { https, logging, nginx, performance, php, python, security, tools }; | ||||
| export default { https, logging, nginx, performance, php, python, reverseProxy, security, tools }; | ||||
|  |  | |||
|  | @ -0,0 +1,32 @@ | |||
| /* | ||||
| Copyright 2020 DigitalOcean | ||||
| 
 | ||||
| This code is licensed under the MIT License. | ||||
| You may obtain a copy of the License at | ||||
| https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
 | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions : | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
| */ | ||||
| 
 | ||||
| import common from '../../common'; | ||||
| 
 | ||||
| export default { | ||||
|     reverseProxyMustBeEnabledOnOneSite: `${common.reverseProxy} must be enabled on at least one site to configure global ${common.reverseProxyLower} settings.`, | ||||
|     seconds: 'seconds', | ||||
| }; | ||||
|  | @ -28,7 +28,7 @@ THE SOFTWARE. | |||
|     <div> | ||||
|         <div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">{{ i18n.templates.domainSections.reverseProxy.reverseProxy }}</label> | ||||
|                 <label class="label">{{ i18n.common.reverseProxy }}</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field"> | ||||
|  | @ -49,7 +49,7 @@ THE SOFTWARE. | |||
| 
 | ||||
|         <div v-else class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">{{ i18n.templates.domainSections.reverseProxy.reverseProxy }}</label> | ||||
|                 <label class="label">{{ i18n.common.reverseProxy }}</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div :class="`field${reverseProxyChanged ? ' is-changed' : ''}`"> | ||||
|  | @ -123,22 +123,22 @@ THE SOFTWARE. | |||
|     }; | ||||
| 
 | ||||
|     export default { | ||||
|         name: 'DomainReverseProxy',                                         // Component name | ||||
|         display: i18n.templates.domainSections.reverseProxy.reverseProxy,   // Display name for tab | ||||
|         key: 'reverseProxy',                                                // Key for data in parent | ||||
|         delegated: delegatedFromDefaults(defaults),                         // Data the parent will present here | ||||
|         name: 'DomainReverseProxy',                                 // Component name | ||||
|         display: i18n.common.reverseProxy,                          // Display name for tab | ||||
|         key: 'reverseProxy',                                        // Key for data in parent | ||||
|         delegated: delegatedFromDefaults(defaults),                 // Data the parent will present here | ||||
|         components: { | ||||
|             PrettyCheck, | ||||
|         }, | ||||
|         props: { | ||||
|             data: Object,                                                   // Data delegated back to us from parent | ||||
|             data: Object,                                           // Data delegated back to us from parent | ||||
|         }, | ||||
|         data () { | ||||
|             return { | ||||
|                 i18n, | ||||
|             }; | ||||
|         }, | ||||
|         computed: computedFromDefaults(defaults, 'reverseProxy'),           // Getters & setters for the delegated data | ||||
|         computed: computedFromDefaults(defaults, 'reverseProxy'),   // Getters & setters for the delegated data | ||||
|         watch: { | ||||
|             // If the PHP or Python is enabled, the Reverse proxy will be forced off | ||||
|             '$parent.$props.data': { | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ export { default as HTTPS } from './https'; | |||
| export { default as Security } from './security'; | ||||
| export { default as PHP } from './php'; | ||||
| export { default as Python } from './python'; | ||||
| export { default as ReverseProxy } from './reverse_proxy'; | ||||
| export { default as Performance } from './performance'; | ||||
| export { default as Logging } from './logging'; | ||||
| export { default as NGINX } from './nginx'; | ||||
|  |  | |||
|  | @ -0,0 +1,213 @@ | |||
| <!-- | ||||
| Copyright 2020 DigitalOcean | ||||
| 
 | ||||
| This code is licensed under the MIT License. | ||||
| You may obtain a copy of the License at | ||||
| https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/ | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions : | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
| --> | ||||
| 
 | ||||
| <template> | ||||
|     <div> | ||||
|         <div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">{{ i18n.common.reverseProxy }}</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field"> | ||||
|                     <div class="control"> | ||||
|                         <label class="text"> | ||||
|                             {{ i18n.templates.globalSections.reverseProxy.reverseProxyMustBeEnabledOnOneSite }} | ||||
|                         </label> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <template v-else> | ||||
|             <div class="field is-horizontal"> | ||||
|                 <div class="field-label"> | ||||
|                     <label class="label">proxy_connect_timeout</label> | ||||
|                 </div> | ||||
|                 <div class="field-body"> | ||||
|                     <div class="field has-addons"> | ||||
|                         <div :class="`control is-expanded${proxyConnectTimeoutChanged ? ' is-changed' : ''}`"> | ||||
|                             <input v-model.number="proxyConnectTimeout" | ||||
|                                    class="input" | ||||
|                                    type="number" | ||||
|                                    min="0" | ||||
|                                    step="1" | ||||
|                                    :placeholder="$props.data.proxyConnectTimeout.default" | ||||
|                             /> | ||||
|                         </div> | ||||
|                         <div class="control"> | ||||
|                             <a class="button is-static"> | ||||
|                                 {{ i18n.templates.globalSections.reverseProxy.seconds }} | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="field is-horizontal"> | ||||
|                 <div class="field-label"> | ||||
|                     <label class="label">proxy_send_timeout</label> | ||||
|                 </div> | ||||
|                 <div class="field-body"> | ||||
|                     <div class="field has-addons"> | ||||
|                         <div :class="`control is-expanded${proxySendTimeoutChanged ? ' is-changed' : ''}`"> | ||||
|                             <input v-model.number="proxySendTimeout" | ||||
|                                    class="input" | ||||
|                                    type="number" | ||||
|                                    min="0" | ||||
|                                    step="1" | ||||
|                                    :placeholder="$props.data.proxySendTimeout.default" | ||||
|                             /> | ||||
|                         </div> | ||||
|                         <div class="control"> | ||||
|                             <a class="button is-static"> | ||||
|                                 {{ i18n.templates.globalSections.reverseProxy.seconds }} | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="field is-horizontal"> | ||||
|                 <div class="field-label"> | ||||
|                     <label class="label">proxy_read_timeout</label> | ||||
|                 </div> | ||||
|                 <div class="field-body"> | ||||
|                     <div class="field has-addons"> | ||||
|                         <div :class="`control is-expanded${proxyReadTimeoutChanged ? ' is-changed' : ''}`"> | ||||
|                             <input v-model.number="proxyReadTimeout" | ||||
|                                    class="input" | ||||
|                                    type="number" | ||||
|                                    min="0" | ||||
|                                    step="1" | ||||
|                                    :placeholder="$props.data.proxyReadTimeout.default" | ||||
|                             /> | ||||
|                         </div> | ||||
|                         <div class="control"> | ||||
|                             <a class="button is-static"> | ||||
|                                 {{ i18n.templates.globalSections.reverseProxy.seconds }} | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </template> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
|     import i18n from '../../i18n'; | ||||
|     import delegatedFromDefaults from '../../util/delegated_from_defaults'; | ||||
|     import computedFromDefaults from '../../util/computed_from_defaults'; | ||||
| 
 | ||||
|     const defaults = { | ||||
|         proxyConnectTimeout: { | ||||
|             default: 60, | ||||
|             computed: '60s', // We use a watcher to append 's' | ||||
|             enabled: false, | ||||
|         }, | ||||
|         proxySendTimeout: { | ||||
|             default: 60, | ||||
|             computed: '60s', // We use a watcher to append 's' | ||||
|             enabled: false, | ||||
|         }, | ||||
|         proxyReadTimeout: { | ||||
|             default: 60, | ||||
|             computed: '60s', // We use a watcher to append 's' | ||||
|             enabled: false, | ||||
|         }, | ||||
|     }; | ||||
| 
 | ||||
|     const validTimeout = data => { | ||||
|         let val = parseFloat(data.computed); | ||||
| 
 | ||||
|         // Use default if we've got an invalid setting | ||||
|         if (isNaN(val)) { | ||||
|             val = data.default; | ||||
|         } | ||||
| 
 | ||||
|         // Set the value with 's' appended | ||||
|         data.computed = `${val}s`; | ||||
|     }; | ||||
| 
 | ||||
|     export default { | ||||
|         name: 'GlobalReverseProxy',                                 // Component name | ||||
|         display: i18n.common.reverseProxy,                          // Display name for tab | ||||
|         key: 'reverseProxy',                                        // Key for data in parent | ||||
|         delegated: delegatedFromDefaults(defaults),                 // Data the parent will present here | ||||
|         props: { | ||||
|             data: Object,                                           // Data delegated back to us from parent | ||||
|         }, | ||||
|         data() { | ||||
|             return { | ||||
|                 i18n, | ||||
|                 reverseProxyEnabled: false, | ||||
|             }; | ||||
|         }, | ||||
|         computed: computedFromDefaults(defaults, 'reverseProxy'),   // Getters & setters for the delegated data | ||||
|         watch: { | ||||
|             // Disable all options if Reverse proxy is disabled | ||||
|             '$parent.$parent.$data.domains': { | ||||
|                 handler(data) { | ||||
|                     for (const domain of data) { | ||||
|                         if (domain && domain.reverseProxy && domain.reverseProxy.reverseProxy | ||||
|                             && domain.reverseProxy.reverseProxy.computed) { | ||||
|                             this.$data.reverseProxyEnabled = true; | ||||
|                             this.$props.data.proxyConnectTimeout.enabled = true; | ||||
|                             this.$props.data.proxyConnectTimeout.computed = this.$props.data.proxyConnectTimeout.value; | ||||
|                             this.$props.data.proxySendTimeout.enabled = true; | ||||
|                             this.$props.data.proxySendTimeout.computed = this.$props.data.proxySendTimeout.value; | ||||
|                             this.$props.data.proxyReadTimeout.enabled = true; | ||||
|                             this.$props.data.proxyReadTimeout.computed = this.$props.data.proxyReadTimeout.value; | ||||
|                             return; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     this.$data.reverseProxyEnabled = false; | ||||
|                     this.$props.data.proxyConnectTimeout.enabled = false; | ||||
|                     this.$props.data.proxyConnectTimeout.computed = ''; | ||||
|                     this.$props.data.proxySendTimeout.enabled = false; | ||||
|                     this.$props.data.proxySendTimeout.computed = ''; | ||||
|                     this.$props.data.proxyReadTimeout.enabled = false; | ||||
|                     this.$props.data.proxyReadTimeout.computed = ''; | ||||
|                 }, | ||||
|                 deep: true, | ||||
|             }, | ||||
|             // Ensure the timeouts are valid numbers | ||||
|             '$props.data.proxyConnectTimeout': { | ||||
|                 handler: validTimeout, | ||||
|                 deep: true, | ||||
|             }, | ||||
|             '$props.data.proxySendTimeout': { | ||||
|                 handler: validTimeout, | ||||
|                 deep: true, | ||||
|             }, | ||||
|             '$props.data.proxyReadTimeout': { | ||||
|                 handler: validTimeout, | ||||
|                 deep: true, | ||||
|             }, | ||||
|         }, | ||||
|     }; | ||||
| </script> | ||||
		Loading…
	
		Reference in New Issue
	
	 MattIPv4
						MattIPv4