Skip to content

Instantly share code, notes, and snippets.

@kylelemons
Created July 25, 2017 23:08
Show Gist options
  • Save kylelemons/eede128f012ae5830ec25c923579c677 to your computer and use it in GitHub Desktop.
Save kylelemons/eede128f012ae5830ec25c923579c677 to your computer and use it in GitHub Desktop.
Very quick example of an HTTP client that connects to a server and posts URLencoded key-value pairs
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
)
// CheckinClient is just an example of what you might collect into a "client" struct.
type CheckinClient struct {
URL string
User string
Password string
}
func (c *CheckinClient) Checkin(values url.Values) error {
// Create a new POST request with the urlencoded checkin values
req, err := http.NewRequest("POST", c.URL, strings.NewReader(values.Encode()))
if err != nil {
return fmt.Errorf("failed to create request: %s", err)
}
// The endpoint requires basic authentication, so set the username/password
req.SetBasicAuth(c.User, c.Password)
// We're sending URLEncoded data in the body, so tell the server what to expect
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// Execute the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("failed to checkin: %s", err)
}
defer resp.Body.Close()
// Copy the body to the console in case there is any response
io.Copy(os.Stdout, resp.Body)
return nil
}
func main() {
// Make a fake checkin server that we can pretend to connect to
fakeCheckinServer := httptest.NewServer(http.HandlerFunc(logRequest))
// Create a "client" with the stuff that's the same for every request
config := &CheckinClient{
URL: fakeCheckinServer.URL + "/checkin/",
User: "sal",
Password: "superSECRET",
}
// Execute a checkin, providing the data to send to the checkin endpoint
config.Checkin(url.Values{
"serial": {"abcde"},
"key": {"private_key_or_auth_token_or_whatever"},
"name": {"gopher"},
"disk_size": {"42"},
"sal_version": {"1"},
})
}
// logRequest is just a dummy "in process" thing that pretends to be the remote server and prints out what it gets
func logRequest(w http.ResponseWriter, r *http.Request) {
log.Printf("Path: %q", r.URL.Path)
if err := r.ParseForm(); err != nil {
log.Fatalf("failed to parse form: %s", err)
}
username, password, ok := r.BasicAuth()
log.Printf("User auth: %s %q (%v)", username, password, ok)
log.Printf("Server records:")
for k, v := range r.Form {
log.Printf(" - %q = %q", k, v)
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "OK")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment