//DeleteObject calls the OpenStack delete object API using //previously obtained token. // //Note from API doc: "A DELETE to a versioned object removes the current version //of the object and replaces it with the next-most current version, moving it //from the non-current container to the current." .. "If you want to completely //remove an object and you have five total versions of it, you must DELETE it //five times." func DeleteObject(url, token string) (err error) { resp, err := misc.CallAPI("DELETE", url, zeroByte, "X-Auth-Token", token) if err != nil { return err } return misc.CheckHTTPResponseStatusCode(resp) }
//ListObjects calls the OpenStack list object API using previously //obtained token. "Limit", "marker", "prefix", "path", "delim" corresponds //to the API's "limit", "marker", "prefix", "path", and "delimiter". func ListObjects(limit int64, marker, prefix, path, delim, conURL, token string) ([]byte, error) { var query = "?format=json" if limit > 0 { query += "&limit=" + strconv.FormatInt(limit, 10) } if marker != "" { query += "&marker=" + url.QueryEscape(marker) } if prefix != "" { query += "&prefix=" + url.QueryEscape(prefix) } if path != "" { query += "&path=" + url.QueryEscape(path) } if delim != "" { query += "&delimiter=" + url.QueryEscape(delim) } resp, err := misc.CallAPI("GET", conURL+query, zeroByte, "X-Auth-Token", token) if err != nil { return nil, err } if err = misc.CheckHTTPResponseStatusCode(resp); err != nil { return nil, err } body, err := ioutil.ReadAll(resp.Body) defer resp.Body.Close() if err != nil { return []byte{}, err } return body, nil }
//GetObjectMeta calls the OpenStack retrieve object metadata API using //previously obtained token. func GetObjectMeta(url, token string) (http.Header, error) { resp, err := misc.CallAPI("HEAD", url, zeroByte, "X-Auth-Token", token) if err != nil { return nil, err } return resp.Header, misc.CheckHTTPResponseStatusCode(resp) }
func TestCallAPIGetContent(t *testing.T) { tokn := "eaaafd18-0fed-4b3a-81b4-663c99ec1cbb" fContent, err := ioutil.ReadFile("./util.go") if err != nil { t.Error(err) } var apiServer = httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { t.Error(err) } if r.Header.Get("X-Auth-Token") != tokn { t.Error(errors.New("Token failed")) } w.Header().Set("Content-Length", r.Header.Get("Content-Length")) w.Write(body) })) var resp *http.Response if resp, err = misc.CallAPI("GET", apiServer.URL, &fContent, "X-Auth-Token", tokn, "Etag", "md5hash-blahblah"); err != nil { t.Error(err) } if strconv.Itoa(len(fContent)) != resp.Header.Get("Content-Length") { t.Error(errors.New("Failed: Content-Length comparison")) } body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Error(err) } if !bytes.Equal(fContent, body) { t.Error(errors.New("Failed: Content body comparison")) } }
//SetObjectMeta calls the OpenStack API to create/update meta data for //object using previously obtained token. func SetObjectMeta(url string, token string, s ...string) (err error) { s = append(s, "X-Auth-Token") s = append(s, token) resp, err := misc.CallAPI("POST", url, zeroByte, s...) if err != nil { return err } return misc.CheckHTTPResponseStatusCode(resp) }
//CopyObject calls the OpenStack copy object API using previously obtained //token. Note from API doc: "The destination container must exist before //attempting the copy." func CopyObject(srcURL, destURL, token string) (err error) { resp, err := misc.CallAPI("COPY", srcURL, zeroByte, "X-Auth-Token", token, "Destination", destURL) if err != nil { return err } return misc.CheckHTTPResponseStatusCode(resp) }
//PutObject calls the OpenStack create object API using previously //obtained token. //url can be regular storage or CDN-enabled storage URL. func PutObject(fContent *[]byte, url, token string, s ...string) (err error) { s = append(s, "X-Auth-Token") s = append(s, token) resp, err := misc.CallAPI("PUT", url, fContent, s...) if err != nil { return err } return misc.CheckHTTPResponseStatusCode(resp) }
func TestCallAPI(t *testing.T) { tokn := "eaaafd18-0fed-4b3a-81b4-663c99ec1cbb" var apiServer = httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("X-Auth-Token") != tokn { t.Error(errors.New("Token failed")) } w.WriteHeader(200) //ok })) zeroByte := &([]byte{}) if _, err := misc.CallAPI("HEAD", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { t.Error(err) } if _, err := misc.CallAPI("DELETE", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { t.Error(err) } if _, err := misc.CallAPI("POST", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { t.Error(err) } }
//GetObject calls the OpenStack retrieve object API using previously //obtained token. It returns http.Header, object / file content downloaded //from the server, and err. // //Since this implementation of GetObject retrieves header info, it //effectively executes GetObjectMeta also in addition to getting the //object content. func GetObject(url, token string) (http.Header, []byte, error) { resp, err := misc.CallAPI("GET", url, zeroByte, "X-Auth-Token", token) if err != nil { return nil, nil, err } if err = misc.CheckHTTPResponseStatusCode(resp); err != nil { return nil, nil, err } var body []byte if body, err = ioutil.ReadAll(resp.Body); err != nil { return nil, nil, err } resp.Body.Close() return resp.Header, body, nil }