[net/http] How to send a Header value of string not []string

The Header struct in net/http lib has a format of map[string][]string, is there any possible way to use such lib to set a header of map[string]string? The host fails to parse the Authorization header value, because it is map not a string returning 401

http.Header is just the in-memory type defined in Go. When the HTTP request is actually sent, the headers are all just part of the request message and they look the same as any other HTTP request header:

Content-Type: application/json
Accept: application/json
Authorization: basic abc123...

So the fact that they were a []string vs. string isn’t known by the server.

The HTTP standard allows multiple values to be associated with a single field by joining them with commas or repeating the field name. If you put values into a slice, one of those two things will happen when the request is generated.

Considering you mentioned an issue parsing the Authorization header value, I’m guessing (if I’m wrong, can you please include the code you’re using, the error message on the server, anything so that we can help you troubleshoot) the issue is that you’re setting the Authorization scheme and value as separate values in the slice (e.g. req.Headers["Authorization"] = []string{"basic", "abc123..."} which is causing the Authorization header field to appear as Authorization: basic, abc123... or

Authorization: basic
Authorization: abc123...

Which is probably not correctly parseable by the server. You should instead Set the Authorization value as a single string:

req.Header.Set("Authorization", "basic abc123...")

If this doesn’t answer your question, please provide more information like your code, the error from the server, etc. to help us help you :slight_smile:

1 Like

Thank you Sean for getting back to me. The token is valid and I tested it with requests lib from py. Looks like it also fails with curl, so there should be no problem using net/http

Request

header := http.Header{}
header.Add("Content-Type", "application/json")
header.Set("Authorization", "Bearer "+t)
resp, err := http.Client.Do(&http.Request{
		Method: "GET",
		URL:    url,
		Header: header,
	})

Code Response

 "{\n  \"error\": {\n    \"code\": 401,\n   
 \"message\": \"Request had invalid authentication credentials. Expected OAuth 2 access token, 
login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\n 
\"status\": \"UNAUTHENTICATED\"\n  }\n}\n"

net/http works fine, I did a curl -v and it seems that I am getting this below error.

Curl Response

< www-authenticate: Bearer realm="https://accounts.google.com/", error="insufficient_scope", scope="SOME_SCOPE">
{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED"
}

Somehow I bypassed the 401 in curl but not in my code. Once I fix the curl response, I should be good.

The issue was a bug I had in the code, idtoken.NewClient is sued where this library fetches token once and automatically sets the header. Using same client to make other calls fail authorization since the token is wrong hence the server returns 401.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.