Skip to content

REST API Examples Program

Rafael Dantas Justo edited this page Jul 15, 2014 · 8 revisions
package main

import (
  "bytes"
  "crypto/md5"
  "crypto/tls"
  "encoding/base64"
  "encoding/json"
  "fmt"
  "github.com/rafaeljusto/shelter/net/http/rest/check"
  "github.com/rafaeljusto/shelter/net/http/rest/protocol"
  "io/ioutil"
  "net/http"
  "net/http/httputil"
  "sort"
  "strconv"
  "strings"
  "time"
)

type Item struct {
  prepare func(item *Item) bool
  url     string
  method  string
  body    string
}

func main() {
  data := []Item{
    {
      url:    "http://localhost:4443/domain/example.com.br.",
      method: "PUT",
      body: `{
  "nameservers": [
    {
      "host": "ns1.example.com.br.",
      "ipv4": "192.0.2.1",
      "ipv6": "fc00::1"
    },
    {
      "host": "ns2.example.com.br.",
      "ipv4": "192.0.2.2",
      "ipv6": "fc00::2"
    }
  ],
  "dsset": [
    {
      "keytag": 48681,
      "algorithm": 7,
      "digest": "42CD908170D80FCD5B42F83A43166EE348785263",
      "digestType": 1
    }
  ]
}`,
    },
    {
      url:    "http://localhost:4443/domain/example.com.br.",
      method: "PUT",
      body: `{
  "nameservers": [
    {
      "host": "ns3.example.com.br.",
      "ipv4": "192.0.2.3",
      "ipv6": "fc00::3"
    },
    {
      "host": "ns4.example.com.br.",
      "ipv4": "192.0.2.4",
      "ipv6": "fc00::4"
    }
  ]
}`,
    },
    {
      url:    "http://localhost:4443/domain/example.com.br.",
      method: "GET",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/example.com.br.",
      method: "HEAD",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/example.com.br.",
      method: "DELETE",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/br./verification",
      method: "PUT",
      body: `{
  "nameservers": [
    {
      "host": "a.dns.br.",
      "ipv4": "200.160.0.10",
      "ipv6": "2001:12ff::10"
    },
    {
      "host": "b.dns.br.",
      "ipv4": "200.189.41.10"
    }
  ]
}`,
    },
    {
      url:    "http://localhost:4443/domain/rafael.net.br./verification",
      method: "GET",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/example1.com.br.",
      method: "PUT",
      body: `{
  "nameservers": [
    {
      "host": "ns1.example1.com.br.",
      "ipv4": "192.0.2.1",
      "ipv6": "fc00::1"
    },
    {
      "host": "ns2.example1.com.br.",
      "ipv4": "192.0.2.2",
      "ipv6": "fc00::2"
    }
  ]
}`,
    },
    {
      url:    "http://localhost:4443/domain/example2.com.br.",
      method: "PUT",
      body: `{
  "nameservers": [
    {
      "host": "ns1.example2.com.br.",
      "ipv4": "192.0.2.3",
      "ipv6": "fc00::3"
    },
    {
      "host": "ns2.example2.com.br.",
      "ipv4": "192.0.2.4",
      "ipv6": "fc00::4"
    }
  ]
}`,
    },
    {
      url:    "http://localhost:4443/domains",
      method: "GET",
      body:   "",
    },
    {
      prepare: func(item *Item) bool {
        _, response := send(Item{
          url:    "http://localhost:4443/scans",
          method: "GET",
          body:   "",
        })

        if response == nil {
          fmt.Println("No response to process!")
          return false
        }

        if response.StatusCode != http.StatusOK {
          fmt.Println("Unexpected status code returned")
          return false
        }

        body, err := ioutil.ReadAll(response.Body)
        if err != nil {
          fmt.Println("Error reading response body. Details:", err)
          return false
        }
        response.Body.Close()

        var scansResponse protocol.ScansResponse
        if err := json.Unmarshal(body, &scansResponse); err != nil {
          fmt.Println("Error parsing response. Details:", err)
          return false
        }

        if len(scansResponse.Scans) > 0 {
          item.url += scansResponse.Scans[0].StartedAt.Format(time.RFC3339Nano)

        } else {
          fmt.Println("No scan item found!")
          return false
        }

        return true
      },
      url:    "http://localhost:4443/scan/",
      method: "GET",
      body:   "",
    },
    {
      url:    "http://localhost:4443/scans/",
      method: "GET",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/example1.com.br.",
      method: "DELETE",
      body:   "",
    },
    {
      url:    "http://localhost:4443/domain/example2.com.br.",
      method: "DELETE",
      body:   "",
    },
  }

  for _, item := range data {
    if item.prepare != nil && !item.prepare(&item) {
      return
    }

    request, response := send(item)
    if response == nil {
      fmt.Println("No response to process!")
      return
    }

    requestHeader, err := httputil.DumpRequestOut(request, false)
    if err != nil {
      fmt.Println("Error converting request to string. Details:", err)
      return
    }
    requestHeaderStr := strings.TrimSpace(string(requestHeader))
    if !strings.Contains(requestHeaderStr, "Content-Length") {
      requestHeaderStr += "\nContent-Length: " + strconv.FormatInt(request.ContentLength, 10)
    }
    requestHeaderOrdered := strings.Split(requestHeaderStr, "\n")[1:]
    sort.Strings(requestHeaderOrdered)
    requestHeaderStr = strings.Split(requestHeaderStr, "\n")[0] + "\n" +
      strings.Join(requestHeaderOrdered, "\n")

    requestBodyJSON := ""
    if len(item.body) > 0 {
      var b bytes.Buffer
      if err := json.Indent(&b, []byte(item.body), "", " "); err != nil {
        fmt.Println("Error formatting request JSON. Details:", err)
        return
      }
      requestBodyJSON = b.String()
    }

    responseHeader, err := httputil.DumpResponse(response, false)
    if err != nil {
      fmt.Println("Error converting response to string. Details:", err)
      return
    }
    responseHeaderStr := strings.TrimSpace(string(responseHeader))
    if !strings.Contains(responseHeaderStr, "Content-Length") {
      responseHeaderStr += "\nContent-Length: " + strconv.FormatInt(response.ContentLength, 10)
    }
    responseHeaderOrdered := strings.Split(responseHeaderStr, "\n")[1:]
    sort.Strings(responseHeaderOrdered)
    responseHeaderStr = strings.Split(responseHeaderStr, "\n")[0] + "\n" +
      strings.Join(responseHeaderOrdered, "\n")

    responseBodyJSON := ""
    if response.ContentLength > 0 && response.Body != nil && item.method != "HEAD" {
      content, err := ioutil.ReadAll(response.Body)
      response.Body.Close()

      if err != nil {
        fmt.Println("Error reading response body. Details:", err)
        return
      }

      var b bytes.Buffer
      if err := json.Indent(&b, content, "", " "); err != nil {
        fmt.Println("Error formatting response JSON. Details:", err)
        return
      }
      responseBodyJSON = b.String()
    }

    fmt.Println("======================================")
    fmt.Printf("\n[REQUEST]\n%s\n\n%s\n", requestHeaderStr, requestBodyJSON)
    fmt.Printf("\n[RESPONSE]\n%s\n\n%s\n", responseHeaderStr, responseBodyJSON)
  }
}

func send(item Item) (*http.Request, *http.Response) {
  var request *http.Request
  var err error

  if len(item.body) > 0 {
    if request, err = http.NewRequest(item.method, item.url,
      strings.NewReader(item.body)); err != nil {

      fmt.Println("Error creating request. Details:", err)
      return request, nil
    }

    hash := md5.New()
    hash.Write([]byte(item.body))
    hashBytes := hash.Sum(nil)
    hashBase64 := base64.StdEncoding.EncodeToString(hashBytes)

    request.Header.Add("Content-MD5", hashBase64)

  } else {
    if request, err = http.NewRequest(item.method, item.url, nil); err != nil {
      fmt.Println("Error creating request. Details:", err)
      return request, nil
    }
  }

  request.Header.Add("Accept", check.SupportedContentType)
  request.Header.Add("Accept-Charset", check.SupportedCharset)
  request.Header.Add("Accept-Language", "en-us")
  request.Header.Add("Content-Type", check.SupportedContentType+"; charset="+check.SupportedCharset)
  request.Header.Add("Date", time.Now().Format(time.RFC1123))

  stringToSign, err := check.BuildStringToSign(request, "key01")
  if err != nil {
    fmt.Println("Error creating authorization. Details:", err)
    return request, nil
  }

  authorization := check.GenerateSignature(stringToSign, "abc123")
  request.Header.Add("Authorization", fmt.Sprintf("%s %s:%s", check.SupportedNamespace, "key01", authorization))

  transport := &http.Transport{
    TLSClientConfig:    &tls.Config{InsecureSkipVerify: true},
    DisableCompression: true,
  }

  client := http.Client{
    Transport: transport,
  }

  response, err := client.Do(request)
  if err != nil {
    fmt.Println(request)
    fmt.Println("Error sending request. Details:", err)
    return request, nil
  }

  return request, response
}
Clone this wiki locally