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())
			}
		}
	}
}
Exemple #2
0
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
	}
}