Created
February 1, 2017 19:07
-
-
Save briansorahan/3207e189db345fb7111bdccb83c7270a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/json" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"strings" | |
"github.com/pkg/errors" | |
) | |
const curbsideURL = "http://challenge.shopcurbside.com" | |
func main() { | |
sessionToken, err := getSession() | |
if err != nil { | |
log.Fatal(err) | |
} | |
if err := start(sessionToken); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func start(sessionToken string) error { | |
req, err := http.NewRequest(http.MethodGet, curbsideURL+"/start", nil) | |
req.Header.Add("Session", sessionToken) | |
if err != nil { | |
return err | |
} | |
resp, err := http.DefaultClient.Do(req) | |
if err != nil { | |
return err | |
} | |
response := Response{} | |
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { | |
return errors.Wrap(err, "decoding response in start") | |
} | |
for _, id := range response.Next { | |
if err := getNext(sessionToken, id); err != nil { | |
return err | |
} | |
} | |
return nil | |
} | |
func getSession() (string, error) { | |
resp, err := http.Get(curbsideURL + "/get-session") | |
if err != nil { | |
return "", err | |
} | |
sessionBytes, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
return "", err | |
} | |
if err := resp.Body.Close(); err != nil { | |
return "", err | |
} | |
return strings.TrimSpace(string(sessionBytes)), nil | |
} | |
func getNext(sessionToken, cur string) error { | |
req, err := http.NewRequest(http.MethodGet, curbsideURL+"/"+cur, nil) | |
req.Header.Add("Session", sessionToken) | |
if err != nil { | |
return err | |
} | |
resp, err := http.DefaultClient.Do(req) | |
if err != nil { | |
return err | |
} | |
if resp.StatusCode == http.StatusBadRequest { | |
body, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
return err | |
} | |
if strings.HasPrefix(string(body), "Invalid session id") { | |
newToken, err := getSession() | |
if err != nil { | |
return err | |
} | |
if err := getNext(newToken, cur); err != nil { | |
return err | |
} | |
} | |
} | |
if resp.StatusCode >= 300 { | |
return errors.Wrapf(err, "code=%d", resp.StatusCode) | |
} | |
var ( | |
buf = &bytes.Buffer{} | |
r = io.TeeReader(resp.Body, buf) | |
response = Response{} | |
) | |
if err := json.NewDecoder(r).Decode(&response); err != nil { | |
// Try decoding "next" as a single string. | |
rs := ResponseSingle{} | |
if err := json.NewDecoder(buf).Decode(&rs); err != nil { | |
return errors.Wrap(err, "decoding response in getNext") | |
} | |
if err := getNext(sessionToken, rs.Next); err != nil { | |
return err | |
} | |
} | |
if len(response.Secret) > 0 { | |
fmt.Printf("%s", response.Secret) | |
return nil | |
} | |
for _, id := range response.Next { | |
if err := getNext(sessionToken, id); err != nil { | |
return err | |
} | |
} | |
return nil | |
} | |
type Response struct { | |
Next []string `json:"next"` | |
Secret string `json:"secret"` | |
} | |
type ResponseSingle struct { | |
Next string `json:"next"` | |
Secret string `json:"secret"` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment