diff --git a/CHANGELOG b/CHANGELOG index 2cebd7a..3ce05eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -54,6 +54,7 @@ c. 在github上发布新版本。 TO RELEASE tank-3.1.0 1. Add prop column into tank31_matter +2. Add charset in mysql config. ALTER TABLE `tank`.`tank30_matter` diff --git a/code/core/config.go b/code/core/config.go index 5b5a1cc..0dc56af 100644 --- a/code/core/config.go +++ b/code/core/config.go @@ -23,5 +23,5 @@ type Config interface { //files storage location. MatterPath() string //when installed by user. Write configs to tank.json - FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string) + FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string) } diff --git a/code/rest/dav_service.go b/code/rest/dav_service.go index f207273..894900f 100644 --- a/code/rest/dav_service.go +++ b/code/rest/dav_service.go @@ -89,7 +89,8 @@ func (this *DavService) PropstatsFromXmlNames(user *User, matter *Matter, xmlNam propstats := make([]dav.Propstat, 0) - var properties []dav.Property + var okProperties []dav.Property + var notFoundProperties []dav.Property for _, xmlName := range xmlNames { //TODO: deadprops not implement yet. @@ -98,22 +99,48 @@ func (this *DavService) PropstatsFromXmlNames(user *User, matter *Matter, xmlNam if liveProp := LivePropMap[xmlName]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) { innerXML := liveProp.findFn(user, matter) - properties = append(properties, dav.Property{ + okProperties = append(okProperties, dav.Property{ XMLName: xmlName, InnerXML: []byte(innerXML), }) } else { - this.logger.Info("%s %s cannot finish.", matter.Path, xmlName.Local) + this.logger.Info("handle props %s %s.", matter.Path, xmlName.Local) + + propMap := matter.FetchPropMap() + if value, isPresent := propMap[xmlName.Local]; isPresent { + okProperties = append(okProperties, dav.Property{ + XMLName: xmlName, + InnerXML: []byte(value), + }) + } else { + + //only accept Space not null. + if xmlName.Space != "" { + + //collect not found props + notFoundProperties = append(notFoundProperties, dav.Property{ + XMLName: xmlName, + InnerXML: []byte(""), + }) + } + + } } } - if len(properties) == 0 { + if len(okProperties) == 0 && len(notFoundProperties) == 0 { panic(result.BadRequest("cannot parse request properties")) } - okPropstat := dav.Propstat{Status: http.StatusOK, Props: properties} + if len(okProperties) != 0 { + okPropstat := dav.Propstat{Status: http.StatusOK, Props: okProperties} + propstats = append(propstats, okPropstat) + } - propstats = append(propstats, okPropstat) + if len(notFoundProperties) != 0 { + notFoundPropstat := dav.Propstat{Status: http.StatusNotFound, Props: notFoundProperties} + propstats = append(propstats, notFoundPropstat) + } return propstats @@ -154,6 +181,11 @@ func (this *DavService) Propstats(user *User, matter *Matter, propfind *dav.Prop //list the directory. func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { + xLimits := request.Header.Get("X-Litmus") + if xLimits == "props: 3 (propfind_invalid2)" { + fmt.Println("stop here!") + } + fmt.Printf("PROPFIND %s\n", subPath) // read depth @@ -202,6 +234,11 @@ func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *htt fmt.Printf("PROPPATCH %s\n", subPath) + xLimits := request.Header.Get("X-Litmus") + if xLimits == "props: 17 (prophighunicode)" { + fmt.Println("stop here!") + } + matter := this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) patches, status, err := webdav.ReadProppatch(request.Body) @@ -218,6 +255,13 @@ func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *htt propStat := dav.Propstat{Status: http.StatusOK} if patch.Remove { + if len(patch.Props) > 0 { + property := patch.Props[0] + if _, isPresent := propMap[property.XMLName.Local]; isPresent { + //delete the prop. + delete(propMap, property.XMLName.Local) + } + } } else { for _, prop := range patch.Props { propMap[prop.XMLName.Local] = string(prop.InnerXML) diff --git a/code/rest/install_controller.go b/code/rest/install_controller.go index cb942a8..ce541cb 100644 --- a/code/rest/install_controller.go +++ b/code/rest/install_controller.go @@ -97,6 +97,7 @@ func (this *InstallController) openDbConnection(writer http.ResponseWriter, requ mysqlSchema := request.FormValue("mysqlSchema") mysqlUsername := request.FormValue("mysqlUsername") mysqlPassword := request.FormValue("mysqlPassword") + mysqlCharset := request.FormValue("mysqlCharset") var mysqlPort int if mysqlPortStr != "" { @@ -105,7 +106,7 @@ func (this *InstallController) openDbConnection(writer http.ResponseWriter, requ mysqlPort = tmp } - mysqlUrl := util.GetMysqlUrl(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword) + mysqlUrl := util.GetMysqlUrl(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset) this.logger.Info("Connect MySQL %s", mysqlUrl) @@ -227,7 +228,7 @@ func (this *InstallController) CreateTable(writer http.ResponseWriter, request * for _, iBase := range this.tableNames { //complete the missing fields or create table. use utf8 charset - db1 := db.Set("gorm:table_options", "CHARSET=utf8").AutoMigrate(iBase) + db1 := db.Set("gorm:table_options", "CHARSET=utf8mb4").AutoMigrate(iBase) this.PanicError(db1.Error) exist, allFields, missingFields := this.getTableMeta(db, iBase) @@ -350,6 +351,7 @@ func (this *InstallController) Finish(writer http.ResponseWriter, request *http. mysqlSchema := request.FormValue("mysqlSchema") mysqlUsername := request.FormValue("mysqlUsername") mysqlPassword := request.FormValue("mysqlPassword") + mysqlCharset := request.FormValue("mysqlCharset") var mysqlPort int if mysqlPortStr != "" { @@ -375,7 +377,7 @@ func (this *InstallController) Finish(writer http.ResponseWriter, request *http. } //announce the config to write config to tank.json - core.CONFIG.FinishInstall(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword) + core.CONFIG.FinishInstall(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset) //announce the context to broadcast the installation news to bean. core.CONTEXT.InstallOk() diff --git a/code/support/tank_config.go b/code/support/tank_config.go index 246f189..823db75 100644 --- a/code/support/tank_config.go +++ b/code/support/tank_config.go @@ -40,6 +40,8 @@ type ConfigItem struct { MysqlUsername string //mysql password MysqlPassword string + //mysql charset + MysqlCharset string } //validate whether the config file is ok @@ -74,6 +76,10 @@ func (this *ConfigItem) validate() bool { core.LOGGER.Error("MysqlSchema is not configured") return false } + if this.MysqlCharset == "" { + core.LOGGER.Error("MysqlCharset is not configured") + return false + } return true @@ -144,7 +150,7 @@ func (this *TankConfig) ReadFromConfigFile() { } util.MakeDirAll(this.matterPath) - this.mysqlUrl = util.GetMysqlUrl(this.item.MysqlPort, this.item.MysqlHost, this.item.MysqlSchema, this.item.MysqlUsername, this.item.MysqlPassword) + this.mysqlUrl = util.GetMysqlUrl(this.item.MysqlPort, this.item.MysqlHost, this.item.MysqlSchema, this.item.MysqlUsername, this.item.MysqlPassword, this.item.MysqlCharset) this.installed = true core.LOGGER.Info("use config file: %s", filePath) @@ -173,7 +179,7 @@ func (this *TankConfig) MatterPath() string { } //Finish the installation. Write config to tank.json -func (this *TankConfig) FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string) { +func (this *TankConfig) FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string) { var configItem = &ConfigItem{ //server port @@ -185,6 +191,7 @@ func (this *TankConfig) FinishInstall(mysqlPort int, mysqlHost string, mysqlSche MysqlSchema: mysqlSchema, MysqlUsername: mysqlUsername, MysqlPassword: mysqlPassword, + MysqlCharset: mysqlCharset, } //pretty json. diff --git a/code/tool/util/util_string.go b/code/tool/util/util_string.go index ed33275..ce85805 100644 --- a/code/tool/util/util_string.go +++ b/code/tool/util/util_string.go @@ -38,8 +38,14 @@ func GetMysqlUrl( mysqlHost string, mysqlSchema string, mysqlUsername string, - mysqlPassword string) string { - return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", mysqlUsername, mysqlPassword, mysqlHost, mysqlPort, mysqlSchema) + mysqlPassword string, + mysqlCharset string) string { + + if mysqlCharset == "" { + mysqlCharset = "utf8" + } + + return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", mysqlUsername, mysqlPassword, mysqlHost, mysqlPort, mysqlSchema, mysqlCharset) } //get random number 4.