Hello community, here is the log from the commit of package go-goauth2 for openSUSE:Factory checked in at Fri Oct 7 00:47:36 CEST 2011.
-------- --- openSUSE:Factory/go-goauth2/go-goauth2.changes 2011-09-23 02:01:30.000000000 +0200 +++ go-goauth2/go-goauth2.changes 2011-10-06 16:12:12.000000000 +0200 @@ -1,0 +2,6 @@ +Thu Oct 6 14:11:22 UTC 2011 - [email protected] + +- Update to hg 13.08.2011 + - refresh token before attempting HTTP request + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- goauth2-0.0.0+hg20110617.tar.bz2 New: ---- goauth2-0.0.0+hg20110813.tar.bz2 rpmlintrc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ go-goauth2.spec ++++++ --- /var/tmp/diff_new_pack.QiF5fh/_old 2011-10-07 00:47:31.000000000 +0200 +++ /var/tmp/diff_new_pack.QiF5fh/_new 2011-10-07 00:47:31.000000000 +0200 @@ -19,7 +19,7 @@ Name: go-goauth2 -Version: 0.0.0+hg20110617 +Version: 0.0.0+hg20110813 Release: 1 Summary: OAuth 2.0 for Go clients Group: Development/Languages/Other ++++++ goauth2-0.0.0+hg20110617.tar.bz2 -> goauth2-0.0.0+hg20110813.tar.bz2 ++++++ Files old/goauth2/.hg/00changelog.i and new/goauth2/.hg/00changelog.i differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/branch new/goauth2/.hg/branch --- old/goauth2/.hg/branch 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/branch 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1 @@ +default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/cache/branchheads new/goauth2/.hg/cache/branchheads --- old/goauth2/.hg/cache/branchheads 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/cache/branchheads 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,2 @@ +1d1bf184962bfb6857eb4360e745adaef1390205 20 +1d1bf184962bfb6857eb4360e745adaef1390205 default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/cache/tags new/goauth2/.hg/cache/tags --- old/goauth2/.hg/cache/tags 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/cache/tags 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,5 @@ +20 1d1bf184962bfb6857eb4360e745adaef1390205 dbd998807b7aad9a4682c2e357d90c61582a921f + +379476c9e05c5275356e0a82ca079e61869e9192 release +dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly.2011-08-17 +dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly Files old/goauth2/.hg/dirstate and new/goauth2/.hg/dirstate differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/hgrc new/goauth2/.hg/hgrc --- old/goauth2/.hg/hgrc 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/hgrc 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,2 @@ +[paths] +default = https://code.google.com/p/goauth2/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/requires new/goauth2/.hg/requires --- old/goauth2/.hg/requires 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/requires 2011-10-06 16:06:23.000000000 +0200 @@ -0,0 +1,4 @@ +revlogv1 +store +fncache +dotencode Files old/goauth2/.hg/store/00changelog.i and new/goauth2/.hg/store/00changelog.i differ Files old/goauth2/.hg/store/00manifest.i and new/goauth2/.hg/store/00manifest.i differ Files old/goauth2/.hg/store/data/_c_o_n_t_r_i_b_u_t_o_r_s.i and new/goauth2/.hg/store/data/_c_o_n_t_r_i_b_u_t_o_r_s.i differ Files old/goauth2/.hg/store/data/lib/codereview/codereview.cfg.i and new/goauth2/.hg/store/data/lib/codereview/codereview.cfg.i differ Files old/goauth2/.hg/store/data/oauth/_makefile.i and new/goauth2/.hg/store/data/oauth/_makefile.i differ Files old/goauth2/.hg/store/data/oauth/example/_makefile.i and new/goauth2/.hg/store/data/oauth/example/_makefile.i differ Files old/goauth2/.hg/store/data/oauth/example/buzz.go.i and new/goauth2/.hg/store/data/oauth/example/buzz.go.i differ Files old/goauth2/.hg/store/data/oauth/oauth.go.i and new/goauth2/.hg/store/data/oauth/oauth.go.i differ Files old/goauth2/.hg/store/data/~2ehgtags.i and new/goauth2/.hg/store/data/~2ehgtags.i differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/store/fncache new/goauth2/.hg/store/fncache --- old/goauth2/.hg/store/fncache 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/store/fncache 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,7 @@ +data/oauth/example/Makefile.i +data/CONTRIBUTORS.i +data/oauth/example/buzz.go.i +data/.hgtags.i +data/lib/codereview/codereview.cfg.i +data/oauth/Makefile.i +data/oauth/oauth.go.i Files old/goauth2/.hg/store/undo and new/goauth2/.hg/store/undo differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/undo.branch new/goauth2/.hg/undo.branch --- old/goauth2/.hg/undo.branch 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/undo.branch 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1 @@ +default \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/undo.desc new/goauth2/.hg/undo.desc --- old/goauth2/.hg/undo.desc 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/.hg/undo.desc 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,3 @@ +0 +pull +https://code.google.com/p/goauth2/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hgtags new/goauth2/.hgtags --- old/goauth2/.hgtags 2011-06-17 10:28:31.000000000 +0200 +++ new/goauth2/.hgtags 2011-10-06 16:06:24.000000000 +0200 @@ -1 +1,3 @@ -682880c510ffb67b8c44ec95c57c535406db9689 release +379476c9e05c5275356e0a82ca079e61869e9192 release +dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly.2011-08-17 +dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/CONTRIBUTORS new/goauth2/CONTRIBUTORS --- old/goauth2/CONTRIBUTORS 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/CONTRIBUTORS 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,2 @@ +Andrew Gerrand <[email protected]> +Brad Fitzpatrick <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/lib/codereview/codereview.cfg new/goauth2/lib/codereview/codereview.cfg --- old/goauth2/lib/codereview/codereview.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/goauth2/lib/codereview/codereview.cfg 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1 @@ +defaultcc: [email protected] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/oauth/example/buzz.go new/goauth2/oauth/example/buzz.go --- old/goauth2/oauth/example/buzz.go 2011-06-17 10:28:31.000000000 +0200 +++ new/goauth2/oauth/example/buzz.go 2011-10-06 16:06:24.000000000 +0200 @@ -84,7 +84,7 @@ // you'd want to store the RefreshToken field as well. } // Make the request. - r, _, err := t.Client().Get(activities) + r, err := t.Client().Get(activities) if err != nil { log.Fatal(err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/oauth/oauth.go new/goauth2/oauth/oauth.go --- old/goauth2/oauth/oauth.go 2011-06-17 10:28:31.000000000 +0200 +++ new/goauth2/oauth/oauth.go 2011-10-06 16:06:24.000000000 +0200 @@ -44,6 +44,7 @@ "json" "os" "time" + "url" ) // Config is the configuration of an OAuth consumer. @@ -66,9 +67,21 @@ // Token contains an end-user's tokens. // This is the data you must store to persist authentication. type Token struct { - AccessToken string "access_token" - RefreshToken string "refresh_token" - TokenExpiry int64 "expires_in" + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + + // TokenExpiry is a unix timestamp in seconds that indicates when the + // token will expire. Zero means the token has no (known) expiry time. + // (Note: this is not the expires_in field as per the spec, + // even though we unmarshal the JSON expires_in value into this field.) + TokenExpiry int64 `json:"expires_in"` +} + +func (t *Token) Expired() bool { + if t.TokenExpiry == 0 { + return false + } + return t.TokenExpiry <= time.Seconds() } // Transport implements http.RoundTripper. When configured with a valid @@ -106,23 +119,23 @@ // AuthCodeURL returns a URL that the end-user should be redirected to, // so that they may obtain an authorization code. func (c *Config) AuthCodeURL(state string) string { - url, err := http.ParseURL(c.AuthURL) + url_, err := url.Parse(c.AuthURL) if err != nil { panic("AuthURL malformed: " + err.String()) } - q := http.Values{ + q := url.Values{ "response_type": {"code"}, "client_id": {c.ClientId}, "redirect_uri": {c.redirectURL()}, "scope": {c.Scope}, "state": {state}, }.Encode() - if url.RawQuery == "" { - url.RawQuery = q + if url_.RawQuery == "" { + url_.RawQuery = q } else { - url.RawQuery += "&" + q + url_.RawQuery += "&" + q } - return url.String() + return url_.String() } // Exchange takes a code and gets access Token from the remote server. @@ -131,7 +144,7 @@ return nil, os.NewError("no Config supplied") } tok = new(Token) - err = t.updateToken(tok, http.Values{ + err = t.updateToken(tok, url.Values{ "grant_type": {"authorization_code"}, "redirect_uri": {t.redirectURL()}, "scope": {t.Scope}, @@ -145,7 +158,13 @@ // RoundTrip executes a single HTTP transaction using the Transport's // Token as authorization headers. -func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err os.Error) { +// +// This method will attempt to renew the Token if it has expired and may return +// an error related to that Token renewal before attempting the client request. +// If the Token cannot be renewed a non-nil os.Error value will be returned. +// If the Token is invalid callers should expect HTTP-level errors, +// as indicated by the Response's StatusCode. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, os.Error) { if t.Config == nil { return nil, os.NewError("no Config supplied") } @@ -153,31 +172,23 @@ return nil, os.NewError("no Token supplied") } - // Make the HTTP request - req.Header.Set("Authorization", "OAuth "+t.AccessToken) - if resp, err = t.transport().RoundTrip(req); err != nil { - return - } - - // Refresh credentials if they're stale and try again - if resp.StatusCode == 401 { - if err = t.refresh(); err != nil { - return + // Refresh the Token if it has expired. + if t.Expired() { + err := t.updateToken(t.Token, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {t.RefreshToken}, + }) + if err != nil { + return nil, err } - resp, err = t.transport().RoundTrip(req) } - return -} - -func (t *Transport) refresh() os.Error { - return t.updateToken(t.Token, http.Values{ - "grant_type": {"refresh_token"}, - "refresh_token": {t.RefreshToken}, - }) + // Make the HTTP request. + req.Header.Set("Authorization", "OAuth "+t.AccessToken) + return t.transport().RoundTrip(req) } -func (t *Transport) updateToken(tok *Token, v http.Values) os.Error { +func (t *Transport) updateToken(tok *Token, v url.Values) os.Error { v.Set("client_id", t.ClientId) v.Set("client_secret", t.ClientSecret) r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/Makefile new/oauth/Makefile --- old/oauth/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/oauth/Makefile 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,11 @@ +# Copyright 2011 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +include $(GOROOT)/src/Make.inc + +TARG=goauth2.googlecode.com/hg/oauth +GOFILES=\ + oauth.go\ + +include $(GOROOT)/src/Make.pkg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/example/Makefile new/oauth/example/Makefile --- old/oauth/example/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/oauth/example/Makefile 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,11 @@ +# Copyright 2011 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +include $(GOROOT)/src/Make.inc + +TARG=buzz +GOFILES=\ + buzz.go\ + +include $(GOROOT)/src/Make.cmd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/example/buzz.go new/oauth/example/buzz.go --- old/oauth/example/buzz.go 1970-01-01 01:00:00.000000000 +0100 +++ new/oauth/example/buzz.go 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,95 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This program makes a call to the buzz API, authenticated with OAuth2. +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + + "goauth2.googlecode.com/hg/oauth" +) + +var ( + code = flag.String("code", "", "Authorization Code") + token = flag.String("token", "", "Access Token") + clientId = flag.String("id", "", "Client ID") + clientSecret = flag.String("secret", "", "Client Secret") +) + +const usageMsg = ` +You must specify at least -id and -secret. +To obtain these details, see the "OAuth 2 Credentials" section under +the "API Access" tab on this page: https://code.google.com/apis/console/ +` + +const activities = "https://www.googleapis.com/buzz/v1/activities/@me/@public?max-results=1&alt=json" + +func main() { + flag.Parse() + if *clientId == "" || *clientSecret == "" { + flag.Usage() + fmt.Fprint(os.Stderr, usageMsg) + return + } + + // Set up a configuration + config := &oauth.Config{ + ClientId: *clientId, + ClientSecret: *clientSecret, + Scope: "https://www.googleapis.com/auth/buzz", + AuthURL: "https://accounts.google.com/o/oauth2/auth", + TokenURL: "https://accounts.google.com/o/oauth2/token", + RedirectURL: "http://localhost/", + } + + // Step one, get an authorization code from the data provider. + // ("Please ask the user if I can access this resource.") + if *code == "" && *token == "" { + url := config.AuthCodeURL("") + fmt.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE") + fmt.Println(url) + return + } + + // Set up a Transport with our config. + t := &oauth.Transport{Config: config} + + // Step two, exchange the authorization code for an access token. + // ("Here's the code you gave the user, now give me a token!") + if *token == "" { + tok, err := t.Exchange(*code) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Now run again with -token=%s\n", tok.AccessToken) + return + // We needn't return here; we could just use the Transport + // to make authenticated requests straight away. + // The process has been split up to demonstrate how one might + // restore Credentials that have been previously stored. + } + + // Step three, make the actual request using the token to authenticate. + // ("Here's the token, let me in!") + // First, re-instate our Token (typically this would be stored on disk). + t.Token = &oauth.Token{ + AccessToken: *token, + // If you were storing this information somewhere, + // you'd want to store the RefreshToken field as well. + } + // Make the request. + r, err := t.Client().Get(activities) + if err != nil { + log.Fatal(err) + } + defer r.Body.Close() + // Write the response to standard output. + io.Copy(os.Stdout, r.Body) + fmt.Println() +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/oauth.go new/oauth/oauth.go --- old/oauth/oauth.go 1970-01-01 01:00:00.000000000 +0100 +++ new/oauth/oauth.go 2011-10-06 16:06:24.000000000 +0200 @@ -0,0 +1,209 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The oauth package provides support for making +// OAuth2-authenticated HTTP requests. +// +// Example usage: +// +// // Specify your configuration. (typically as a global variable) +// var config = &oauth.Config{ +// ClientId: YOUR_CLIENT_ID, +// ClientSecret: YOUR_CLIENT_SECRET, +// Scope: "https://www.googleapis.com/auth/buzz", +// AuthURL: "https://accounts.google.com/o/oauth2/auth", +// TokenURL: "https://accounts.google.com/o/oauth2/token", +// RedirectURL: "http://you.example.org/handler", +// } +// +// // A landing page redirects to the OAuth provider to get the auth code. +// func landing(w http.ResponseWriter, r *http.Request) { +// http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound) +// } +// +// // The user will be redirected back to this handler, that takes the +// // "code" query parameter and Exchanges it for an access token. +// func handler(w http.ResponseWriter, r *http.Request) { +// t := &oauth.Transport{Config: config} +// t.Exchange(r.FormValue("code")) +// // The Transport now has a valid Token. Create an *http.Client +// // with which we can make authenticated API requests. +// c := t.Client() +// c.Post(...) +// // ... +// // btw, r.FormValue("state") == "foo" +// } +// +package oauth + +// TODO(adg): A means of automatically saving credentials when updated. + +import ( + "http" + "json" + "os" + "time" + "url" +) + +// Config is the configuration of an OAuth consumer. +type Config struct { + ClientId string + ClientSecret string + Scope string + AuthURL string + TokenURL string + RedirectURL string // Defaults to out-of-band mode if empty. +} + +func (c *Config) redirectURL() string { + if c.RedirectURL != "" { + return c.RedirectURL + } + return "oob" +} + +// Token contains an end-user's tokens. +// This is the data you must store to persist authentication. +type Token struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + + // TokenExpiry is a unix timestamp in seconds that indicates when the + // token will expire. Zero means the token has no (known) expiry time. + // (Note: this is not the expires_in field as per the spec, + // even though we unmarshal the JSON expires_in value into this field.) + TokenExpiry int64 `json:"expires_in"` +} + +func (t *Token) Expired() bool { + if t.TokenExpiry == 0 { + return false + } + return t.TokenExpiry <= time.Seconds() +} + +// Transport implements http.RoundTripper. When configured with a valid +// Config and Token it can be used to make authenticated HTTP requests. +// +// t := &oauth.Transport{config} +// t.Exchange(code) +// // t now contains a valid Token +// r, _, err := t.Client().Get("http://example.org/url/requiring/auth") +// +// It will automatically refresh the Token if it can, +// updating the supplied Token in place. +type Transport struct { + *Config + *Token + + // Transport is the HTTP transport to use when making requests. + // It will default to http.DefaultTransport if nil. + // (It should never be an oauth.Transport.) + Transport http.RoundTripper +} + +// Client returns an *http.Client that makes OAuth-authenticated requests. +func (t *Transport) Client() *http.Client { + return &http.Client{Transport: t} +} + +func (t *Transport) transport() http.RoundTripper { + if t.Transport != nil { + return t.Transport + } + return http.DefaultTransport +} + +// AuthCodeURL returns a URL that the end-user should be redirected to, +// so that they may obtain an authorization code. +func (c *Config) AuthCodeURL(state string) string { + url_, err := url.Parse(c.AuthURL) + if err != nil { + panic("AuthURL malformed: " + err.String()) + } + q := url.Values{ + "response_type": {"code"}, + "client_id": {c.ClientId}, + "redirect_uri": {c.redirectURL()}, + "scope": {c.Scope}, + "state": {state}, + }.Encode() + if url_.RawQuery == "" { + url_.RawQuery = q + } else { + url_.RawQuery += "&" + q + } + return url_.String() +} + +// Exchange takes a code and gets access Token from the remote server. +func (t *Transport) Exchange(code string) (tok *Token, err os.Error) { + if t.Config == nil { + return nil, os.NewError("no Config supplied") + } + tok = new(Token) + err = t.updateToken(tok, url.Values{ + "grant_type": {"authorization_code"}, + "redirect_uri": {t.redirectURL()}, + "scope": {t.Scope}, + "code": {code}, + }) + if err == nil { + t.Token = tok + } + return +} + +// RoundTrip executes a single HTTP transaction using the Transport's +// Token as authorization headers. +// +// This method will attempt to renew the Token if it has expired and may return +// an error related to that Token renewal before attempting the client request. +// If the Token cannot be renewed a non-nil os.Error value will be returned. +// If the Token is invalid callers should expect HTTP-level errors, +// as indicated by the Response's StatusCode. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, os.Error) { + if t.Config == nil { + return nil, os.NewError("no Config supplied") + } + if t.Token == nil { + return nil, os.NewError("no Token supplied") + } + + // Refresh the Token if it has expired. + if t.Expired() { + err := t.updateToken(t.Token, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {t.RefreshToken}, + }) + if err != nil { + return nil, err + } + } + + // Make the HTTP request. + req.Header.Set("Authorization", "OAuth "+t.AccessToken) + return t.transport().RoundTrip(req) +} + +func (t *Transport) updateToken(tok *Token, v url.Values) os.Error { + v.Set("client_id", t.ClientId) + v.Set("client_secret", t.ClientSecret) + r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != 200 { + return os.NewError("invalid response: " + r.Status) + } + if err = json.NewDecoder(r.Body).Decode(tok); err != nil { + return err + } + if tok.TokenExpiry != 0 { + tok.TokenExpiry = time.Seconds() + tok.TokenExpiry + } + return nil +} ++++++ rpmlintrc ++++++ addFilter("binaryinfo-readelf-failed") # go binaries are suposedly ELF-compliant addFilter("statically-linked-binary") # go doesn't yet support dynamic linking continue with "q"... Remember to have fun... -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
