gohttp_work.go 1.8 KB
/*
http server doing some small text work on each http request.

Shows not only how runtime network reactor is good, but also how actual request
processing hooked to the reactor affects overal server handling capacity.
*/

package main

import (
    "fmt"
    "net/http"
)


func handler(w http.ResponseWriter, r *http.Request) {
    xc := NewXClassifier()
    path := r.URL.Path
    for i := range path {
        xc.nextChar(path[i])
    }

    fmt.Fprintf(w, "%s:\t%d\n%s:\t%d\n%s:\t%d\n%s:\t%d\ntotal:\t%d\n",
                navytux, xc.nnavytux, nexedi, xc.nnexedi,
                lab, xc.nlab, erp5, xc.nerp5,
                xc.ntotal)
}


const (
    navytux = "navytux.spb.ru"
    nexedi  = "www.nexedi.com"
    lab     = "lab.nexedi.com"
    erp5    = "www.erp5.com"
)

func abs8(v int8) int8 {
    if v >= 0 {
        return v
    }
    return -v
}

// whether character ch is close to string s.
// character is close to a string if it is close to any of characters in it
// character is close to a character if their distance <= 1
func isclose(ch byte, s string) bool {
    for i := 0; i < len(s) ; i++ {
        ch2 := s[i]
        if abs8(int8(ch - ch2)) <= 1 {
            return true
        }
    }
    return false
}


type XClassifier struct {
    nnavytux int
    nnexedi  int
    nlab     int
    nerp5    int
    ntotal   int
}

func NewXClassifier() *XClassifier {
    return &XClassifier{}
}

func (xc *XClassifier) nextChar(ch byte) {
    if isclose(ch, navytux) {
        xc.nnavytux += 1
    }
    if isclose(ch, nexedi) {
        xc.nnexedi  += 1
    }
    if isclose(ch, lab) {
        xc.nlab     += 1
    }
    if isclose(ch, erp5) {
        xc.nerp5    += 1
    }

    xc.ntotal += 1
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Serving on :25000")
    http.ListenAndServe(":25000", nil)
}