|
|
package utils |
|
|
|
|
|
import ( |
|
|
"context" |
|
|
"encoding/json" |
|
|
"fmt" |
|
|
"net" |
|
|
"net/http" |
|
|
"time" |
|
|
|
|
|
"github.com/apernet/hysteria/core/v2/client" |
|
|
) |
|
|
|
|
|
const ( |
|
|
updateCheckEndpoint = "https://api.hy2.io/v1/update" |
|
|
updateCheckTimeout = 10 * time.Second |
|
|
) |
|
|
|
|
|
type UpdateChecker struct { |
|
|
CurrentVersion string |
|
|
Platform string |
|
|
Architecture string |
|
|
Channel string |
|
|
Side string |
|
|
Client *http.Client |
|
|
} |
|
|
|
|
|
func NewServerUpdateChecker(currentVersion, platform, architecture, channel string) *UpdateChecker { |
|
|
return &UpdateChecker{ |
|
|
CurrentVersion: currentVersion, |
|
|
Platform: platform, |
|
|
Architecture: architecture, |
|
|
Channel: channel, |
|
|
Side: "server", |
|
|
Client: &http.Client{ |
|
|
Timeout: updateCheckTimeout, |
|
|
}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func NewClientUpdateChecker(currentVersion, platform, architecture, channel string, hyClient client.Client) *UpdateChecker { |
|
|
return &UpdateChecker{ |
|
|
CurrentVersion: currentVersion, |
|
|
Platform: platform, |
|
|
Architecture: architecture, |
|
|
Channel: channel, |
|
|
Side: "client", |
|
|
Client: &http.Client{ |
|
|
Timeout: updateCheckTimeout, |
|
|
Transport: &http.Transport{ |
|
|
DialContext: func(_ context.Context, network, addr string) (net.Conn, error) { |
|
|
|
|
|
return hyClient.TCP(addr) |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
|
|
|
type UpdateResponse struct { |
|
|
HasUpdate bool `json:"update"` |
|
|
LatestVersion string `json:"lver"` |
|
|
URL string `json:"url"` |
|
|
Urgent bool `json:"urgent"` |
|
|
} |
|
|
|
|
|
func (uc *UpdateChecker) Check() (*UpdateResponse, error) { |
|
|
url := fmt.Sprintf("%s?cver=%s&plat=%s&arch=%s&chan=%s&side=%s", |
|
|
updateCheckEndpoint, |
|
|
uc.CurrentVersion, |
|
|
uc.Platform, |
|
|
uc.Architecture, |
|
|
uc.Channel, |
|
|
uc.Side, |
|
|
) |
|
|
resp, err := uc.Client.Get(url) |
|
|
if err != nil { |
|
|
return nil, err |
|
|
} |
|
|
defer resp.Body.Close() |
|
|
|
|
|
if resp.StatusCode != http.StatusOK { |
|
|
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) |
|
|
} |
|
|
var uResp UpdateResponse |
|
|
decoder := json.NewDecoder(resp.Body) |
|
|
if err := decoder.Decode(&uResp); err != nil { |
|
|
return nil, err |
|
|
} |
|
|
return &uResp, nil |
|
|
} |
|
|
|