package main import ( "encoding/json" "io" "log" "net/http" "net/http/httputil" "net/url" "os" ) type TokenResponse struct { Error string `json:"error"` AccessToken string `json:"access_token"` } func authorizeRoute(w http.ResponseWriter, r *http.Request) { code := r.URL.Query().Get("code") if len(code) == 0 { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"error":"missing code"}`)) return } values := make(url.Values) values["grant_type"] = []string{"authorization_code"} values["client_id"] = []string{os.Getenv("APP_ID")} values["client_secret"] = []string{os.Getenv("SECRET_KEY")} values["code"] = []string{code} values["redirect_uri"] = []string{os.Getenv("REDIRECT_URI")} resp, err := http.PostForm("https://api.mercadolibre.com/oauth/token", values) if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(`{"error":"ML API error"}`)) return } tokenResp := TokenResponse{} rawJson, err := io.ReadAll(resp.Body) if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(`{"error":"ML API error"}`)) return } err = resp.Body.Close() if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(`{"error":"ML API error"}`)) return } err = json.Unmarshal(rawJson, &tokenResp) if err != nil { log.Println(err) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(`{"error":"ML API error"}`)) return } // if len(tokenResp.Error) != 0 { // log.Println(string(rawJson)) // w.WriteHeader(http.StatusInternalServerError) // w.Write([]byte(`{"error":"ML API error"}`)) // return // } w.Write([]byte(rawJson)) } func proxyRoute(res http.ResponseWriter, req *http.Request) { // parse the url url, _ := url.Parse("https://api.mercadolibre.com/") // create the reverse proxy proxy := httputil.NewSingleHostReverseProxy(url) // Update the headers to allow for SSL redirection req.URL.Host = url.Host req.URL.Scheme = url.Scheme req.Header.Set("X-Forwarded-Host", "") req.Header.Set("X-Forwarded-For", "") req.Header.Set("Origin", "") req.Header.Set("Referer", "") req.Host = url.Host // Note that ServeHttp is non blocking and uses a go routine under the hood proxy.ServeHTTP(res, req) } func main() { fs := http.FileServer(http.Dir("static")) http.Handle("/", fs) http.HandleFunc("/authorize", authorizeRoute) http.HandleFunc("/pictures/items/upload", proxyRoute) http.HandleFunc("/items", proxyRoute) log.Fatalln(http.ListenAndServe(":6969", nil)) }