func (ps *ProposerServer) handleRemovePreparer(w http.ResponseWriter, r *http.Request) {
	buf, _ := ioutil.ReadAll(r.Body)
	u, err := url.Parse(string(buf))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	target := AcceptorClient{URL: u}
	if err := ps.proposer.RemovePreparer(target); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, "OK")
}
RemovePreparer(target Acceptor) error
package httpapi
import (
	"bufio"
	"bytes"
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"github.com/gorilla/mux"
	"github.com/peterbourgon/caspaxos/extension"
	"github.com/peterbourgon/caspaxos/protocol"
)
type ProposerServer struct {
	proposer protocol.Proposer
	*mux.Router
}
var _ http.Handler = (*ProposerServer)(nil)
func NewProposerServer(proposer protocol.Proposer) *ProposerServer {
	ps := &ProposerServer{
		proposer: proposer,
	}
	r := mux.NewRouter()
	{
		r.StrictSlash(true)
		r.Methods("POST").Path("/read/{key}").HandlerFunc(ps.handleRead)
		r.Methods("POST").Path("/cas/{key}").HandlerFunc(ps.handleCAS)
		r.Methods("POST").Path("/identity-read/{key}").HandlerFunc(ps.handleIdentityRead)
		r.Methods("POST").Path("/add-accepter").HandlerFunc(ps.handleAddAccepter)
		r.Methods("POST").Path("/add-preparer").HandlerFunc(ps.handleAddPreparer)
		r.Methods("POST").Path("/remove-preparer").HandlerFunc(ps.handleRemovePreparer)
		r.Methods("POST").Path("/remove-accepter").HandlerFunc(ps.handleRemoveAccepter)
		r.Methods("POST").Path("/full-identity-read/{key}").HandlerFunc(ps.handleFullIdentityRead)
		r.Methods("POST").Path("/fast-forward-increment/{key}").HandlerFunc(ps.handleFastForwardIncrement)
		r.Methods("GET").Path("/list-preparers").HandlerFunc(ps.handleListPreparers)
		r.Methods("GET").Path("/list-accepters").HandlerFunc(ps.handleListAccepters)
		r.Methods("POST").Path("/watch/{key}").HandlerFunc(ps.handleWatch)
	}
	ps.Router = r
	return ps
}
func (ps *ProposerServer) handleRead(w http.ResponseWriter, r *http.Request) {
	var (
		key, _ = url.PathUnescape(mux.Vars(r)["key"])
		read   = func(x []byte) []byte { return x }
	)
	state, b, err := ps.proposer.Propose(r.Context(), key, read)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	version, value, err := parseVersionValue(state)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	setBallot(w.Header(), b)
	setVersion(w.Header(), version)
	w.Write(value)
}
func (ps *ProposerServer) handleCAS(w http.ResponseWriter, r *http.Request) {
	var (
		key, _         = url.PathUnescape(mux.Vars(r)["key"])
		currentVersion = getVersion(r.Header)
		nextValue, _   = ioutil.ReadAll(r.Body)
	)
	cas := func(x []byte) []byte {
		if version, _, err := parseVersionValue(x); err == nil && version == currentVersion {
			return makeVersionValue(version+1, nextValue)
		}
		return x
	}
	state, _, err := ps.proposer.Propose(r.Context(), key, cas)
	if _, ok := err.(protocol.ConflictError); ok {
		http.Error(w, err.Error(), http.StatusPreconditionFailed)  
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	version, value, err := parseVersionValue(state)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	setVersion(w.Header(), version)
	w.Write(value)
}
func (ps *ProposerServer) handleIdentityRead(w http.ResponseWriter, r *http.Request) {
	ps.handleRead(w, r)
}
func (ps *ProposerServer) handleAddAccepter(w http.ResponseWriter, r *http.Request) {
	buf, _ := ioutil.ReadAll(r.Body)
	u, err := url.Parse(string(buf))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	target := AcceptorClient{URL: u}
	if err := ps.proposer.AddAccepter(target); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, "OK")
}
func (ps *ProposerServer) handleAddPreparer(w http.ResponseWriter, r *http.Request) {
	buf, _ := ioutil.ReadAll(r.Body)
	u, err := url.Parse(string(buf))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	target := AcceptorClient{URL: u}
	if err := ps.proposer.AddPreparer(target); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, "OK")
}