Compare commits

...
22 Commits
Author SHA1 Message Date
Svilen Markov f5bfd9d4d1 Merge branch 'dev'
Create release / release (push) Has been cancelled
2025-05-19 21:25:48 +01:00
Svilen Markov 9e3639eb54 Update readme 2025-05-19 21:25:33 +01:00
Svilen Markov b4094b28bd Allow disabling theme picker 2025-05-19 21:25:33 +01:00
Svilen Markov b294839b79 Make theme key accessible via CSS 2025-05-19 21:25:33 +01:00
Svilen Markov 14a21de37f Add user agent to test reddit request 2025-05-19 21:23:13 +01:00
Svilen Markov d9239acbce Increase diagnose command timeout 2025-05-19 21:23:13 +01:00
Svilen Markov a2247c0b6c Use default client in diagnose command
defaultHTTPClient may behave differently to http.DefaultClient and is used for almost all widgets, using it within the diagnose
command will make debugging and replicating issues easier
2025-05-19 21:23:13 +01:00
Svilen Markov c1aaec5ffc Add .Options.JSON to custom API 2025-05-19 21:23:13 +01:00
Svilen Markov bcef9fbd61 Simplify implementation of func 2025-05-19 21:23:12 +01:00
Svilen Markov 32db59fda2 Merge pull request #678 from ralphocdol/fix-text-truncate-formatting
Fix text-truncate or related formatting
2025-05-19 21:12:21 +01:00
Svilen Markov 92bc68b61a Use innerText instead of textContent 2025-05-19 21:11:11 +01:00
Svilen Markov a6382b2e1d Merge pull request #681 from ralphocdol/update-the-and-or-doc-description
Docs: The 'and' and 'or' accepts more than 2 boolean arguments
2025-05-19 21:07:05 +01:00
Ralph Ocdol 571cdaf618 The 'and' and 'or' accepts more than 2 boolean arguments 2025-05-19 19:46:26 +08:00
Ralph Ocdol aa3b2c3b1b Fix text-truncate or related formatting 2025-05-18 20:33:03 +08:00
Svilen Markov 9bbf73db97 Merge pull request #661 from anant-j/dev
Add Mod operation
2025-05-16 17:33:58 +01:00
Svilen Markov dc950e7ec2 Merge pull request #668 from Xevion/main
Add Anchors to Links to Configuration Documentation within README
2025-05-16 17:30:14 +01:00
Svilen Markov 91ca57e242 Merge pull request #662 from mazzz1y/dev
Add http proxy support
2025-05-16 17:21:53 +01:00
Xevion 95541ef5e1 Use an anchor for links to root configuration 2025-05-15 23:19:54 -05:00
Svilen Markov 1ace129a58 Add safeHTML function 2025-05-15 14:21:59 +01:00
Svilen Markov af04605d7d Remove unused function 2025-05-15 13:57:27 +01:00
Dmitry Rubtsov 0ec9cf4aaa Add http proxy support 2025-05-15 13:34:17 +06:00
Anant Jain a5b0664b9c Add Mod operation 2025-05-14 22:38:13 -07:00
12 changed files with 108 additions and 51 deletions
+3 -4
View File
@@ -1,6 +1,6 @@
<p align="center"><em>What if you could see everything at a...</em></p> <p align="center"><em>What if you could see everything at a...</em></p>
<h1 align="center">Glance</h1> <h1 align="center">Glance</h1>
<p align="center"><a href="#installation">Install</a> • <a href="docs/configuration.md">Configuration</a> • <a href="https://discord.com/invite/7KQ7Xa9kJd">Discord</a> • <a href="https://github.com/sponsors/glanceapp">Sponsor</a></p> <p align="center"><a href="#installation">Install</a> • <a href="docs/configuration.md#configuring-glance">Configuration</a> • <a href="https://discord.com/invite/7KQ7Xa9kJd">Discord</a> • <a href="https://github.com/sponsors/glanceapp">Sponsor</a></p>
<p align="center"><a href="https://github.com/glanceapp/community-widgets">Community widgets</a> • <a href="docs/preconfigured-pages.md">Preconfigured pages</a> • <a href="docs/themes.md">Themes</a></p> <p align="center"><a href="https://github.com/glanceapp/community-widgets">Community widgets</a> • <a href="docs/preconfigured-pages.md">Preconfigured pages</a> • <a href="docs/themes.md">Themes</a></p>
![](docs/images/readme-main-image.png) ![](docs/images/readme-main-image.png)
@@ -17,7 +17,7 @@
* Docker containers status * Docker containers status
* Server stats * Server stats
* Custom widgets * Custom widgets
* [and many more...](docs/configuration.md) * [and many more...](docs/configuration.md#configuring-glance)
### Fast and lightweight ### Fast and lightweight
* Low memory usage * Low memory usage
@@ -46,8 +46,7 @@ Easily create your own theme by tweaking a few numbers or choose from one of the
<br> <br>
## Configuration ## Configuration
Configuration is done through YAML files, to learn more about how the layout works, how to add more pages and how to configure widgets, visit the [configuration documentation](docs/configuration.md). Configuration is done through YAML files, to learn more about how the layout works, how to add more pages and how to configure widgets, visit the [configuration documentation](docs/configuration.md#configuring-glance).
<details> <details>
<summary><strong>Preview example configuration file</strong></summary> <summary><strong>Preview example configuration file</strong></summary>
<br> <br>
+7 -1
View File
@@ -389,10 +389,12 @@ Example:
```yaml ```yaml
theme: theme:
# This will be the default theme
background-color: 100 20 10 background-color: 100 20 10
primary-color: 40 90 40 primary-color: 40 90 40
contrast-multiplier: 1.1 contrast-multiplier: 1.1
disable-picker: false
presets: presets:
gruvbox-dark: gruvbox-dark:
background-color: 0 0 16 background-color: 0 0 16
@@ -421,6 +423,7 @@ If you don't want to spend time configuring your own theme, there are [several a
| contrast-multiplier | number | no | 1 | | contrast-multiplier | number | no | 1 |
| text-saturation-multiplier | number | no | 1 | | text-saturation-multiplier | number | no | 1 |
| custom-css-file | string | no | | | custom-css-file | string | no | |
| disable-picker | bool | false | |
| presets | object | no | | | presets | object | no | |
#### `light` #### `light`
@@ -466,8 +469,11 @@ theme:
> >
> In addition, you can also use the `css-class` property which is available on every widget to set custom class names for individual widgets. > In addition, you can also use the `css-class` property which is available on every widget to set custom class names for individual widgets.
#### `disable-picker`
When set to `true` hides the theme picker and disables the abiltity to switch between themes. All users who previously picked a non-default theme will be switched over to the default theme.
#### `presets` #### `presets`
Define additional theme presets that can be selected from the theme switcher on the page. For each preset, you can specify the same properties as for the default theme, such as `background-color`, `primary-color`, `positive-color`, `negative-color`, `contrast-multiplier`, etc., except for the `custom-css-file` property. Define additional theme presets that can be selected from the theme picker on the page. For each preset, you can specify the same properties as for the default theme, such as `background-color`, `primary-color`, `positive-color`, `negative-color`, `contrast-multiplier`, etc., except for the `custom-css-file` property.
Example: Example:
+12 -3
View File
@@ -238,7 +238,7 @@ Output:
<div>90</div> <div>90</div>
``` ```
Other operations include `add`, `mul`, and `div`. Other operations include `add`, `mul`, `div` and `mod`.
<hr> <hr>
@@ -415,6 +415,14 @@ The following functions are available on the `JSON` object:
- `Array(key string) []JSON`: Returns the value of the key as an array of `JSON` objects. - `Array(key string) []JSON`: Returns the value of the key as an array of `JSON` objects.
- `Exists(key string) bool`: Returns true if the key exists in the JSON object. - `Exists(key string) bool`: Returns true if the key exists in the JSON object.
The following functions are available on the `Options` object:
- `StringOr(key string, default string) string`: Returns the value of the key as a string, or the default value if the key does not exist.
- `IntOr(key string, default int) int`: Returns the value of the key as an integer, or the default value if the key does not exist.
- `FloatOr(key string, default float) float`: Returns the value of the key as a float, or the default value if the key does not exist.
- `BoolOr(key string, default bool) bool`: Returns the value of the key as a boolean, or the default value if the key does not exist.
- `JSON(key string) JSON`: Returns the value of the key as a stringified `JSON` object, or throws an error if the key does not exist.
The following helper functions provided by Glance are available: The following helper functions provided by Glance are available:
- `toFloat(i int) float`: Converts an integer to a float. - `toFloat(i int) float`: Converts an integer to a float.
@@ -431,6 +439,7 @@ The following helper functions provided by Glance are available:
- `sub(a, b float) float`: Subtracts two numbers. - `sub(a, b float) float`: Subtracts two numbers.
- `mul(a, b float) float`: Multiplies two numbers. - `mul(a, b float) float`: Multiplies two numbers.
- `div(a, b float) float`: Divides two numbers. - `div(a, b float) float`: Divides two numbers.
- `mod(a, b int) int`: Remainder after dividing a by b (a % b).
- `formatApproxNumber(n int) string`: Formats a number to be more human-readable, e.g. 1000 -> 1k. - `formatApproxNumber(n int) string`: Formats a number to be more human-readable, e.g. 1000 -> 1k.
- `formatNumber(n float|int) string`: Formats a number with commas, e.g. 1000 -> 1,000. - `formatNumber(n float|int) string`: Formats a number with commas, e.g. 1000 -> 1,000.
- `trimPrefix(prefix string, str string) string`: Trims the prefix from a string. - `trimPrefix(prefix string, str string) string`: Trims the prefix from a string.
@@ -458,8 +467,8 @@ The following helper functions provided by Go's `text/template` are available:
- `lte(a, b any) bool`: Compares two values for less than or equal to. - `lte(a, b any) bool`: Compares two values for less than or equal to.
- `gt(a, b any) bool`: Compares two values for greater than. - `gt(a, b any) bool`: Compares two values for greater than.
- `gte(a, b any) bool`: Compares two values for greater than or equal to. - `gte(a, b any) bool`: Compares two values for greater than or equal to.
- `and(a, b bool) bool`: Returns true if both values are true. - `and(args ...bool) bool`: Returns true if **all** arguments are true; accepts two or more boolean values.
- `or(a, b bool) bool`: Returns true if either value is true. - `or(args ...bool) bool`: Returns true if **any** argument is true; accepts two or more boolean values.
- `not(a bool) bool`: Returns the opposite of the value. - `not(a bool) bool`: Returns the opposite of the value.
- `index(a any, b int) any`: Returns the value at the specified index of an array. - `index(a any, b int) any`: Returns the value at the specified index of an array.
- `len(a any) int`: Returns the length of an array. - `len(a any) int`: Returns the length of an array.
+4 -2
View File
@@ -47,8 +47,10 @@ type config struct {
Theme struct { Theme struct {
themeProperties `yaml:",inline"` themeProperties `yaml:",inline"`
CustomCSSFile string `yaml:"custom-css-file"` CustomCSSFile string `yaml:"custom-css-file"`
Presets orderedYAMLMap[string, *themeProperties] `yaml:"presets"`
DisablePicker bool `yaml:"disable-picker"`
Presets orderedYAMLMap[string, *themeProperties] `yaml:"presets"`
} `yaml:"theme"` } `yaml:"theme"`
Branding struct { Branding struct {
+5 -3
View File
@@ -12,7 +12,7 @@ import (
"time" "time"
) )
const httpTestRequestTimeout = 10 * time.Second const httpTestRequestTimeout = 15 * time.Second
var diagnosticSteps = []diagnosticStep{ var diagnosticSteps = []diagnosticStep{
{ {
@@ -75,7 +75,9 @@ var diagnosticSteps = []diagnosticStep{
{ {
name: "fetch data from Reddit API", name: "fetch data from Reddit API",
fn: func() (string, error) { fn: func() (string, error) {
return testHttpRequest("GET", "https://www.reddit.com/search.json", 200) return testHttpRequestWithHeaders("GET", "https://www.reddit.com/search.json", map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0",
}, 200)
}, },
}, },
{ {
@@ -165,7 +167,7 @@ func testHttpRequestWithHeaders(method, url string, headers map[string]string, e
request.Header.Add(key, value) request.Header.Add(key, value)
} }
response, err := http.DefaultClient.Do(request) response, err := defaultHTTPClient.Do(request)
if err != nil { if err != nil {
return "", err return "", err
} }
+39 -31
View File
@@ -101,35 +101,37 @@ func newApplication(c *config) (*application, error) {
// Init themes // Init themes
// //
themeKeys := make([]string, 0, 2) if !config.Theme.DisablePicker {
themeProps := make([]*themeProperties, 0, 2) themeKeys := make([]string, 0, 2)
themeProps := make([]*themeProperties, 0, 2)
defaultDarkTheme, ok := config.Theme.Presets.Get("default-dark") defaultDarkTheme, ok := config.Theme.Presets.Get("default-dark")
if ok && !config.Theme.SameAs(defaultDarkTheme) || !config.Theme.SameAs(&themeProperties{}) { if ok && !config.Theme.SameAs(defaultDarkTheme) || !config.Theme.SameAs(&themeProperties{}) {
themeKeys = append(themeKeys, "default-dark") themeKeys = append(themeKeys, "default-dark")
themeProps = append(themeProps, &themeProperties{}) themeProps = append(themeProps, &themeProperties{})
} }
themeKeys = append(themeKeys, "default-light") themeKeys = append(themeKeys, "default-light")
themeProps = append(themeProps, &themeProperties{ themeProps = append(themeProps, &themeProperties{
Light: true, Light: true,
BackgroundColor: &hslColorField{240, 13, 95}, BackgroundColor: &hslColorField{240, 13, 95},
PrimaryColor: &hslColorField{230, 100, 30}, PrimaryColor: &hslColorField{230, 100, 30},
NegativeColor: &hslColorField{0, 70, 50}, NegativeColor: &hslColorField{0, 70, 50},
ContrastMultiplier: 1.3, ContrastMultiplier: 1.3,
TextSaturationMultiplier: 0.5, TextSaturationMultiplier: 0.5,
}) })
themePresets, err := newOrderedYAMLMap(themeKeys, themeProps) themePresets, err := newOrderedYAMLMap(themeKeys, themeProps)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating theme presets: %v", err) return nil, fmt.Errorf("creating theme presets: %v", err)
} }
config.Theme.Presets = *themePresets.Merge(&config.Theme.Presets) config.Theme.Presets = *themePresets.Merge(&config.Theme.Presets)
for key, properties := range config.Theme.Presets.Items() { for key, properties := range config.Theme.Presets.Items() {
properties.Key = key properties.Key = key
if err := properties.init(); err != nil { if err := properties.init(); err != nil {
return nil, fmt.Errorf("initializing preset theme %s: %v", key, err) return nil, fmt.Errorf("initializing preset theme %s: %v", key, err)
}
} }
} }
@@ -288,11 +290,13 @@ type templateData struct {
func (a *application) populateTemplateRequestData(data *templateRequestData, r *http.Request) { func (a *application) populateTemplateRequestData(data *templateRequestData, r *http.Request) {
theme := &a.Config.Theme.themeProperties theme := &a.Config.Theme.themeProperties
selectedTheme, err := r.Cookie("theme") if !a.Config.Theme.DisablePicker {
if err == nil { selectedTheme, err := r.Cookie("theme")
preset, exists := a.Config.Theme.Presets.Get(selectedTheme.Value) if err == nil {
if exists { preset, exists := a.Config.Theme.Presets.Get(selectedTheme.Value)
theme = preset if exists {
theme = preset
}
} }
} }
@@ -436,7 +440,11 @@ func (a *application) server() (func() error, func() error) {
mux.HandleFunc("GET /{page}", a.handlePageRequest) mux.HandleFunc("GET /{page}", a.handlePageRequest)
mux.HandleFunc("GET /api/pages/{page}/content/{$}", a.handlePageContentRequest) mux.HandleFunc("GET /api/pages/{page}/content/{$}", a.handlePageContentRequest)
mux.HandleFunc("POST /api/set-theme/{key}", a.handleThemeChangeRequest)
if !a.Config.Theme.DisablePicker {
mux.HandleFunc("POST /api/set-theme/{key}", a.handleThemeChangeRequest)
}
mux.HandleFunc("/api/widgets/{widget}/{path...}", a.handleWidgetRequest) mux.HandleFunc("/api/widgets/{widget}/{path...}", a.handleWidgetRequest)
mux.HandleFunc("GET /api/healthz", func(w http.ResponseWriter, _ *http.Request) { mux.HandleFunc("GET /api/healthz", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
+8 -4
View File
@@ -661,7 +661,7 @@ function setupTruncatedElementTitles() {
for (let i = 0; i < elements.length; i++) { for (let i = 0; i < elements.length; i++) {
const element = elements[i]; const element = elements[i];
if (element.getAttribute("title") === null) element.title = element.textContent; if (element.getAttribute("title") === null) element.title = element.innerText;
} }
} }
@@ -683,17 +683,21 @@ async function changeTheme(key, onChanged) {
.appendTo(document.head); .appendTo(document.head);
themeStyleElem.html(newThemeStyle); themeStyleElem.html(newThemeStyle);
document.documentElement.setAttribute("data-theme", key);
document.documentElement.setAttribute("data-scheme", response.headers.get("X-Scheme")); document.documentElement.setAttribute("data-scheme", response.headers.get("X-Scheme"));
typeof onChanged == "function" && onChanged(); typeof onChanged == "function" && onChanged();
setTimeout(() => { tempStyle.remove(); }, 10); setTimeout(() => { tempStyle.remove(); }, 10);
} }
function initThemeSwitcher() { function initThemePicker() {
const themeChoicesInMobileNav = find(".mobile-navigation .theme-choices");
if (!themeChoicesInMobileNav) return;
const themeChoicesInHeader = find(".header-container .theme-choices"); const themeChoicesInHeader = find(".header-container .theme-choices");
if (themeChoicesInHeader) { if (themeChoicesInHeader) {
themeChoicesInHeader.replaceWith( themeChoicesInHeader.replaceWith(
find(".mobile-navigation .theme-choices").cloneNode(true) themeChoicesInMobileNav.cloneNode(true)
); );
} }
@@ -738,7 +742,7 @@ function initThemeSwitcher() {
} }
async function setupPage() { async function setupPage() {
initThemeSwitcher(); initThemePicker();
const pageElement = document.getElementById("page"); const pageElement = document.getElementById("page");
const pageContentElement = document.getElementById("page-content"); const pageContentElement = document.getElementById("page-content");
+3 -2
View File
@@ -5,7 +5,6 @@ import (
"html/template" "html/template"
"math" "math"
"strconv" "strconv"
"strings"
"golang.org/x/text/language" "golang.org/x/text/language"
"golang.org/x/text/message" "golang.org/x/text/message"
@@ -22,6 +21,9 @@ var globalTemplateFunctions = template.FuncMap{
"safeURL": func(str string) template.URL { "safeURL": func(str string) template.URL {
return template.URL(str) return template.URL(str)
}, },
"safeHTML": func(str string) template.HTML {
return template.HTML(str)
},
"absInt": func(i int) int { "absInt": func(i int) int {
return int(math.Abs(float64(i))) return int(math.Abs(float64(i)))
}, },
@@ -54,7 +56,6 @@ var globalTemplateFunctions = template.FuncMap{
return template.HTML(value + ` <span class="color-base size-h5">` + label + `</span>`) return template.HTML(value + ` <span class="color-base size-h5">` + label + `</span>`)
}, },
"hasPrefix": strings.HasPrefix,
} }
func mustParseTemplate(primary string, dependencies ...string) *template.Template { func mustParseTemplate(primary string, dependencies ...string) *template.Template {
+1 -1
View File
@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" id="top" data-scheme="{{ if .Request.Theme.Light }}light{{ else }}dark{{ end }}"> <html lang="en" id="top" data-theme="{{ .Request.Theme.Key }}" data-scheme="{{ if .Request.Theme.Light }}light{{ else }}dark{{ end }}">
<head> <head>
{{ block "document-head-before" . }}{{ end }} {{ block "document-head-before" . }}{{ end }}
<script> <script>
+4
View File
@@ -33,6 +33,7 @@
<nav class="nav flex grow hide-scrollbars"> <nav class="nav flex grow hide-scrollbars">
{{ template "navigation-links" . }} {{ template "navigation-links" . }}
</nav> </nav>
{{ if not .App.Config.Theme.DisablePicker }}
<div class="theme-picker self-center" data-popover-type="html" data-popover-position="below" data-popover-show-delay="0"> <div class="theme-picker self-center" data-popover-type="html" data-popover-position="below" data-popover-show-delay="0">
<div class="current-theme-preview"> <div class="current-theme-preview">
{{ .Request.Theme.PreviewHTML }} {{ .Request.Theme.PreviewHTML }}
@@ -41,6 +42,7 @@
<div class="theme-choices"></div> <div class="theme-choices"></div>
</div> </div>
</div> </div>
{{ end }}
{{- if .App.RequiresAuth }} {{- if .App.RequiresAuth }}
<a class="block self-center" href="{{ .App.Config.Server.BaseURL }}/logout" title="Logout"> <a class="block self-center" href="{{ .App.Config.Server.BaseURL }}/logout" title="Logout">
<svg class="logout-button" stroke="var(--color-text-subdue)" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"> <svg class="logout-button" stroke="var(--color-text-subdue)" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
@@ -66,6 +68,7 @@
</div> </div>
<div class="mobile-navigation-actions flex flex-column margin-block-10"> <div class="mobile-navigation-actions flex flex-column margin-block-10">
{{ if not .App.Config.Theme.DisablePicker }}
<div class="theme-picker flex justify-between items-center" data-popover-type="html" data-popover-position="above" data-popover-show-delay="0" data-popover-hide-delay="100" data-popover-anchor=".current-theme-preview" data-popover-trigger="click"> <div class="theme-picker flex justify-between items-center" data-popover-type="html" data-popover-position="above" data-popover-show-delay="0" data-popover-hide-delay="100" data-popover-anchor=".current-theme-preview" data-popover-trigger="click">
<div data-popover-html> <div data-popover-html>
<div class="theme-choices"> <div class="theme-choices">
@@ -87,6 +90,7 @@
</svg> </svg>
</div> </div>
</div> </div>
{{ end }}
{{ if .App.RequiresAuth }} {{ if .App.RequiresAuth }}
<a href="{{ .App.Config.Server.BaseURL }}/logout" class="flex justify-between items-center"> <a href="{{ .App.Config.Server.BaseURL }}/logout" class="flex justify-between items-center">
+20
View File
@@ -108,6 +108,20 @@ func (o *customAPIOptions) BoolOr(key string, defaultValue bool) bool {
return customAPIGetOptionOrDefault(*o, key, defaultValue) return customAPIGetOptionOrDefault(*o, key, defaultValue)
} }
func (o *customAPIOptions) JSON(key string) string {
value, exists := (*o)[key]
if !exists {
panic(fmt.Sprintf("key %q does not exist in options", key))
}
encoded, err := json.Marshal(value)
if err != nil {
panic(fmt.Sprintf("marshaling %s: %v", key, err))
}
return string(encoded)
}
func customAPIGetOptionOrDefault[T any](o customAPIOptions, key string, defaultValue T) T { func customAPIGetOptionOrDefault[T any](o customAPIOptions, key string, defaultValue T) T {
if value, exists := o[key]; exists { if value, exists := o[key]; exists {
if typedValue, ok := value.(T); ok { if typedValue, ok := value.(T); ok {
@@ -479,6 +493,12 @@ var customAPITemplateFuncs = func() template.FuncMap {
"div": func(a, b any) any { "div": func(a, b any) any {
return doMathOpWithAny(a, b, "div") return doMathOpWithAny(a, b, "div")
}, },
"mod": func(a, b int) int {
if b == 0 {
return 0
}
return a % b
},
"now": func() time.Time { "now": func() time.Time {
return time.Now() return time.Now()
}, },
+2
View File
@@ -26,6 +26,7 @@ const defaultClientTimeout = 5 * time.Second
var defaultHTTPClient = &http.Client{ var defaultHTTPClient = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
MaxIdleConnsPerHost: 10, MaxIdleConnsPerHost: 10,
Proxy: http.ProxyFromEnvironment,
}, },
Timeout: defaultClientTimeout, Timeout: defaultClientTimeout,
} }
@@ -34,6 +35,7 @@ var defaultInsecureHTTPClient = &http.Client{
Timeout: defaultClientTimeout, Timeout: defaultClientTimeout,
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
}, },
} }