Compare commits
10 Commits
4876998f5d
...
1.0.11
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c65cdb156 | |||
| ae013f9a3b | |||
| d94b53c395 | |||
| 847931ed43 | |||
| 4387236d22 | |||
| f6ce004922 | |||
| 8e487876d2 | |||
| 1be7f5bd20 | |||
| f237b89ca7 | |||
| ae07239021 |
@@ -2,11 +2,17 @@ version: 2
|
|||||||
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- go mod tidy
|
- go mod tidy -v
|
||||||
|
|
||||||
builds:
|
builds:
|
||||||
- ldflags:
|
- id: default
|
||||||
|
binary: steamcache2
|
||||||
|
ldflags:
|
||||||
|
- -s
|
||||||
|
- -w
|
||||||
|
- -extldflags "-static"
|
||||||
- -X s1d3sw1ped/SteamCache2/version.Version={{.Version}}
|
- -X s1d3sw1ped/SteamCache2/version.Version={{.Version}}
|
||||||
|
- -X s1d3sw1ped/SteamCache2/version.Date={{.Date}}
|
||||||
env:
|
env:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
goos:
|
goos:
|
||||||
@@ -14,19 +20,24 @@ builds:
|
|||||||
- windows
|
- windows
|
||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
|
- arm64
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm64
|
||||||
|
|
||||||
|
checksum:
|
||||||
|
name_template: "checksums.txt"
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- formats: tar.gz
|
- id: default
|
||||||
name_template: >-
|
name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
|
||||||
{{ .ProjectName }}_
|
formats: tar.gz
|
||||||
{{- title .Os }}_
|
|
||||||
{{- if eq .Arch "amd64" }}x86_64
|
|
||||||
{{- else if eq .Arch "386" }}i386
|
|
||||||
{{- else }}{{ .Arch }}{{ end }}
|
|
||||||
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
|
||||||
format_overrides:
|
format_overrides:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
formats: zip
|
formats: zip
|
||||||
|
files:
|
||||||
|
- README.md
|
||||||
|
- LICENSE
|
||||||
|
|
||||||
changelog:
|
changelog:
|
||||||
sort: asc
|
sort: asc
|
||||||
@@ -36,12 +47,7 @@ changelog:
|
|||||||
- "^test:"
|
- "^test:"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name_template: '{{.ProjectName}}-{{.Version}}'
|
name_template: "{{ .ProjectName }}-{{ .Version }}"
|
||||||
footer: >-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Released by [GoReleaser](https://github.com/goreleaser/goreleaser).
|
|
||||||
|
|
||||||
gitea_urls:
|
gitea_urls:
|
||||||
api: https://git.s1d3sw1ped.com/api/v1
|
api: https://git.s1d3sw1ped.com/api/v1
|
||||||
|
|||||||
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@@ -23,6 +23,8 @@
|
|||||||
"lru",
|
"lru",
|
||||||
"--log-level",
|
"--log-level",
|
||||||
"debug",
|
"debug",
|
||||||
|
"--upstream",
|
||||||
|
"http://192.168.2.5:80",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -40,6 +42,8 @@
|
|||||||
"hybrid",
|
"hybrid",
|
||||||
"--log-level",
|
"--log-level",
|
||||||
"debug",
|
"debug",
|
||||||
|
"--upstream",
|
||||||
|
"http://192.168.2.5:80",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -55,6 +59,8 @@
|
|||||||
"lfu",
|
"lfu",
|
||||||
"--log-level",
|
"--log-level",
|
||||||
"debug",
|
"debug",
|
||||||
|
"--upstream",
|
||||||
|
"http://192.168.2.5:80",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ var rootCmd = &cobra.Command{
|
|||||||
logger.Logger = zerolog.New(writer).With().Timestamp().Logger()
|
logger.Logger = zerolog.New(writer).With().Timestamp().Logger()
|
||||||
|
|
||||||
logger.Logger.Info().
|
logger.Logger.Info().
|
||||||
Msg("SteamCache2 " + version.Version + " starting...")
|
Msg("SteamCache2 " + version.Version + " " + version.Date + " starting...")
|
||||||
|
|
||||||
address := ":80"
|
address := ":80"
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var versionCmd = &cobra.Command{
|
|||||||
Short: "prints the version of SteamCache2",
|
Short: "prints the version of SteamCache2",
|
||||||
Long: `Prints the version of SteamCache2. This command is useful for checking the version of the application.`,
|
Long: `Prints the version of SteamCache2. This command is useful for checking the version of the application.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Fprintln(os.Stderr, "SteamCache2", version.Version)
|
fmt.Fprintln(os.Stderr, "SteamCache2", version.Version, version.Date)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,21 +222,23 @@ func New(address string, memorySize string, diskSize string, diskPath, upstream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
MaxIdleConns: 100,
|
MaxIdleConns: 200, // Increased from 100
|
||||||
MaxIdleConnsPerHost: 10,
|
MaxIdleConnsPerHost: 50, // Increased from 10
|
||||||
IdleConnTimeout: 90 * time.Second,
|
IdleConnTimeout: 120 * time.Second, // Increased from 90s
|
||||||
DialContext: (&net.Dialer{
|
DialContext: (&net.Dialer{
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
KeepAlive: 30 * time.Second,
|
KeepAlive: 30 * time.Second,
|
||||||
}).DialContext,
|
}).DialContext,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 15 * time.Second, // Increased from 10s
|
||||||
ResponseHeaderTimeout: 10 * time.Second,
|
ResponseHeaderTimeout: 30 * time.Second, // Increased from 10s
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 5 * time.Second, // Increased from 1s
|
||||||
|
DisableCompression: true, // Steam doesn't use compression
|
||||||
|
ForceAttemptHTTP2: true, // Enable HTTP/2 if available
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
Timeout: 60 * time.Second,
|
Timeout: 120 * time.Second, // Increased from 60s
|
||||||
}
|
}
|
||||||
|
|
||||||
sc := &SteamCache{
|
sc := &SteamCache{
|
||||||
@@ -250,9 +252,11 @@ func New(address string, memorySize string, diskSize string, diskPath, upstream,
|
|||||||
client: client,
|
client: client,
|
||||||
server: &http.Server{
|
server: &http.Server{
|
||||||
Addr: address,
|
Addr: address,
|
||||||
ReadTimeout: 5 * time.Second,
|
ReadTimeout: 30 * time.Second, // Increased
|
||||||
WriteTimeout: 10 * time.Second,
|
WriteTimeout: 60 * time.Second, // Increased
|
||||||
IdleTimeout: 120 * time.Second,
|
IdleTimeout: 120 * time.Second, // Good for keep-alive
|
||||||
|
ReadHeaderTimeout: 10 * time.Second, // New, for header attacks
|
||||||
|
MaxHeaderBytes: 1 << 20, // 1MB, optional
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +270,8 @@ func New(address string, memorySize string, diskSize string, diskPath, upstream,
|
|||||||
|
|
||||||
if d != nil {
|
if d != nil {
|
||||||
if d.Size() > d.Capacity() {
|
if d.Size() > d.Capacity() {
|
||||||
gc.LRUGC(d, uint(d.Size()-d.Capacity()))
|
gcHandler := gc.GetGCAlgorithm(gc.GCAlgorithm(diskGC))
|
||||||
|
gcHandler(d, uint(d.Size()-d.Capacity()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +282,7 @@ func (sc *SteamCache) Run() {
|
|||||||
if sc.upstream != "" {
|
if sc.upstream != "" {
|
||||||
resp, err := sc.client.Get(sc.upstream)
|
resp, err := sc.client.Get(sc.upstream)
|
||||||
if err != nil || resp.StatusCode != http.StatusOK {
|
if err != nil || resp.StatusCode != http.StatusOK {
|
||||||
logger.Logger.Error().Err(err).Str("upstream", sc.upstream).Msg("Failed to connect to upstream server")
|
logger.Logger.Error().Err(err).Int("status_code", resp.StatusCode).Str("upstream", sc.upstream).Msg("Failed to connect to upstream server")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
@@ -310,11 +315,6 @@ func (sc *SteamCache) Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.URL.Path == "/metrics" {
|
|
||||||
promhttp.Handler().ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Method != http.MethodGet {
|
if r.Method != http.MethodGet {
|
||||||
requestsTotal.WithLabelValues(r.Method, "405").Inc()
|
requestsTotal.WithLabelValues(r.Method, "405").Inc()
|
||||||
logger.Logger.Warn().Str("method", r.Method).Msg("Only GET method is supported")
|
logger.Logger.Warn().Str("method", r.Method).Msg("Only GET method is supported")
|
||||||
@@ -322,6 +322,11 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.URL.Path == "/" {
|
||||||
|
w.WriteHeader(http.StatusOK) // this is used by steamcache2's upstream verification at startup
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if r.URL.String() == "/lancache-heartbeat" {
|
if r.URL.String() == "/lancache-heartbeat" {
|
||||||
w.Header().Add("X-LanCache-Processed-By", "SteamCache2")
|
w.Header().Add("X-LanCache-Processed-By", "SteamCache2")
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
@@ -329,6 +334,11 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.URL.Path == "/metrics" {
|
||||||
|
promhttp.Handler().ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(r.URL.String(), "/depot/") {
|
if strings.HasPrefix(r.URL.String(), "/depot/") {
|
||||||
// trim the query parameters from the URL path
|
// trim the query parameters from the URL path
|
||||||
// this is necessary because the cache key should not include query parameters
|
// this is necessary because the cache key should not include query parameters
|
||||||
@@ -453,18 +463,6 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
filename := filepath.Base(cacheKey)
|
filename := filepath.Base(cacheKey)
|
||||||
expectedHash, hasHash := extractHashFromFilename(filename)
|
expectedHash, hasHash := extractHashFromFilename(filename)
|
||||||
|
|
||||||
// Debug logging for manifest files
|
|
||||||
if strings.Contains(cacheKey, "manifest") {
|
|
||||||
logger.Logger.Debug().
|
|
||||||
Str("key", cacheKey).
|
|
||||||
Str("filename", filename).
|
|
||||||
Bool("hasHash", hasHash).
|
|
||||||
Str("expectedHash", expectedHash).
|
|
||||||
Int64("content_length_header", resp.ContentLength).
|
|
||||||
Int("actual_content_length", len(bodyData)).
|
|
||||||
Msg("Manifest file hash verification debug")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash verification using Steam's X-Content-Sha header and content length verification
|
// Hash verification using Steam's X-Content-Sha header and content length verification
|
||||||
hashVerified := true
|
hashVerified := true
|
||||||
if hasHash {
|
if hasHash {
|
||||||
@@ -522,7 +520,6 @@ func (sc *SteamCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
Str("key", cacheKey).
|
Str("key", cacheKey).
|
||||||
Str("host", r.Host).
|
Str("host", r.Host).
|
||||||
Str("status", "MISS").
|
Str("status", "MISS").
|
||||||
Bool("hash_verified", hasHash).
|
|
||||||
Dur("duration", time.Since(tstart)).
|
Dur("duration", time.Since(tstart)).
|
||||||
Msg("request")
|
Msg("request")
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
// version/version.go
|
// version/version.go
|
||||||
package version
|
package version
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
var Version string
|
var Version string
|
||||||
|
var Date string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if Version == "" {
|
if Version == "" {
|
||||||
Version = "0.0.0-dev"
|
Version = "0.0.0-dev"
|
||||||
}
|
}
|
||||||
|
if Date == "" {
|
||||||
|
Date = time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user