Nathaniel Waisbrot
Nathaniel Waisbrot

Reputation: 24523

404 when using the Go http client

I want to programmatically authenticate against the Docker hub service. When I run my code, I get a 404 error. But when I pass the same URL into Curl, I get a 200. I'm not sure how to debug the problem.

I use the following code:

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
    "time"
)

type Image struct {
    host, name, tag string
}

func authenticate(image Image) (token string) {
    var url = fmt.Sprintf("https://auth.docker.io/token?service=%s&scope=repository:%s:pull", image.host, image.name)
    var req, e1 = http.NewRequest("get", url, nil)
    if e1 != nil {
        log.Fatal(e1)
    }
    fmt.Println(req)
    var client = &http.Client{
        Timeout:       time.Second * 10,
        CheckRedirect: nil,
        Jar:           nil,
    }
    var res, e2 = client.Do(req)
    if e2 != nil {
        log.Fatal(e2)
    }
    var buf, e3 = ioutil.ReadAll(res.Body)
    if e3 != nil {
        log.Fatal(e3)
    }
    if res.StatusCode > 299 {
        log.Fatal(res.StatusCode, ": ", bytes.NewBuffer(buf).String())
    }
    type AuthResponse struct {
        token string
    }
    var authres AuthResponse
    fmt.Println(bytes.NewBuffer(buf).String())
    var e4 = json.Unmarshal(buf, &authres)
    if e4 != nil {
        log.Fatal(e4)
    }
    return authres.token
}

My print statements output:

&{registry.docker.io waisbrot/wait latest}

&{get https://auth.docker.io/token?service=registry.docker.io&scope=repository:waisbrot/wait:pull HTTP/1.1 1 1 map[] 0 [] false auth.docker.io map[] map[] map[] }

2016/09/11 11:19:42 404: 404 page not found

But the URL shown does not produce a 404 in Curl (or in a web browser), so I don't understand why Go is seeing an error.

Upvotes: 1

Views: 2295

Answers (1)

superfell
superfell

Reputation: 19040

"get" is not a valid HTTP Method, you want "GET" or http.MethodGet when you construct the request, e.g.

var req, e1 = http.NewRequest(http.MethodGet, url, nil)

with that change i get a successful response

&{GET https://auth.docker.io/token?service=registry.docker.io&scope=repository:waisbrot/wait:pull HTTP/1.1 1 1 map[] <nil> 0 [] false auth.docker.io map[] map[] <nil> map[]   <nil> <nil>}
{"token":"eyJhbGciOiJFUzI1N....

Upvotes: 6

Related Questions