Skip to content

Instantly share code, notes, and snippets.

@RadioactiveMouse
Last active December 14, 2015 20:19
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 RadioactiveMouse/5142920 to your computer and use it in GitHub Desktop.
Save RadioactiveMouse/5142920 to your computer and use it in GitHub Desktop.
Go gist to help explain issues with content parsing errors. NB: headers are going to be modified differently and handed into query function.
curl -v -d '{"":"testvalue"}' -H "Content-Type: application/json" http://127.0.0.1:8098/buckets/test/keys?returnbody=true
* About to connect() to 127.0.0.1 port 8098 (#0)
* Trying 127.0.0.1... connected
> POST /buckets/test/keys?returnbody=true HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: 127.0.0.1:8098
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
* upload completely sent off: 16out of 16 bytes
< HTTP/1.1 201 Created
< X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgYaWnBmMCUy5rEyxNXuOsWXBQA=
< Vary: Accept-Encoding
< Server: MochiWeb/1.1 WebMachine/1.9.2 (someone had painted it blue)
< Location: /riak/test/5R214ghD18J7sTV1lbTxEzwKkpZ
< Link: </buckets/test>; rel="up"
< Last-Modified: Sun, 17 Mar 2013 17:46:06 GMT
< ETag: "5yUEPLc3hVNvftnyO7qUPB"
< Date: Sun, 17 Mar 2013 17:46:06 GMT
< Content-Type: application/json
< Content-Length: 16
<
* Connection #0 to host 127.0.0.1 left intact
* Closing connection #0
{"":"testvalue"}
type Client struct {
Address string
Port int
Type string
Log bool
}
func (self *Client) Store(bucket string, returnBody bool, data *Data) (*Data, error) {
// check if the key exists for conditional put/post
path := ""
returnData := Data{}
resp := http.Response{}
// check if the key exists
if data.value == "" {
return &returnData, errors.New("RGO: no value defined for the key")
}
if data.key != "" {
// put
path = fmt.Sprintf("/buckets/%s/keys/%s",bucket,data.key)
values := url.Values{data.key:{data.value}}
err := self.query("PUT",path,values,&resp)
if err != nil {
return &returnData, err
}
} else {
//post
path = fmt.Sprintf("/buckets/%s/keys",bucket)
values := url.Values{"":{data.value}}
err := self.query("POST",path,values,&resp)
if err != nil {
return &returnData, err
}
}
if self.Log {
fmt.Println("Returned r : ", resp.Body)
}
// catch errors 400 404
if resp.StatusCode > 300 {
return &returnData, errors.New(fmt.Sprintf("Error during store request code : %d",resp.StatusCode))
}
// content-length should always be > 0 as we specify returnbody=true
if resp.ContentLength <= 0 {
return &returnData, errors.New(fmt.Sprintf("Error during store operation, content-length : %d",resp.ContentLength))
}
body, err := ioutil.ReadAll(resp.Body)
if self.Log {
fmt.Println("Body : ", body)
}
defer resp.Body.Close()
if err != nil {
return &returnData, err
}
error := json.Unmarshal(body, &returnData)
return &returnData, error
}
func (self *Client) query(method string, path string, values url.Values, r *http.Response) (error) {
// construct the base URL
riakurl := fmt.Sprintf("%s:%d",self.Address,self.Port)
endpoint, err := url.Parse(riakurl)
if err != nil {
return err
}
endpoint.Path = path
if method == "GET" {
endpoint.RawQuery = values.Encode()
}
var body io.Reader
if method != "GET" && values != nil {
returnBod := url.Values{"returnbody" : {"true"}}
endpoint.RawQuery = returnBod.Encode()
body = strings.NewReader(values.Encode())
}
if self.Log {
fmt.Println("RGO :", method, endpoint.String())
fmt.Println(values.Encode())
}
request, err := http.NewRequest(method, endpoint.String(), body)
if err != nil {
return err
}
// set the correct headers for the data TODO: needs some sort of ability to change the content-type
request.Header.Set("Content-Type","application/json")
response, err := http.DefaultClient.Do(request)
*r = *response
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment