Skip to content

Instantly share code, notes, and snippets.

@suntong
Forked from Merovius/foo.go
Created June 7, 2019 23:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suntong/7175f685c2611fa6ad06170a0ad460f7 to your computer and use it in GitHub Desktop.
Save suntong/7175f685c2611fa6ad06170a0ad460f7 to your computer and use it in GitHub Desktop.
////////////////////////////////////////////////////////////////////////////
// Program: dbab-svr
// Purpose: Pixel Server in Go
// Authors: Tong Sun (c) 2019, All rights reserved
////////////////////////////////////////////////////////////////////////////
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"regexp"
"strings"
"time"
)
////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions
const (
confFile = "dbab.addr"
proxyFile = "dbab.proxy"
pixel = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x21\xF9\x04\x01\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B"
)
type proxyHandler struct {
setting string
}
////////////////////////////////////////////////////////////////////////////
// Global variables definitions
var (
progname = "dbab-svr"
)
////////////////////////////////////////////////////////////////////////////
// Function definitions
func pixelServ(w http.ResponseWriter, r *http.Request) {
w.Header().Set("ETag", "dbab")
w.Header().Set("Connection", "close")
w.Header().Set("Content-Type", "image/gif")
w.Header().Set("Cache-Control", "public, max-age=31536000")
w.Write([]byte(pixel))
}
func (h *proxyHandler) handle(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Connection", "close")
w.Header().Set("Content-Type", "application/octet-stream")
w.Write([]byte(h.setting))
}
//==========================================================================
// support functions
// readFile returns the single-line file content (less trailing \n) of the file by the given fname
func readFile(fname string) string {
b, err := ioutil.ReadFile(fname)
abortOn("Reading input file: "+fname, err)
return strings.TrimSuffix(string(b), "\n")
}
// abortOn will quit on anticipated errors gracefully without stack trace
func abortOn(errCase string, e error) {
if e != nil {
fmt.Fprintf(os.Stderr, "[%s] %s error: %v\n", progname, errCase, e)
os.Exit(1)
}
}
//==========================================================================
// Main
func main() {
httpPort := readFile(confFile)
_httpPort := os.Getenv("DBAB_SERVER_ADDR")
if _httpPort != "" {
httpPort = _httpPort
}
autoProxy := &proxyHandler{fmt.Sprintf(
"function FindProxyForURL(url, host) { return \"PROXY %s:3128; DIRECT\"; }",
readFile(proxyFile))}
_ = autoProxy
l, err := net.Listen("tcp", httpPort)
if err != nil {
log.Fatal(err)
}
re := regexp.MustCompile(`\s*(\w+)\s*([^\s]+)\s*HTTP\/(\d.\d)`)
for {
c, err := l.Accept()
if err != nil {
log.Fatal(err)
}
if err := c.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
log.Fatal(err)
}
s := bufio.NewScanner(c)
var req struct {
Method string
URL string
Version string
}
for s.Scan() {
line := s.Text()
matches := re.FindStringSubmatch(line)
if matches != nil {
req.Method = strings.ToUpper(matches[1])
req.URL = matches[2]
req.Version = matches[3]
continue
}
if line == "" {
break
}
}
if err := s.Err(); err != nil {
continue
}
if req.Method == "GET" && (req.URL == "/proxy.pac" || req.URL == "/wpad.dat") {
// Ignore the proxy-stuff, it doesn't matter for the benchmark
} else {
fmt.Fprintf(c, "HTTP/1.0 200 OK\r\n")
fmt.Fprintf(c, "Connection: close\r\n")
fmt.Fprintf(c, "Content-type: image/gif\r\n")
fmt.Fprintf(c, "Content-length: 43\r\n\r\n")
c.Write([]byte(pixel))
}
c.Close()
}
l.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment