// build a request based on an existing http.Request func getRequest(reqid uint16, conn http.ResponseWriter, req *http.Request) *request { r := &request{ reqId: reqid, // this is not right because whether the ws<->fcgi connection stays // up is separate from whether the browser<->ws connection goes down // close: req.Close, params: map[string]string{ "SERVER_SOFTWARE": "fcgigo-handler", "HTTP_HOST": req.Host, "SERVER_NAME": req.Host, "REQUEST_URI": req.RawURL, "REQUEST_METHOD": req.Method, "GATEWAY_INTERFACE": "FCGI/1.0", "SERVER_PORT": "0", //TODO "SERVER_ADDR": "127.0.0.1", "SERVER_PROTOCOL": req.Proto, "REMOTE_PORT": "0", "REMOTE_ADDR": conn.RemoteAddr(), // TODO: this wouldn't be defined for a remote responder, but would // if it were spawned. deferred until we support dynamic spawning again // (ie have unit tests). "SCRIPT_FILENAME": "", // TODO: this should be the path portion of the url matched by the // ServeMux pattern "SCRIPT_NAME": req.URL.Path, // TODO: this should be the remainder of the path AFTER the ServeMux // pattern is stripped from the front "PATH_INFO": "", "DOCUMENT_ROOT": "", "PATH_TRANSLATED": "", // depends on PATH_INFO and DOCUMENT_ROOT "QUERY_STRING": req.URL.RawQuery, }, stdin: new(bytes.Buffer), } // set a default DOCUMENT_ROOT if dir, err := os.Getwd(); err != nil { r.params["DOCUMENT_ROOT"] = dir } // patch the ?query_string to include the #fragment if len(req.URL.Fragment) > 0 { r.params["QUERY_STRING"] = r.params["QUERY_STRING"] + "#" + req.URL.Fragment } // carry over the content-length if c, ok := req.Header["Content-Length"]; ok { r.params["CONTENT_LENGTH"] = c } mapFunc := func(c int) int { if c == '-' { return '_' } return c } // store the HTTP_HEADER_NAME version of each header for k, v := range req.Header { k = strings.Map(mapFunc, "HTTP_"+strings.ToUpper(k)) r.params[k] = v } return r }
func logResponse(w http.ResponseWriter, r *http.Request) { fmt.Printf( "%s - - [%s] \"%s %s %s\" - - \"%s\" \"%s\"\n", w.RemoteAddr(), time.UTC().Format("10/Jan/2006:15:04:05 -0700"), r.Method, r.URL.Path, r.Proto, r.Referer, r.UserAgent) }
func log(stamp int64, w io.Writer, rw http.ResponseWriter, req *http.Request) { addr := rw.RemoteAddr() // Strip port number. Make sure we don't cut off bits of the actual IP if we // have an IPv6 address. It will be encased in [ and ]. eg: [::1]:1234 if idx := strings.LastIndex(addr, ":"); idx > strings.LastIndex(addr, "]") { addr = addr[:idx] } fmt.Fprintf(w, "%d %s %s\n", stamp, addr, req.URL) }
func log(rw http.ResponseWriter, req *http.Request) { reqtime := time.Nanoseconds() / 1000 addr := rw.RemoteAddr() // Strip port number. Make sure we don't cut off bits of the actual IP if we // have an IPv6 address. It will be encased in [ and ]. eg: [::1]:1234 if idx := strings.LastIndex(addr, ":"); idx > strings.LastIndex(addr, "]") { addr = addr[:idx] } fmt.Fprintf(os.Stdout, "[i] %d %s %s\n", reqtime, addr, req.URL) }
func httpHandler(rw http.ResponseWriter, req *http.Request) { log(rw, req) cookies := ParseCookies(req) var session *Session if id := GetSecureCookie(cookies, "mudkip_id"); len(id) > 0 { if session = context.GetSession(id); session == nil { SetSecureCookie(rw, "mudkip_id", "", "/", -1) } } else { session = context.CreateSession(rw.RemoteAddr()) SetSecureCookie(rw, "mudkip_id", session.Id, "/", 2592000) } }
// ServeHTTP implements an http.Handler that answers RPC requests. func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { if req.Method != "CONNECT" { w.SetHeader("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusMethodNotAllowed) io.WriteString(w, "405 must CONNECT\n") return } conn, _, err := w.Hijack() if err != nil { log.Print("rpc hijacking ", w.RemoteAddr(), ": ", err.String()) return } io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n") server.ServeConn(conn) }
func evServer(w http.ResponseWriter, r *http.Request) { wevs := make(chan store.Event) logger := util.NewLogger(w.RemoteAddr()) path := r.URL.Path[len(evPrefix):] logger.Println("new", path) evs := Store.Watch(path + "**") // TODO convert store.Snapshot to json and use that go func() { walk(path, Store, wevs) close(wevs) }() websocket.Handler(func(ws *websocket.Conn) { send(ws, path, wevs, logger) send(ws, path, evs, logger) ws.Close() }).ServeHTTP(w, r) }
func (h *logHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { // Strip port number from address addr := rw.RemoteAddr() if colon := strings.LastIndex(addr, ":"); colon != -1 { addr = addr[:colon] } lr := &logRecord{ time: time.UTC(), ip: addr, method: r.Method, rawpath: r.URL.RawPath, userAgent: r.UserAgent, referer: r.Referer, responseStatus: http.StatusOK, proto: r.Proto, rw: rw, } h.handler.ServeHTTP(lr, r) h.ch <- lr }
func newRequest(hr *http.Request, hc http.ResponseWriter) *Request { remoteAddr, _ := net.ResolveTCPAddr(hc.RemoteAddr()) req := Request{ Method: hr.Method, RawURL: hr.RawURL, URL: hr.URL, Proto: hr.Proto, ProtoMajor: hr.ProtoMajor, ProtoMinor: hr.ProtoMinor, Headers: hr.Header, Body: hr.Body, Close: hr.Close, Host: hr.Host, Referer: hr.Referer, UserAgent: hr.UserAgent, Params: hr.Form, RemoteAddr: remoteAddr.IP.String(), RemotePort: remoteAddr.Port, } return &req }
func NewServiceContext(rw http.ResponseWriter, req *http.Request) *ServiceContext { sc := new(ServiceContext) sc.Conn = rw sc.Req = req sc.Compressed = false sc.Cookies = ParseCookies(req) if id := GetSecureCookie(sc.Cookies, "mudkip_id"); len(id) > 0 { if sc.Session = context.GetSession(id); sc.Session == nil { sc.Session = context.CreateSession(rw.RemoteAddr()) SetSecureCookie(rw, "mudkip_id", sc.Session.Id, "/", 2592000) } } else { sc.Session = context.CreateSession(rw.RemoteAddr()) SetSecureCookie(rw, "mudkip_id", sc.Session.Id, "/", 2592000) } if v, ok := req.Header["Accept-Encoding"]; ok { sc.Compressed = strings.Index(v, "gzip") != -1 } return sc }
func HandleGarage(conn http.ResponseWriter, req *http.Request) { timeString := req.FormValue("t") requestTime, err := strconv.Atoi64(timeString) if len(timeString) == 0 || err != nil { conn.WriteHeader(http.StatusBadRequest) fmt.Fprintf(conn, "Missing/bogus 't' query parameter.") return } if requestTime < time.Seconds()-60 { conn.WriteHeader(http.StatusForbidden) fmt.Fprintf(conn, "Request too old.") return } key := req.FormValue("key") if len(key) == 0 { conn.WriteHeader(http.StatusBadRequest) fmt.Fprintf(conn, "Missing 'key' query parameter.") return } secretHasher := hmac.NewSHA1([]byte(sharedSecret)) fmt.Fprint(secretHasher, timeString) expectedHash := fmt.Sprintf("%40x", secretHasher.Sum()) if key != expectedHash { conn.WriteHeader(http.StatusForbidden) fmt.Fprintf(conn, "Signature fail.") return } lastOpenMutex.Lock() defer lastOpenMutex.Unlock() now := time.Seconds() if lastOpenTime > now-10 { conn.WriteHeader(http.StatusBadRequest) fmt.Fprintf(conn, "Too soon, considering this a dup.") return } lastOpenTime = now fmt.Println("Opening garage door...") cmd, err := exec.Run( *heyUPath, []string{"heyu", "on", *x10Unit}, os.Environ(), "/", exec.DevNull, // stdin exec.DevNull, // stdout exec.MergeWithStdout) // stderr if err != nil { GarageOpenError(conn, err) return } fmt.Printf("Started heyu with pid %v\n", cmd.Pid) waitmsg, err := cmd.Wait(0) if err != nil { GarageOpenError(conn, err) return } fmt.Printf("WaitMsg: %v\n", waitmsg) if waitmsg.WaitStatus != 0 { conn.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(conn, "x10 command returned error opening garage: %v", err) return } fmt.Fprint(conn, "Opened.") fmt.Printf("Garage opened at %v from %v\n", time.LocalTime(), conn.RemoteAddr()) }