Skip to content

Instantly share code, notes, and snippets.

@ayanamist
Created April 15, 2021 07:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayanamist/30a2b4b202e244219ebbbe8b92a88bf9 to your computer and use it in GitHub Desktop.
Save ayanamist/30a2b4b202e244219ebbbe8b92a88bf9 to your computer and use it in GitHub Desktop.
Check Chrome Stable Update
module github.com/ayanamist/CheckChrome
require github.com/google/uuid v1.2.0
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
package main
import (
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"strings"
"sync"
"time"
"github.com/google/uuid"
)
const (
updateUrl = "https://tools.google.com/service/update2"
archX86 = "x86"
archX64 = "x64"
channelStableX86 = "-multi-chrome"
channelStableX64 = "x64-stable-multi-chrome"
channelBetaX86 = "1.1-beta"
channelBetaX64 = "x64-beta-multi-chrome"
channelDevX86 = "2.0-dev"
channelDevX64 = "x64-dev-multi-chrome"
channelCanaryX86 = "" // not a mistake, yes, it's blank
channelCanaryX64 = "x64-canary"
postBodyTemplate = `<?xml version='1.0' encoding='UTF-8'?>
<request protocol='3.0' version='1.3.23.9' shell_version='1.3.21.103' ismachine='0'
sessionid='%s' installsource='ondemandcheckforupdate'
requestid='%s' dedup='cr'>
<hw sse='1' sse2='1' sse3='1' ssse3='1' sse41='1' sse42='1' avx='1' physmemory='12582912' />
<os platform='win' version='6.3' arch='%s'/>
<app appid='{8A69D345-D564-463C-AFF1-A69D9E530F96}' ap='%s' version='' nextversion='' lang='' brand='GGLS' client=''>
<updatecheck/>
</app>
</request>`
)
var (
httpClient = &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 10 * time.Second,
}).DialContext,
ResponseHeaderTimeout: 10 * time.Second,
},
Timeout: 30 * time.Second,
}
)
type Response struct {
Urls []struct {
Codebase string `xml:"codebase,attr"`
} `xml:"app>updatecheck>urls>url"`
Manifest struct {
Version string `xml:"version,attr"`
Package struct {
HashSha256 string `xml:"hash_sha256,attr"`
Name string `xml:"name,attr"`
Size string `xml:"size,attr"`
} `xml:"packages>package"`
} `xml:"app>updatecheck>manifest"`
}
type args struct {
friendlyName string
arch string
channel string
}
func httpPost(url string, body string) ([]byte, error) {
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(body))
if err != nil {
return nil, err
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
respBody, err := ioutil.ReadAll(resp.Body)
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
return respBody, err
}
func main() {
args := []args{
{"X86 Stable", archX86, channelStableX86},
{"X64 Stable", archX64, channelStableX64},
}
wg := sync.WaitGroup{}
wg.Add(len(args))
for _, v := range args {
a := v
go func() {
defer wg.Done()
resp, err := httpPost(updateUrl, fmt.Sprintf(postBodyTemplate, uuid.NewString(), uuid.NewString(), a.arch, a.channel))
if err != nil {
log.Printf("%+v post error: %v", a, err)
return
}
var result Response
if err := xml.Unmarshal(resp, &result); err != nil {
log.Printf("%+v unmarshal error: %v\n%s", a, err, resp)
return
}
var downloadUrl string
pkg := result.Manifest.Package
codebaseUrls := result.Urls
for _, c := range codebaseUrls {
s := c.Codebase
if strings.Contains(s, "https://dl.google.com/") {
downloadUrl = s + pkg.Name
break
}
}
if downloadUrl == "" && len(codebaseUrls) > 0 {
downloadUrl = codebaseUrls[0].Codebase + pkg.Name
}
fmt.Printf("%s updates:\nVersion: %s\nDownload: %s\nSHA256: %s\nSize: %s\n\n",
a.friendlyName, result.Manifest.Version, downloadUrl, pkg.HashSha256, pkg.Size)
}()
}
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment