naett.c

Tiny cross-platform HTTP / HTTPS client library in C.
git clone git://git.finwo.net/lib/naett.c
Log | Files | Refs | README | LICENSE

rig.go (3003B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"io"
      6 	"log"
      7 	"net/http"
      8 	"os"
      9 	"os/exec"
     10 	"path"
     11 )
     12 
     13 func main() {
     14 	if len(os.Args) > 1 && os.Args[1] == "-serve" {
     15 		serve()
     16 	}
     17 
     18 	err := build()
     19 	if err != nil {
     20 		log.Fatal(err)
     21 	}
     22 
     23 	go serve()
     24 
     25 	err = runTest()
     26 	if err != nil {
     27 		log.Fatal(err)
     28 	}
     29 
     30 	os.Exit(0)
     31 }
     32 
     33 func build() error {
     34 	cmd := exec.Command("make")
     35 	output, err := cmd.CombinedOutput()
     36 	if err != nil {
     37 		return fmt.Errorf("build failed: %v", string(output))
     38 	}
     39 	return nil
     40 }
     41 
     42 func runTest() error {
     43 	cwd, err := os.Getwd()
     44 	if err != nil {
     45 		return err
     46 	}
     47 	cmd := exec.Command(path.Join(cwd, "test"), "http://localhost:4711")
     48 	output, err := cmd.CombinedOutput()
     49 	if err != nil {
     50 		return fmt.Errorf("Failed to run test: %s", string(output))
     51 	}
     52 	fmt.Print(string(output))
     53 	return nil
     54 }
     55 
     56 type Handler func(w http.ResponseWriter, r *http.Request)
     57 
     58 func trace(handler Handler) Handler {
     59 	return func(w http.ResponseWriter, r *http.Request) {
     60 		log.Printf("%v - %v", r.Method, r.URL)
     61 		handler(w, r)
     62 	}
     63 }
     64 
     65 func serve() {
     66 	http.HandleFunc("/get", trace(testGETHandler))
     67 	http.HandleFunc("/stress", testGETHandler)
     68 	http.HandleFunc("/post", trace(testPOSTHandler))
     69 	http.HandleFunc("/redirect", trace(testRedirectHandler))
     70 	http.HandleFunc("/redirected", trace(redirectedHandler))
     71 	log.Fatal(http.ListenAndServe(":4711", nil))
     72 }
     73 
     74 func fail(w http.ResponseWriter, message string) {
     75 	w.WriteHeader(400)
     76 	w.Write([]byte(message + "\n"))
     77 }
     78 
     79 func ok(w http.ResponseWriter) {
     80 	w.Write([]byte("OK"))
     81 }
     82 
     83 func checkHeader(w http.ResponseWriter, r *http.Request, header string, expected string) bool {
     84 	actual := r.Header[header]
     85 	if len(actual) == 0 || actual[0] != expected {
     86 		fail(w, fmt.Sprintf("Expected header %q to be %q, got %q", header, expected, actual))
     87 		return false
     88 	}
     89 	return true
     90 }
     91 
     92 func testGETHandler(w http.ResponseWriter, r *http.Request) {
     93 	if r.Method != "GET" {
     94 		fail(w, fmt.Sprintf("Unexpected method, %q", r.Method))
     95 		return
     96 	}
     97 
     98 	if r.ContentLength != 0 {
     99 		fail(w, "Non-empty body in GET")
    100 		return
    101 	}
    102 
    103 	if !checkHeader(w, r, "Accept", "naett/testresult") {
    104 		return
    105 	}
    106 
    107 	if !checkHeader(w, r, "User-Agent", "Naett/1.0") {
    108 		return
    109 	}
    110 
    111 	ok(w)
    112 }
    113 
    114 func testPOSTHandler(w http.ResponseWriter, r *http.Request) {
    115 	if r.Method != "POST" {
    116 		fail(w, fmt.Sprintf("Unexpected method, %q", r.Method))
    117 		return
    118 	}
    119 
    120 	if r.ContentLength == 0 {
    121 		fail(w, "Empty body in POST")
    122 		return
    123 	}
    124 
    125 	if !checkHeader(w, r, "Accept", "naett/testresult") {
    126 		return
    127 	}
    128 
    129 	if !checkHeader(w, r, "User-Agent", "Naett/1.0") {
    130 		return
    131 	}
    132 
    133 	bodyBytes, err := io.ReadAll(r.Body)
    134 	if err != nil {
    135 		fail(w, err.Error())
    136 	}
    137 
    138 	body := string(bodyBytes)
    139 	expectedBody := "TestRequest!"
    140 
    141 	if body != expectedBody {
    142 		fail(w, fmt.Sprintf("Unexpected body: %v", bodyBytes))
    143 	} else {
    144 		ok(w)
    145 	}
    146 }
    147 
    148 func testRedirectHandler(w http.ResponseWriter, _ *http.Request) {
    149 	w.Header().Add("Location", "/redirected")
    150 	w.WriteHeader(302)
    151 }
    152 
    153 func redirectedHandler(w http.ResponseWriter, _ *http.Request) {
    154 	w.Write([]byte("Redirected"))
    155 }