package jkl import ( "bytes" "encoding/json" "errors" "fmt" "io" "io/ioutil" "net/http" "net/http/cookiejar" "net/url" "os" "strings" "time" ) var j, _ = cookiejar.New(nil) var httpClient *JiraClient type JiraClient struct { *http.Client jiraRoot string } func init() { x := false Verbose = &x } func NewJiraClient(jiraRoot string) *JiraClient { jc := &JiraClient{ &http.Client{ Jar: j, }, jiraRoot, } if jc.jiraRoot == "" { jc.jiraRoot = os.Getenv("JIRA_ROOT") } if cookiefile := os.Getenv("JIRA_COOKIEFILE"); cookiefile != "" { makeNewFile := false f, err := os.Open(cookiefile) server := jc.jiraRoot + "rest/gadget/1.0/login" u, _ := url.Parse(server) if err != nil { makeNewFile = true } else { if stat, err := f.Stat(); err == nil { if time.Now().Sub(stat.ModTime()).Minutes() > 60 { makeNewFile = true } else { var cookies []*http.Cookie dec := json.NewDecoder(f) dec.Decode(&cookies) u, _ = url.Parse(jc.jiraRoot) jc.Jar.SetCookies(u, cookies) } } f.Close() } if makeNewFile { f, err = os.Create(cookiefile) if err != nil { panic(err) } http.DefaultClient.Jar = j form := url.Values{} form.Add("os_username", os.Getenv("JIRA_USER")) form.Add("os_password", os.Getenv("JIRA_PASSWORD")) req, _ := http.NewRequest("POST", server, strings.NewReader(form.Encode())) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil || resp.StatusCode >= 400 { fmt.Println(resp.Header) fmt.Println(resp.Status) fmt.Println(err) } b := bytes.NewBuffer(nil) enc := json.NewEncoder(b) enc.Encode(j.Cookies(u)) io.Copy(f, b) f.Close() } } if *Verbose { fmt.Println("Jira root:", jc.jiraRoot) } return jc } func (j *JiraClient) DoLess(req *http.Request) (*http.Response, error) { req.Header.Add("Content-Type", "application/json") req.Header.Add("Accept", "application/json, text/plain, text/html") return j.DoEvenLess(req) } func (j *JiraClient) DoEvenLess(req *http.Request) (*http.Response, error) { var err error if os.Getenv("JIRA_COOKIEFILE") == "" { req.SetBasicAuth(os.Getenv("JIRA_USER"), os.Getenv("JIRA_PASSWORD")) } resp, err := j.Client.Do(req) if err != nil { return nil, err } if resp.StatusCode >= 400 { fmt.Println("Status code:", resp.StatusCode) if *Verbose { fmt.Println("Headers:") fmt.Println(resp.Header) } fmt.Println("Response:") b, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } fmt.Println(string(b)) return nil, errors.New("Some http error happened.") } return resp, nil } func (j *JiraClient) Do(req *http.Request) (*http.Response, error) { var err error req.URL, err = url.Parse(j.jiraRoot + "rest/" + req.URL.RequestURI()) if err != nil { return nil, err } return j.DoLess(req) } func (j *JiraClient) Put(path string, payload io.Reader) (*http.Response, error) { req, err := http.NewRequest("PUT", path, payload) if err != nil { return nil, err } return j.Do(req) } func (j *JiraClient) Post(path string, payload io.Reader) (*http.Response, error) { req, err := http.NewRequest("POST", path, payload) if err != nil { return nil, err } return j.Do(req) } func (j *JiraClient) Get(path string) (*http.Response, error) { req, err := http.NewRequest("GET", path, nil) if err != nil { return nil, err } return j.Do(req) }