I'm trying to POST a comment to imgur through the Imgur API. But I can't make the payload right. I have looked through Imgur's page about this and they showed that it should be coded like I have in strings.NewReader. The imageID is nP0uKKO
func HandleComment(w http.ResponseWriter, r *http.Request){
parts := strings.Split(r.URL.Path, "/")
switch r.Method {
case "POST":
// URL for POSTing comment
url := "https://api.imgur.com/3/comment"
// Authorization key
token := "Bearer " + os.Getenv("TOKEN")
// Payload
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
// Get body and http status code
body, status := DoStuff(parts[2], url, payload, token)
// If status is not OK
if status != 200 {
http.Error(w, "Could not post comment", status)
} else {
fmt.Fprintln(w, string(body))
}
DoStuff() does this
func DoStuff(method string, url string, body io.Reader, key string) ([]byte, int) {
// New request
req, err := http.NewRequest(method, url, body)
if err != nil {
fmt.Println(err)
}
// Add header with 'key' authorization
req.Header.Add("authorization", key)
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
imgBody, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return imgBody, res.StatusCode
}
I just get this error
{
data: {
error: "The parameter, image_id, is required.",
request: "/3/comment",
method: "POST"
},
success: false,
status: 400
}
The thing missing is the Content-Type header. You can modify your code like this:
In your handler HandleComment you can define the headers you want to pass to the request
case "POST":
// URL for POSTing comment
url := "https://api.imgur.com/3/comment"
// Authorization key
token := "Bearer " + os.Getenv("TOKEN")
// Payload
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
// Headers
headers := map[string]string{
"Authorization": token,
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
}
// Get body and http status code
body, status := DoStuff(parts[2], url, payload, headers)
// If status is not OK
if status != 200 {
http.Error(w, "Could not post comment", status)
} else {
fmt.Fprintln(w, string(body))
}
Update DoStuff to read and pass the headers
func DoStuff(method string, url string, body io.Reader, headers map[string]string) ([]byte, int) {
// New request
req, err := http.NewRequest(method, url, body)
if err != nil {
fmt.Println(err)
}
// Add headers
for k, v := range headers {
req.Header.Add(k, v)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
imgBody, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return imgBody, res.StatusCode
}
I would suggest instead of using multipart/form-data; you might utilize the json content type. It is easier to manage and more readable
// Payload
payload := strings.NewReader("{\"image_id\": \"nP0uKKO\", \"comment\": \"I'm a giraffe!\"}")
// Headers
headers := map[string]string{
"Authorization": token,
"Content-Type": "application/json",
}
Related
I am trying to get the list of hosts from ansible tower using the API defined in here
I am using the ansible tower URL -> https://zzzztower.zzzz.com/api/v2/hosts/
and the bearer token -> aaaaaaaaaaaaaaaaaaaaaaaaaaa
to hit the API.
When I use postman to hit the API I am getting a proper response
but when I use golang code, I am getting error
Get "https://ansibletower.micron.com/api/v2/hosts/": x509: certificate relies on legacy Common Name field, use SANs instead
Here is my code:
package globals
import (
"fmt"
"io/ioutil"
"net/http"
)
// var AUTH_TOKEN string = os.Getenv("AUTH_TOKEN")
func GetAnsibleHosts() (string, error) {
url := "https://zzzztower.zzzz.com/api/v2/hosts/"
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
return "", fmt.Errorf("Error creating request: %v", err)
}
bearerToken := "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
// Add the Bearer Auth token to the request
req.Header.Add("Authorization", "Bearer "+bearerToken)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return "", err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return "", err
}
// fmt.Println(string(body))
return string(body), err
}
I tried finding the error on google but i didn't find much help.
Few articles mentioned to use GODEBUG=x509ignoreCN=0 but it didn't worked.
I would really appreciate you help.
I'm trying to obtain the current market value of a coin from the bingx exchange, and I'm doing an http get request on what I believe is the correct api endpoint. after acquiring an access token it's still not allowing me to access the resource, is my logic flawed or am I just querying the wrong endpoint?
// get the current market value of a coin on Bingx - not working
func getBingxPriceWithAuth(currency string) {
// set API endpoint
url := "https://api.bingx.com/api/v3/ticker/price?symbol=" + currency
// create HTTP client
client := &http.Client{
Timeout: time.Second * 10,
}
// create HTTP GET request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
}
// add the API credentials
req.Header.Add("Bingx-API-Key", MYKEY)
req.Header.Add("Bingx-API-Secret", MYSECRET)
// HTTP GET request
resp, err := client.Do(req)
if err != nil {
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
}
fmt.Println()
// parse the JSON
var data map[string]interface{}
err = json.Unmarshal(body, &data)
if err != nil {
}
fmt.Println(data)t
//return data["price"].(float64)
}
I am able to fetch the secrets from AWS secrets manager and using this secrets (ex : {"x-api-key":"123456789qwertyuiop"}) as an header, I want to call an API, I am new to golang and can anyone help me on this?
My code example
func fetch_api() {
?? How to call an POST API with below header??
// I get header secrets from below func getsecrets in above mentioned example
secret, _ := getsecrets("MyAPISecrets")
fmt.Println(secret)
}
func getsecrets(s string) (string, error) {
// Create a session
mySession, err := session.NewSession(&aws.Config{
Region: aws.String(os.Getenv("REGION"))},
)
if err != nil {
log.Fatal(err)
}
svc := secretsmanager.New(mySession)
result, err := svc.GetSecretValue(&secretsmanager.GetSecretValueInput{SecretId: &s})
if err != nil {
log.Fatal(err.Error())
}
return *result.SecretString, nil
}
func main() {
lambda.Start(fetch_api)
}
You can modify this code, it is just an example
func fetch_api() {
// I get header secrets from below func getsecrets in above mentioned example
secret, _ := getsecrets("MyAPISecrets")
fmt.Println(secret)
client := &http.Client{}
// create POST request
req, err := http.NewRequest("POST", url, body)))
if err != nil {
panic(err)
}
// set content-type header
req.Header.Set("Content-Type", "application/json")
// set x-api-key header
req.Header.Set("x-api-key", secret)
// send request
resp, err := client.Do(req)
if err != nil {
panic(err)
}
// print response
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}
I am developing an application which consumes a backend made in golang through api rest, what I am trying to do is a login, but I am running into a problem and that is that when I want to make the request with vue it returns a error which says Unexpected end of JSON input, but I make the request for postman and it does not generate any error.
This is my file vue:
<script>
import { ref } from '#vue/reactivity';
export default {
setup() {
const email = ref('');
const password = ref('');
const submitForm = () => {
fetch(`http://localhost:8000/api/v1/users/login`, {
method: 'POST',
body: JSON.stringify({
email: email.value,
password: password.value,
}),
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.catch((error) => console.error(`Error: ${error}`))
.catch((response) => console.log(`Success: ${response}`));
};
return {
email,
password,
submitForm,
};
},
};
</script>
and just in case this is my backend made in golang:
func Login(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var u model.User
if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
http.Error(w, "format incorrect of json", http.StatusBadRequest)
return
}
user, err := function.VerificationLogin(u.Email, u.Password)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
token, err := jwt.CreateToken(user)
if err != nil {
http.Error(w, "ups "+err.Error(), http.StatusBadRequest)
return
}
http.SetCookie(w, &http.Cookie{
Name: "token",
Value: token,
Expires: time.Now().Add(1 * time.Hour),
})
w.WriteHeader(http.StatusOK)
}
I need to make a webrequest with HTTPS URL. But it always return (403) error. is there any other way for HTTPS URLs?
You can try this:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
dataMap := map[string]interface{}{} // own map
data, err := json.Marshal(dataMap)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", "https://newsapi.org/v2/everything", bytes.NewBuffer(data)) // replace url
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := (&http.Client{}).Do(req) // send request
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) // read body
if err != nil {
panic(err)
}
var jsonResp map[string]interface{} // response map
err = json.Unmarshal(body, &jsonResp)
if err != nil {
panic(err)
}
fmt.Printf("Response: %s\nStatus: %s\n", jsonResp, resp.Status)
}
The output was:
Response: map[status:error code:apiKeyMissing message:Your API key is missing. Append this to the URL with the apiKey param, or use the x-api-key HTTPheader.]
Status: 401 Unauthorized
There still is an error, but that is caused by the server, because there is no API key.