From d1b8d0aa1b42950c7a37b2dd72e9c2f2f0cafb37 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 27 Mar 2013 16:58:22 -0700 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 3 + src/omaha/fixtures/appid.txt | 1 + src/omaha/fixtures/request.xml | 12 ++ .../update-engine/no-update/request.xml | 7 + .../update-engine/no-update/response.xml | 7 + .../fixtures/update-engine/update/request.xml | 9 ++ .../update-engine/update/response.xml | 27 ++++ src/omaha/omaha.go | 138 ++++++++++++++++++ src/omaha/omaha_test.go | 60 ++++++++ 10 files changed, 265 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 src/omaha/fixtures/appid.txt create mode 100644 src/omaha/fixtures/request.xml create mode 100644 src/omaha/fixtures/update-engine/no-update/request.xml create mode 100644 src/omaha/fixtures/update-engine/no-update/response.xml create mode 100644 src/omaha/fixtures/update-engine/update/request.xml create mode 100644 src/omaha/fixtures/update-engine/update/response.xml create mode 100644 src/omaha/omaha.go create mode 100644 src/omaha/omaha_test.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5fff1d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pkg diff --git a/README.md b/README.md new file mode 100644 index 0000000..eef5579 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Implementation of the omaha protocol in Go. + +https://code.google.com/p/omaha/ diff --git a/src/omaha/fixtures/appid.txt b/src/omaha/fixtures/appid.txt new file mode 100644 index 0000000..a90c4ed --- /dev/null +++ b/src/omaha/fixtures/appid.txt @@ -0,0 +1 @@ +AC07C722-45D6-4D0E-B1D4-2E1E297569A1 diff --git a/src/omaha/fixtures/request.xml b/src/omaha/fixtures/request.xml new file mode 100644 index 0000000..185d2a5 --- /dev/null +++ b/src/omaha/fixtures/request.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/omaha/fixtures/update-engine/no-update/request.xml b/src/omaha/fixtures/update-engine/no-update/request.xml new file mode 100644 index 0000000..7fe5e81 --- /dev/null +++ b/src/omaha/fixtures/update-engine/no-update/request.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/omaha/fixtures/update-engine/no-update/response.xml b/src/omaha/fixtures/update-engine/no-update/response.xml new file mode 100644 index 0000000..02d6c75 --- /dev/null +++ b/src/omaha/fixtures/update-engine/no-update/response.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/omaha/fixtures/update-engine/update/request.xml b/src/omaha/fixtures/update-engine/update/request.xml new file mode 100644 index 0000000..6510544 --- /dev/null +++ b/src/omaha/fixtures/update-engine/update/request.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/omaha/fixtures/update-engine/update/response.xml b/src/omaha/fixtures/update-engine/update/response.xml new file mode 100644 index 0000000..affcee4 --- /dev/null +++ b/src/omaha/fixtures/update-engine/update/response.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/omaha/omaha.go b/src/omaha/omaha.go new file mode 100644 index 0000000..a08d8ce --- /dev/null +++ b/src/omaha/omaha.go @@ -0,0 +1,138 @@ +/* + Package that implements the Google omaha protocol. + + Omaha is a request/response protocol using XML. Requests are made by + clients and responses are given by the Omaha server. + http://code.google.com/p/omaha/wiki/ServerProtocol + The +*/ +package omaha + +import "encoding/xml" + +type Request struct { + Os Os + Apps []App `xml:"app"` + Protocol string `xml:"protocol,attr"` + Version string `xml:"version,attr,omitempty"` + IsMachine string `xml:"ismachine,attr,omitempty"` + SessionId string `xml:"sessionid,attr,omitempty"` + UserId string `xml:"userid,attr,omitempty"` + InstallSource string `xml:"installsource,attr,omitempty"` + TestSource string `xml:"testsource,attr,omitempty"` + RequestId string `xml:"requestid,attr,omitempty"` + UpdaterVersion string `xml:"updaterversion,attr,omitempty"` +} + +func NewRequest(os *Os, app *App) *Request { + r := new(Request) + r.Protocol = "3.0" + r.AddApp(app) + r.Os = *os + return r +} + +func (r *Request) AddApp(a *App) { + r.Apps = append(r.Apps, *a) +} + +// app element +type App struct { + XMLName xml.Name `xml:"app"` + UpdateCheck *UpdateCheck `xml:"updatecheck"` + Ping *Ping + Id string `xml:"appid,attr,omitempty"` + Version string `xml:"version,attr,omitempty"` + NextVersion string `xml:"nextversion,attr,omitempty"` + Lang string `xml:"lang,attr,omitempty"` + Client string `xml:"client,attr,omitempty"` + InstallAge string `xml:"installage,attr,omitempty"` +} + +func NewApp(id string, version string) *App { + a := new(App) + a.Id = id + a.Version = version + return a +} + +type UpdateCheck struct { + XMLName xml.Name `xml:"updatecheck"` + TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"` +} + +func (a *App) AddUpdateCheck() { + a.UpdateCheck = new(UpdateCheck) +} + +type Ping struct { + XMLName xml.Name `xml:"ping"` + LastReportDays string `xml:"r,attr,omitempty"` +} + +type Os struct { + XMLName xml.Name `xml:"os"` + Platform string `xml:"platform,attr,omitempty"` + Version string `xml:"version,attr,omitempty"` + Sp string `xml:"sp,attr,omitempty"` + Arch string `xml:"arch,attr,omitempty"` +} + +func NewOs(platform string, version string, sp string, arch string) *Os { + o := new(Os) + o.Platform = platform + o.Version = version + o.Sp = sp + o.Arch = arch + return o +} + +func (a *App) AddPing() { +} + +type Event struct { + XMLName xml.Name `xml:"event"` + EventType string `xml:"eventtype,attr,omitempty"` + EventResult string `xml:"eventresult,attr,omitempty"` + PreviousVersion string `xml:"previousversion,attr,omitempty"` +} + +var EventTypes = map[int] string { + 0: "unknown", + 1: "download complete", + 2: "install complete", + 3: "update complete", + 4: "uninstall", + 5: "download started", + 6: "install started", + 9: "new application install started", + 10: "setup started", + 11: "setup finished", + 12: "update application started", + 13: "update download started", + 14: "update download finished", + 15: "update installer started", + 16: "setup update begin", + 17: "setup update complete", + 20: "register product complete", + 30: "OEM install first check", + 40: "app-specific command started", + 41: "app-specific command ended", + 100: "setup failure", + 102: "COM server failure", + 103: "setup update failure", +} + +var EventResults = map[int] string { + 0: "error", + 1: "success", + 2: "success reboot", + 3: "success restart browser", + 4: "cancelled", + 5: "error installer MSI", + 6: "error installer other", + 7: "noupdate", + 8: "error installer system", + 9: "update deferred", + 10: "handoff error", +} diff --git a/src/omaha/omaha_test.go b/src/omaha/omaha_test.go new file mode 100644 index 0000000..eaeb38e --- /dev/null +++ b/src/omaha/omaha_test.go @@ -0,0 +1,60 @@ +package omaha + +import ( + "testing" + "fmt" + "encoding/xml" + "io/ioutil" + "os" +) + +func TestOmahaUpdateCheck(t *testing.T) { + file, err := os.Open("fixtures/update-engine/update/request.xml") + if err != nil { + t.Error(err) + } + fix, err := ioutil.ReadAll(file) + if err != nil { + t.Error(err) + } + v := Request{} + xml.Unmarshal(fix, &v) + + if v.Os.Version != "Indy" { + t.Error("Unexpected version", v.Os.Version) + } + + if v.Apps[0].Id != "{87efface-864d-49a5-9bb3-4b050a7c227a}" { + t.Error("Expected an App Id") + } + + if v.Apps[0].UpdateCheck == nil { + t.Error("Expected an UpdateCheck") + } +} + +func ExampleOmaha_NewRequest() { + os := NewOs("linux", "3.0", "", "x64") + + app := NewApp("{27BD862E-8AE8-4886-A055-F7F1A6460627}", "1.0.0.0") + app.AddUpdateCheck() + + request := NewRequest(os, app) + + if raw, err := xml.MarshalIndent(request, "", " "); err != nil { + fmt.Println(err) + return + } else { + fmt.Printf("%s%s\n", xml.Header, raw) + } + + // Output: + // + // + // + // + // + // + // + // +}