How to get path and filename from postman request body using Go - forms

This question already asked but it is not solve my issue.
In my Go project am not able to print path and filename. It is showing some error like below:
2021/10/13 16:25:07 http: panic serving [::1]:60170: runtime error: invalid memory address or nil pointer dereference goroutine 6 [running]:
My Postman collection
my code
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func encodeFfmpeg(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "multipart/form-data")
_, header, _ := r.FormFile("video")
fmt.Println(header.Filename)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/encode", encodeFfmpeg).Methods("POST")
// config port
fmt.Printf("Starting server at 8080 \n")
http.ListenAndServe(":8080", router)
}
Am trying to print filename with path eg: /home/ramesh/videos/video.mp4

The sent request is missing the boundary parameter in the Content-Type header. This parameter is required for multipart/form-data to work properly.
In Postman remove the explicit Content-Type header setting and leave it to Postman to automatically set the header with the boundary parameter.
For more see: https://stackoverflow.com/a/16022213/965900 & https://stackoverflow.com/a/41435972/965900
Last but not least, do not ignore errors.

Related

401 Error when consuming an API from Go Code, while cURL Works well

I've written a simple go code that, sends a GET request to an API and in response I receive a 401 error. However when I use cURL, I receive the desired response. I also get expected response using API Tester. So, I believe, there has to be something wrong with my code and that, I'm unable to find out.
Below is my Go code, that, responds with 401 Error
func main() {
clusterId := os.Getenv("CLUSTER_ID")
apiUrl := "https://api.qubole.com/api/v1.3/clusters/"+clusterId+"/state"
auth_token := os.Getenv("X_AUTH_TOKEN")
fmt.Println("URL - ",apiUrl)
req, err := http.NewRequest("GET", apiUrl, nil)
if(err != nil){
fmt.Println("ERROR in getting rest response",err)
}
req.Header.Set("X-Auth-Token", auth_token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if(err != nil){
fmt.Println("Error: No response received", err)
}
defer res.Body.Close()
//print raw response body for debugging purposes
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
Extract of Response/Error I get, is as follows:
URL - https://api.qubole.com/api/v1.3/clusters/presto-bi/state
{"error":{"error_code":401,"error_message":"Invalid Token"}}
Now, Following is the cURL command that, returns me the desired response
curl -X GET -H "X-AUTH-TOKEN:$X_AUTH_TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" "https://us.qubole.com/api/v1.3/clusters/presto-bi/state"
below is the stdout I receive, which is as expected: {"state":"DOWN"}%
Need check api hostname at golang and curl again. Thanks!
The error is because, the documentation of API provider states the host WRONG (API Documentation) . But, since the portal login is us.qubole.com (PORTAL Login URL), cURL command was written considering that in mind.
I'm just guessing here without enough information. I'm assuming clusterId := os.Getenv("CLUSTER_ID") is presto-bi. If that is the case, then you are just missing "clusters" in your path.
apiUrl := "https://api.qubole.com/api/v1.3/clusters/"+clusterId+"/state"
Also, shouldn't you use us.qubole.com/api instead of api.qubole.com?

Golang HTTP POST succeeds, but it doesn't invoke a docker action

Problem: Although I can easily issue GET and POST commands from curl on my local docker socket, when I try to do the POST equivalent in Golang for a docker pull action, using net.Dial, I see no action taken on Docker's behalf.
Note that, meanwhile, the GET action works just fine using docker sockets via the golang client.
For example, when running the code at the bottom of this post, I see:
2018/01/05 14:16:33 Pulling http://localhost/v1.24/images/create?fromImage=fedora&tag=latest ......
2018/01/05 14:16:34 Succeeded pull for http://localhost/v1.24/images/create?fromImage=fedora&tag=latest &{200 OK 200 HTTP/1.1 1 1 map[Docker-Experimental:[true] Ostype:[linux] Server:[Docker/17.09.0-ce (linux)] Api-Version:[1.32] Content-Type:[application/json] Date:[Fri, 05 Jan 2018 19:16:34 GMT]] 0xc42010a100 -1 [chunked] false false map[] 0xc420102000 <nil>}
The code for attempting to do a pull via a POST action:
// pullImage is the equivalent of curl --unix-socket /var/run/docker.sock -X POST http://localhost/images/create?fromImage=alpine
func pullImage(img string, tag string) (err error) {
fd := func (proto, addr string) (conn net.Conn, err error) {
return net.Dial("unix", "/var/run/docker.sock")
}
tr := &http.Transport{
Dial: fd,
}
client := &http.Client{Transport: tr}
imageUrl := fmt.Sprintf("http://localhost/v1.24/images/create?fromImage=%s&tag=%s", img, tag)
log.Printf("Pulling %s ...... ", imageUrl)
resp, err := client.Post(imageUrl, "application/json", nil)
if resp.StatusCode == 200 && err == nil {
log.Printf("Succeeded pull for %s %v",imageUrl, resp)
} else {
log.Printf("FAILED pull for %s , ERROR = (( %s )) ",imageUrl , err)
}
return err
Question:
What does curl --unix-socket /var/run/docker.sock -X POST http://localhost/v1.24/images/create?fromImage=fedora do differently then the Golang code in the above snippet?
I figured this out. Actually, my prolem was that I wasn't completing the response body.
Adding
defer resp.Body.Close()
after the rest, err := client... clause was enough to finish triggering an entire pull. Not quite sure why closing the response body effects the ability of docker to start pulling the images down, but in any case, that was the case.

Getting cors errors in Scala Play Framework v2.6.x

I'm trying to get around a CORS error for a simple "hello world" style REST API in Scala/Play 2.6.x and I have tried everything that I can think of at this point. As far as I can tell there is not a good solution or example to be found on the internet, so even if this should be an easy fix then anyone that has a good solution would really help me out by posting it in full. I am simply trying to send a post request from localhost:3000 (a react application using axios) to localhost:9000 where my Scala/Play framework lives.
THE ERRORS
The error that I am getting on the client-side is the following:
XMLHttpRequest cannot load http://localhost:9000/saveTest.
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. The response had HTTP status code 403.
The error that I am getting on the server-side is
success] Compiled in 1s
--- (RELOAD) ---
[info] p.a.h.EnabledFilters - Enabled Filters
(see <https://www.playframework.com/documentation/latest/Filters>):
play.filters.csrf.CSRFFilter
play.filters.headers.SecurityHeadersFilter
play.filters.hosts.AllowedHostsFilter
play.filters.cors.CORSFilter
[info] play.api.Play - Application started (Dev)
[warn] p.f.c.CORSFilter - Invalid CORS
request;Origin=Some(http://localhost:3000);
Method=OPTIONS;Access-Control-Request-Headers=Some(content-type)
MY CODE
I have the following in my application.conf file
# https://www.playframework.com/documentation/latest/Configuration
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
pathPrefixes = ["/"]
allowedOrigins = ["http://localhost:3000", ...]
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE"]
allowedHttpHeaders = ["Accept"]
preflightMaxAge = 3 days
}
I've tried changing pathPrefixes to /saveTest (my endpoint), and tried changing allowedOrigins to simply 'https://localhost'. I've tried changing allowedHttpHeaders="Allow-access-control-allow-origin". I've tried setting allowedOrigins, allowedHttpMethods, and allowedHttpHeaders all to null which, according to the documentation (https://www.playframework.com/documentation/2.6.x/resources/confs/filters-helpers/reference.conf) should allow everything (as should pathPrefixes=["/"]
My build.sbt is the following, so it should be adding the filter to the libraryDependencies:
name := """scalaREST"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.2"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.0" % Test
libraryDependencies += filters
According to documentation available here: https://www.playframework.com/documentation/2.6.x/Filters#default-filters you can set the default filters like this:
import javax.inject.Inject
import play.filters.cors.CORSFilter
import play.api.http.{ DefaultHttpFilters, EnabledFilters }
class Filters #Inject()(enabledFilters: EnabledFilters, corsFilter: CORSFilter)
extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
I'm not sure exactly where that should go in my project - it doesn't say, but from other stackoverflow answers I kind of assume it should go in the root of my directory (that is /app). So that's where I put it.
Finally, there was one exotic stackoverflow response that said to put this class in my controllers and add it as a function to my OK responses
implicit class RichResult (result: Result) {
def enableCors = result.withHeaders(
"Access-Control-Allow-Origin" -> "*"
, "Access-Control-Allow-Methods" ->
"OPTIONS, GET, POST, PUT, DELETE, HEAD"
// OPTIONS for pre-flight
, "Access-Control-Allow-Headers" ->
"Accept, Content-Type, Origin, X-Json,
X-Prototype-Version, X-Requested-With"
//, "X-My-NonStd-Option"
, "Access-Control-Allow-Credentials" -> "true"
)
}
Needless to say, this did not work.
WRAP UP
Here is the backend for my current scala project.
https://github.com/patientplatypus/scalaproject1/tree/master/scalarest
Please, if you can, show a full working example of a CORS implementation - I cannot get anything I can find online to work. I will probably be submitting this as a documentation request to the Play Framework organization - this should not be nearly this difficult. Thank you.
Your preflight request fails because you have a Content-Type header set
Add content-type to allowedHttpHeaders in your application.conf like so
#application.conf
play.filters.cors {
#other cors configuration
allowedHttpHeaders = ["Accept", "Content-Type"]
}
I had this problem too and I added these code in application.conf
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
allowedHttpMethods = ["GET", "HEAD", "POST"]
allowedHttpHeaders = ["Accept", "Content-Type"]"
}
and now everything is OK!
for more info
For playframework version 2.8.x , we can wrap the Response in a function as below -
def addCorsHeader (response : Result) : Result = {
response.withHeaders(
("Access-Control-Allow-Origin", "*"),
("Access-Control-Allow-Methods" , "GET,POST,OPTIONS,DELETE,PUT")
)
}
Now in the controller, wrap the Results using the above function.
val result = myService.swipeOut(inputParsed)
addCorsHeader(Ok(s"$result row successfully updated. Trip complete"))
}
else {
addCorsHeader(InternalServerError("POST body is mandatory"))
}

Not able to send mail in Golang

I am trying to send mail on my local system using gmail package of golang. For which I tried the following:
package main
import(
"fmt"
"github.com/SlyMarbo/gmail"
)
func main() {
email := gmail.Compose("Email subject", "Email body")
email.From = "account#gmail.com"
email.Password = "password"
// Defaults to "text/plain; charset=utf-8" if unset.
email.ContentType = "text/html; charset=utf-8"
// Normally you'll only need one of these, but I thought I'd show both.
email.AddRecipient("recepient#domain.com")
err := email.Send()
if err != nil {
fmt.Println(err)
// handle error.
}
}
I am neither getting any error nor mail. Not sure if it is not sent due to local server. Can anyone please guide me what am I missing? I took reference from this page.

Go HTTP Request with Basic Auth returning a 401 instead of a 301 redirect

Using Go 1.5.1.
When I try to make a request to a site that automatically redirects to HTTPS using Basic Auth I would expect to get a 301 Redirect response, instead I get a 401.
package main
import "net/http"
import "log"
func main() {
url := "http://aerolith.org/files"
username := "cesar"
password := "password"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println("error", err)
}
if username != "" || password != "" {
req.SetBasicAuth(username, password)
log.Println("[DEBUG] Set basic auth to", username, password)
}
cli := &http.Client{
}
resp, err := cli.Do(req)
if err != nil {
log.Println("Do error", err)
}
log.Println("[DEBUG] resp.Header", resp.Header)
log.Println("[DEBUG] req.Header", req.Header)
log.Println("[DEBUG] code", resp.StatusCode)
}
Note that curl returns a 301:
curl -vvv http://aerolith.org/files --user cesar:password
Any idea what could be going wrong?
A request to http://aerolith.org/files redirects to https://aerolith.org/files (note change from http to https). A request to https://aerolith.org/files redirects to https://aerolith.org/files/ (note addition of trailing /).
Curl does not follow redirects. Curl prints the 301 status for the redirect from http://aerolith.org/files to https://aerolith.org/files/.
The Go client follows the two redirects to https://aerolith.org/files/. The request to https://aerolith.org/files/ returns with status 401 because the Go client does not propagate the authorization header through the redirects.
Requests to https://aerolith.org/files/ from the Go client and Curl return status 200.
If you want to follow the redirects and auth successfully, set auth header in a CheckRedirect function:
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
req.SetBasicAuth(username, password)
return nil
}}
resp, err := cli.Do(req)
If you want to match what Curl does, use a transport directly. The transport does not follow redirects.
resp, err := http.DefaultTransport.RoundTrip(req)
The application can also use the client CheckRedirect function and a distinguished error to prevent redirects as shown in an answer to How Can I Make the Go HTTP Client NOT Follow Redirects Automatically?. This technique seems to be somewhat popular, but is more complicated than using the transport directly.
redirectAttemptedError := errors.New("redirect")
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return redirectAttemptedError
}}
resp, err := cli.Do(req)
if urlError, ok := err.(*url.Error); ok && urlError.Err == redirectAttemptedError {
// ignore error from check redirect
err = nil
}
if err != nil {
log.Println("Do error", err)
}