func configHandle(w http.ResponseWriter, req *http.Request) {
	if web.AuthCheck(w, req) {
		user := web.AuthUser(req)
		if req.Method == "PUT" {
			dec := json.NewDecoder(req.Body)
			for {
				var uc UserConfig
				if err := dec.Decode(&uc); err == io.EOF {
					break
				} else if err != nil {
					log.Print("Error %v", err)
					break
				}
				configChannel <- configRequest{c: uc, op: setConfig, user: user}
			}
		}
		r := configRequest{op: getConfig, ret: make(chan UserConfig), user: user}
		configChannel <- r
		j, err := json.Marshal(<-r.ret)
		if err != nil {
			fmt.Fprintf(w, "%v\n", err)
			return
		}

		buff := new(bytes.Buffer)
		json.Indent(buff, j, "", "\t")

		if err != nil {
			log.Printf("%v\n", err)
		}
		fmt.Fprintf(w, "%s", buff)
	}
}
func statusXmlHandle(cm *CredsManager, w http.ResponseWriter, req *http.Request) {
	if web.AuthCheck(w, req) {
		user := web.AuthUser(req)
		var state string
		if cm.userCreds[user] == nil {
			state = "auth"
		} else {
			state = bm.BundleUserState(user)
		}
		_, err := w.Write([]byte("<?xml version=\"1.0\"?>\n<pacifica_uploader><status>" + state + "</status></pacifica_uploader>"))
		if err != nil {
			fmt.Fprintf(w, "%v", err)
		}
	}
}
func bundleIdsHandle(bm *BundleManager, w http.ResponseWriter, req *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprintf(w, "{\"Error\":\"%v\"}", err)
		}
	}()
	if web.AuthCheck(w, req) {
		user := web.AuthUser(req)
		if req.Method == "GET" && req.RequestURI == "/bundle/json/" {
			//FIXME allow watcher to be specified by the user of the service.
			list, err := bm.BundleIdsGet(user, "web")
			if err != nil {
				//FIXME
				return
			}
			w.Write([]byte("["))
			for idx, id := range list {
				if idx < len(list)-1 {
					fmt.Fprintf(w, "%v,", id)
				} else {
					fmt.Fprintf(w, "%v", id)
				}
			}
			w.Write([]byte("]"))
		} else if req.Method == "POST" {
			paths := strings.Split(req.RequestURI, "/")
			if len(paths) < 5 {
				//FIXME
				w.WriteHeader(http.StatusBadRequest)
				return
			}
			if paths[4] == "submit" {
				id, err := strconv.Atoi(paths[3])
				if err != nil {
					w.WriteHeader(http.StatusBadRequest)
					return
				}
				log.Printf("Got submit request for %v %v", user, id)
				bm.BundleStateSet(user, id, BundleState_ToBundle)
			} else if paths[4] == "delete" {
				id, err := strconv.Atoi(paths[3])
				if err != nil {
					w.WriteHeader(http.StatusBadRequest)
					return
				}
				log.Printf("Got delete request for %v %v", user, id)
				//FIXME allow the service user to specify the watcher.
				bm.BundleDelete(user, "web", id)
			}
		} else if req.Method == "GET" {
			paths := strings.Split(req.RequestURI, "/")
			id, err := strconv.Atoi(paths[3])
			if err != nil {
				panic(err)
			}
			b, err := bm.BundleGet(user, id)
			panic_err(err)
			state, err := b.StateGet()
			panic_err(err)
			available, err := b.AvailableGet()
			panic_err(err)
			transaction, err := b.TransactionGet()
			panic_err(err)
			errormsg, err := b.ErrorGet()
			panic_err(err)
			file_service, err := b.FileServiceGet()
			panic_err(err)
			flist, err := b.FilesGet()
			panic_err(err)
			fstr := ""
			for id, file := range flist {
				if id > 0 {
					fstr += ","
				}
				spacifica_filename, err := file.PacificaFilenameGet()
				panic_err(err)
				pacifica_filename, err := json.Marshal(spacifica_filename)
				panic_err(err)
				slocal_filename, err := file.LocalFilenameGet()
				panic_err(err)
				local_filename, err := json.Marshal(slocal_filename)
				panic_err(err)
				sdisable_on_error_msg, err := file.DisableOnErrorMsgGet()
				panic_err(err)
				disable_on_error, err := file.DisableOnErrorGet()
				panic_err(err)
				disable_on_error_msg, err := json.Marshal(sdisable_on_error_msg)
				panic_err(err)
				mtime, err := file.MtimeGet()
				panic_err(err)
				smtime := "null"
				if mtime != nil {
					bmtime, err := mtime.MarshalJSON()
					panic_err(err)
					smtime = string(bmtime)
				}
				groups, err := file.GroupsGet()
				panic_err(err)
				sgroups := ""
				for id, group := range groups {
					if id > 0 {
						sgroups += ","
					}
					t, err := json.Marshal(group[0])
					panic_err(err)
					n, err := json.Marshal(group[1])
					panic_err(err)
					sgroups += fmt.Sprintf("{\"Type\":%v, \"Name\":%v}", string(t), string(n))
				}
				//FIXME verify json encodings.
				fstr += fmt.Sprintf(`
{
	"Id":%v,
	"PacificaFilename":%v,
	"LocalFilename":%v,
	"Mtime":%v,
	"DisableOnErrorMsg":%v,
	"DisableOnError":%v,
	"Groups":[%v]
}`,
					file.id,
					string(pacifica_filename),
					string(local_filename),
					smtime,
					string(disable_on_error_msg),
					disable_on_error,
					sgroups)
			}
			fmt.Fprintf(w, `{
	"State":%v,
	"Available":%v,
	"FileService":"%v",
	"Transaction":"%v",
	"ErrorMsg":"%v",
	"Submittable":%v,
	"Editable":%v,
	"MakeEditable":%v,
	"Deletable":%v,
	"Cancelable":%v,
	"Files":[%v]

}`,
				state,
				available,
				file_service,
				transaction,
				errormsg,
				BundleStateActionOk(state, BundleAction_Submittable),
				BundleStateActionOk(state, BundleAction_Editable),
				BundleStateActionOk(state, BundleAction_MakeEditable),
				BundleStateActionOk(state, BundleAction_Deletable),
				BundleStateActionOk(state, BundleAction_Cancelable),
				fstr)
		}
	}
	return
}
func passcredsHandle(cm *CredsManager, w http.ResponseWriter, req *http.Request) {
	if web.AuthCheck(w, req) {
		if req.Method != "PUT" {
			w.WriteHeader(http.StatusMethodNotAllowed)
		} else {
			file, err := ioutil.TempFile(filepath.Join(common.BaseDir, "auth", "tmpcreds"), "creds")
			if err != nil {
				//FIXME what to return here?
				w.WriteHeader(http.StatusBadRequest)
				return
			}
			var buffer [BUFFSIZE]byte
			total := 0
			for {
				num, err := req.Body.Read(buffer[:])
				if (err != nil && err != io.EOF) || num < 0 {
					w.WriteHeader(http.StatusBadRequest)
					log.Printf("Failed to read during pass creds. %v %v", file.Name(), err)
					file.Close()
					os.Remove(file.Name())

					return
				}
				if num == 0 {
					break
				}
				total += num
				if total > MAXCRED {
					w.WriteHeader(http.StatusBadRequest)
					log.Printf("Cred call too big.")
					file.Close()
					os.Remove(file.Name())
					return
				}
				_, err = file.Write(buffer[0:num])
				if err != nil {
					//FIXME what to return here?
					w.WriteHeader(http.StatusBadRequest)
					log.Printf("Failed to write to temp cred file. %v\n", err)
					file.Close()
					os.Remove(file.Name())
					return
				}
			}
			_, err = file.Seek(0, 0)
			if err != nil {
				//FIXME what to return here?
				w.WriteHeader(http.StatusBadRequest)
				os.Remove(file.Name())
				return
			}
			auth := pacificaauth.NewAuth(file)
			file.Close()
			log.Println("testauth:", auth.Services["testauth"])
			client := auth.NewClient()
			r, err := client.Get(auth.Services["testauth"])
			if err != nil {
				log.Println(err)
				os.Remove(file.Name())
				return
			}
			log.Println(r.StatusCode)
			user := web.AuthUser(req)
			upath := filepath.Join(common.BaseDir, "auth", "creds", common.FsEncodeUser(user))
			if platform.PlatformGet() == platform.Windows {
				err = os.Remove(upath)
			}
			err = os.Rename(file.Name(), upath)
			if err != nil {
				log.Println(err)
				os.Remove(file.Name())
				return
			}
			if cm.userCreds[user] != nil {
				oldclient := cm.userCreds[user].NewClient()
				r, err = oldclient.Get(auth.Services["logout"])
				if err != nil {
					log.Println(err)
				} else {
					log.Printf("Logged out %v: %v\n", user, r.StatusCode)
				}
			}
			cm.userCreds[user] = auth
			cm.outage[user] = nil
		}
	}
}