| 154 | var appIDRE = regexp.MustCompile(`app_id["']?\s*:\s*['"]?([-a-z0-9.:~]+)`) |
| 155 | |
| 156 | func getAppID(client *http.Client, url string) (string, error) { |
| 157 | // Generate a pseudo-random token for handshaking. |
| 158 | token := strconv.Itoa(rand.New(rand.NewSource(time.Now().UnixNano())).Int()) |
| 159 | |
| 160 | resp, err := client.Get(fmt.Sprintf("%s?rtok=%s", url, token)) |
| 161 | if err != nil { |
| 162 | return "", err |
| 163 | } |
| 164 | defer resp.Body.Close() |
| 165 | |
| 166 | body, err := ioutil.ReadAll(resp.Body) |
| 167 | if resp.StatusCode != http.StatusOK { |
| 168 | return "", fmt.Errorf("bad response %d; body: %q", resp.StatusCode, body) |
| 169 | } |
| 170 | if err != nil { |
| 171 | return "", fmt.Errorf("failed reading response: %v", err) |
| 172 | } |
| 173 | |
| 174 | // Check the token is present in response. |
| 175 | if !bytes.Contains(body, []byte(token)) { |
| 176 | return "", fmt.Errorf("token not found: want %q; body %q", token, body) |
| 177 | } |
| 178 | |
| 179 | match := appIDRE.FindSubmatch(body) |
| 180 | if match == nil { |
| 181 | return "", fmt.Errorf("app ID not found: body %q", body) |
| 182 | } |
| 183 | |
| 184 | return string(match[1]), nil |
| 185 | } |
| 186 | |
| 187 | type headerAddingRoundTripper struct { |
| 188 | Wrapped http.RoundTripper |