Craig
Craig

Reputation: 151

go properly handling slices and strings

I am using goRequest http://parnurzeal.github.io/gorequest/ to make some HTTP requests against a server process I need to talk to. The authentication process works like this;

send in a GET request with an authentication header set. No problem there, but I need to grab a header from the response and use a returned value to reauthenticate each following request.

The retuned HTTP header looks like this.

Response headers
map[Location:[900767244] Content-Type:[application/xml] Date:[Fri, 18     Sep 2015 18:19:41 GMT] Server:[Apache] X-Frame-Options:[SAMEORIGIN] Set-Cookie:[JSESSIONID=D5C976F5646365FF030DBAD770DA774C; Path=/; Secure; HttpOnly]]

I need to get that location value as it's my session token going forward. If I grap it like this:

session, ok := response.Header["Location"]
if !ok {
    fmt.Println("Did not receive a location header.")
}

fmt.Println("Session: ", session)

I can get it, but it's a slice and NOT a string. How can I get that value as a string so I can pop it back into my request headers going forward? As you can see in the following error:

./login.go:133: cannot use session (type []string) as type string in argument to logoutRequest.Delete

Thanks a lot! Craig

Upvotes: 0

Views: 198

Answers (2)

JimB
JimB

Reputation: 109339

If you want one value, use the Header's Get method

location := response.Header.Get("Location")

This also canonicalizes the header name for you, so that you still get a value even when using slightly different capitalization.

You only need to index an http.Header value directly when you need to get more than than the first possible value. If you want all values with a canonicalized header name, you can use textproto.CanonicalMIMEHeaderKey

vals := response.Header[textproto.CanonicalMIMEHeaderKey(header)]

Upvotes: 1

evanmcdonnal
evanmcdonnal

Reputation: 48076

The headers have location as an array, you just need to pass Location[0] to that method rather than simply Location because it is a slice. That being said, indexing into the array without checking the bounds is unsafe so you should probably do;

if len(Location) == 1 {
     logoutRequest(Location[0])
} else {
    // error state
}

One last thing to provide you guidance in the future. You can tell that the response headers object has a type more like this; map[string][]string (in reality that maybe []interface{} but I'm not certain from the output) by seeing that each item inside the outer brackets [] has it's values contained within another set of brackets, meaning it is an array that could contain 0 or more values.

Upvotes: 0

Related Questions