コード例 #1
0
ファイル: balanser.go プロジェクト: Monnoroch/psearch
func (self *Balanser) Request(w http.ResponseWriter, r *http.Request) ([]error, error) {
	if r.Method != "GET" {
		return nil, util.ClientError(errors.New("Can only process GET requests!"))
	}

	url := *r.URL
	url.Scheme = "http"

	var resErrors []error = nil
	failed := map[string]struct{}{}
	for {
		if len(failed) == self.count {
			return resErrors, errors.New("All backends are broken!")
		}

		backend, err := self.router.Choose()
		if err != nil {
			return resErrors, err
		}

		if _, ok := failed[backend]; ok {
			continue
		}

		url.Host = backend
		nreq, err := http.NewRequest("GET", url.String(), r.Body)
		if err != nil {
			return resErrors, errors.NewErr(err)
		}

		nreq.Header = r.Header
		resp, err := (&http.Client{}).Do(nreq)
		if err != nil {
			failed[backend] = struct{}{}
			resErrors = append(resErrors, errors.NewErr(err))
			continue
		}
		defer resp.Body.Close()

		for k, hs := range resp.Header {
			for _, val := range hs {
				w.Header().Add(k, val)
			}
		}
		w.WriteHeader(resp.StatusCode)
		_, err = io.Copy(w, resp.Body)
		return resErrors, errors.NewErr(err)
	}
}
コード例 #2
0
ファイル: utils.go プロジェクト: Monnoroch/psearch
func GetParam(r *http.Request, name string) (string, error) {
	sval, ok := r.Form[name]
	if !ok || len(sval) != 1 {
		return "", errors.New("No " + name + " in request params!")
	}

	return sval[0], nil
}
コード例 #3
0
func NewChooser(name string, backends []string) (chooser.BackendChooser, error) {
	if name == "random" {
		return chooser.NewRandomChooser(backends), nil
	}
	if name == "roundrobin" {
		return chooser.NewRoundRobinChooser(backends), nil
	}
	return nil, errors.New("Unknown name: \"" + name + "\".")
}
コード例 #4
0
ファイル: utils.go プロジェクト: Monnoroch/psearch
func GetParamOr(r *http.Request, name string, def string) (string, error) {
	sval, ok := r.Form[name]
	if !ok {
		return def, nil
	}

	if len(sval) != 1 {
		return "", errors.New("Too many " + name + " in request params!")
	}

	return sval[0], nil
}
コード例 #5
0
func (self *Balanser) Request(client *net.TCPConn) error {
	defer client.Close()

	failed := map[string]struct{}{}
	for {
		if len(failed) == self.count {
			return errors.New("All backends are broken!")
		}

		backend, err := self.router.Choose()
		if err != nil {
			return err
		}

		if _, ok := failed[backend]; ok {
			continue
		}

		conn, err := net.Dial("tcp", backend)
		if err != nil {
			failed[backend] = struct{}{}
			continue
		}

		server := conn.(*net.TCPConn)

		clientClosed := make(chan error, 1)
		go func() {
			_, err := io.Copy(server, client)
			clientClosed <- errors.NewErr(err)
		}()

		serverClosed := make(chan error, 1)
		go func() {
			_, err := io.Copy(client, server)
			serverClosed <- errors.NewErr(err)
		}()

		select {
		case err = <-clientClosed:
			server.SetLinger(0)
			server.CloseRead()
		case err = <-serverClosed:
		}

		return err
	}
}
コード例 #6
0
ファイル: file_reader.go プロジェクト: Monnoroch/psearch
func (self *FileReader) ReadByte() (byte, error) {
	n, err := self.file.Read(self.buf)
	if err == io.EOF {
		return 0, err
	}
	if err != nil {
		return 0, errors.NewErr(err)
	}

	if n != 1 {
		return 0, errors.New("Read " + strconv.Itoa(n) + " bytes, instead of one!")
	}

	self.offset += 1
	return self.buf[0], nil
}
コード例 #7
0
ファイル: file_reader.go プロジェクト: Monnoroch/psearch
func (self *FileReader) ReadLenval() (uint64, []byte, error) {
	start := self.offset
	l, err := binary.ReadUvarint(self)
	diff := self.offset - start
	if err == io.EOF {
		return diff, nil, err
	}
	if err != nil {
		return diff, nil, errors.NewErr(err)
	}

	res := make([]byte, l)
	n, err := self.Read(res)
	diff += uint64(n)
	if err != nil {
		return diff, nil, err
	}
	if n != int(l) {
		return diff, nil, errors.New("Read " + strconv.Itoa(n) + " bytes, instead of " + strconv.Itoa(int(l)) + "!")
	}

	return diff, res, nil
}