func wrapErrors(handler func(r *http.Request) (interface{}, int, error)) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() resp, status, err := handler(r) if err != nil { w.Header().Set("Content-Type", "application/text") w.WriteHeader(status) common.SafeWrite(w, err.Error()) } else { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) enc := json.NewEncoder(w) if err := enc.Encode(resp); err != nil { w.Header().Set("Content-Type", "application/text") w.WriteHeader(http.StatusInternalServerError) common.SafeWrite(w, err.Error()) } } } }
func (ss *SocketServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { if origin := r.Header.Get("Origin"); origin != "" { w.Header().Set("Access-Control-Allow-Origin", origin) w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Methods", "POST, PUT, PATCH, GET, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding") } if err := r.ParseForm(); err != nil { w.WriteHeader(http.StatusBadRequest) common.SafeWrite(w, fmt.Sprintf("Error parsing form: %s", err.Error())) return } token := r.Form.Get("token") machineKey := r.Form.Get("machine_key") sockType := r.Form.Get("sock_type") fmt.Printf("Get Stream: %s <%s>\n", machineKey, sockType) if err := validateSockType(sockType); err != nil { w.WriteHeader(http.StatusBadRequest) common.SafeWrite(w, err.Error()) return } attachCarousel := func(w http.ResponseWriter, r *http.Request) mgr.Carousel { machine, err := ss.getMachine(machineKey) if err != nil { w.WriteHeader(http.StatusNotFound) common.SafeWrite(w, err.Error()) return nil } defer machine.release() if machine.Token != token { w.WriteHeader(http.StatusUnauthorized) common.SafeWrite(w, "Invalid token") return nil } if machine.State != MACHINE_STATE_ATTACHED { w.WriteHeader(http.StatusConflict) common.SafeWrite(w, fmt.Sprintf("Machine is not attached: %+v\n", machine)) return nil } if machine.connections[sockType] != nil { w.WriteHeader(http.StatusInternalServerError) common.SafeWrite(w, "Machine connection is already bound") return nil } if machine.carousels[sockType] != nil { w.WriteHeader(http.StatusInternalServerError) common.SafeWrite(w, "Machine carousel is already bound") return nil } header := http.Header{} upgrader := websocket.Upgrader{ HandshakeTimeout: 5 * time.Second, ReadBufferSize: 4096, WriteBufferSize: 4096, CheckOrigin: func(r *http.Request) bool { origin := r.Header.Get("Origin") return machine.OriginRegexp.MatchString(origin) }, } conn, err := upgrader.Upgrade(w, r, header) if err != nil { w.WriteHeader(http.StatusInternalServerError) common.SafeWrite(w, err.Error()) return nil } machine.connections[sockType] = conn carousel, err := ss.newCarousel(sockType, machine) if err != nil { fmt.Printf("[sockserver.ServeHTTP]: Error getting new carousel %s\n", err.Error()) return nil } machine.carousels[sockType] = carousel return carousel } detachCarousel := func() { fmt.Printf("[detachCarousel] %s (%s)\n", machineKey, sockType) machine, err := ss.getMachine(machineKey) if err != nil { fmt.Printf("[detachCarousel] Could not find machine with key \"%s\"\n", machineKey) return } defer machine.release() if machine.carousels[sockType] != nil { machine.carousels[sockType].Terminate() delete(machine.carousels, sockType) } if machine.connections[sockType] != nil { machine.connections[sockType].Close() delete(machine.connections, sockType) } } carousel := attachCarousel(w, r) defer detachCarousel() if carousel == nil { //The error has already been written to the response writer or stderr //TODO: this is jenk, redo this return } if err := carousel.Init(); err != nil { fmt.Printf("[sockserver.ServeHTTP] carousel.Init() returns %s\n", err.Error()) return } if err := carousel.Run(); err != nil { fmt.Printf("[sockserver.ServeHTTP] carousel.Run() returns %s\n", err.Error()) return } }