func (this DocsController) GetDocAsHtml(rw http.ResponseWriter, req *http.Request, params mux.Params) { var fp string var err error DocName := fp_utils.TrimExt(params.ByName("name")) fp = getDocTextFilePath(this.DocRoot, DocName) if fs_utils.Exists(fp) != true { rw.WriteHeader(http.StatusNoContent) return } html, err := readPageAsHtml(DocName, fp) if err != nil { // TODO:MED instead of returning status 500 here, // perhaps should return status OK (200) with // an error message. rw.WriteHeader(500) log.Errorf("ERROR %s", err.Error()) return } _, err = rw.Write(html) if err != nil { http.NotFound(rw, req) log.Errorf("ERROR %s", err.Error()) return } }
func (this DocsController) GetDocSummary(rw http.ResponseWriter, req *http.Request, params mux.Params) { // TODO:HIGH this removing the extension here shouldn't be required // but we'll leave it for now. DocName := fp_utils.TrimExt(params.ByName("name")) fp := getDocPreviewFilePath(this.DocRoot, DocName) if fs_utils.Exists(fp) != true { rw.WriteHeader(http.StatusNoContent) return } data, err := readPageSummary(fp) if err != nil { // TODO:MED instead of returning status 500 here, // perhaps should return status OK (200) with // an error message. rw.WriteHeader(500) log.Errorf("ERROR %s", err.Error()) return } // WARNING: We don't escape any of the user input data here. // I guess this should be OK if the raw data isn't displayed // as HTML anywhere. unsafe := data _, err = rw.Write(unsafe) if err != nil { log.Errorf("ERROR %s", err.Error()) return } }
func (this CommandsController) OpenFile(rw http.ResponseWriter, req *http.Request, params mux.Params) { ResultData := struct { IsSuccess bool ErrorType string ErrorMsg string }{false, "Unknown", "Unknown Error"} defer rest_utils.WriteResultData(rw, &ResultData) DocName := params.ByName("DocName") if DocName == "" { panic("DocName can not be empty.") } TargetFilePath := params.ByName("filepath") if TargetFilePath == "" { panic("TargetFilePath can not be empty.") } rootDir, err := malkovich.GetWikiPageDirectory(DocName) if err != nil { ResultData.IsSuccess = false ResultData.ErrorType = "CannotGetWikiDirectory" ResultData.ErrorMsg = err.Error() return } fp := filepath.Join(rootDir, `files`, TargetFilePath) log.Infof("OpenFile %s", fp) if fs_utils.Exists(fp) != true { ResultData.IsSuccess = false ResultData.ErrorType = "FileDoesNotExist" ResultData.ErrorMsg = err.Error() return } cmd := exec.Command("rundll32.exe", "url.dll,FileProtocolHandler", fp) err = cmd.Run() if err != nil { ResultData.IsSuccess = false ResultData.ErrorType = "CannotOpenFile" ResultData.ErrorMsg = err.Error() return } //== return the correct AJAX result. == ResultData.IsSuccess = true ResultData.ErrorType = "" ResultData.ErrorMsg = "" }
func (this WebServer) HandleNotFound(rw http.ResponseWriter, req *http.Request) { var fp string fp = path.Join(this.DocRoot, req.URL.Path) fp = filepath.ToSlash(fp) fp = path.Clean(fp) fp = filepath.FromSlash(fp) if fs_utils.IsDir(fp) { fp = filepath.Join(fp, "index.html") } if fs_utils.Exists(fp) { // TODO:HIGH we should optionally have a whitelist or blacklist of // files that can and can''t be served. http.ServeFile(rw, req, fp) } else { // TODO:HIGH need to return a 404 error here. } }
func (this WebServer) Handle(rw http.ResponseWriter, req *http.Request, params mux.Params) { //TODO:HIGH Need to ensure requested file is a child of the directory root. var fp string fp = path.Join(this.DocRoot, params.ByName("filepath")) fp = filepath.ToSlash(fp) fp = path.Clean(fp) fp = filepath.FromSlash(fp) if fs_utils.IsDir(fp) { fp = filepath.Join(fp, "index.html") } if fs_utils.Exists(fp) { // TODO:HIGH we should optionally have a whitelist or blacklist of // files that can and can''t be served. http.ServeFile(rw, req, fp) } else { // TODO:HIGH need to return a 404 error here. } }
func updatePageContent(DocName, PageFilePath, DocText string) error { var tx string var OriginalFileName string var err error var TempFN string var TempCopyFN string var RootDir string var IsUndoRequired bool // TODO:MED // This function is pretty long because it is taking effort // to avoid deleting any user data. The file is written // to a temp file first, then the file is renamed to the // target filename. // The safe file update code should be pulled out to a new function. // TODO:HIGH, we could also add a file lock function here to // ensure the target file isn't modified while we're modifing it. // The same thing as Open Office does. // TODO:MED all leading and trailing white space from // the file should be removed. //======================================== IsUndoRequired = true defer func() { if IsUndoRequired { os.Remove(TempFN) os.Remove(TempCopyFN) } }() //======================================== OriginalFileName = PageFilePath RootDir = filepath.Dir(OriginalFileName) err = os.MkdirAll(RootDir, 0666) if err != nil { return errors.New("Cannot create directory. " + err.Error()) } // TODO:MED creating temporary file names. Should // probably look at creating them right away. // or add a document lock. for { tx = rand.AlphaNumeric(32) + ".temp" tx = filepath.Join(RootDir, tx) if fs_utils.Exists(tx) == false { TempFN = tx break } } for { tx = filepath.Base(OriginalFileName) + "." + rand.AlphaNumeric(32) + ".temp" tx = filepath.Join(RootDir, tx) if fs_utils.Exists(tx) == false { TempCopyFN = tx break } } err = ioutil.WriteFile(TempFN, []byte(DocText), os.FileMode(0644)) if err != nil { return errors.New("Cannot write file. " + err.Error()) } if fs_utils.Exists(OriginalFileName) == true { err = os.Rename(OriginalFileName, TempCopyFN) if err != nil { return errors.New("Cannot rename file. " + err.Error()) } } IsUndoRequired = false err = os.Rename(TempFN, OriginalFileName) if err != nil { return errors.New("Cannot rename file. " + err.Error()) } err = os.Rename(TempFN, OriginalFileName) // remove the temp files. os.Remove(TempFN) os.Remove(TempCopyFN) // if we make it this far, nothing has gone wrong. Yay. return nil }
func (this *FilesController) ListForDoc(rw http.ResponseWriter, req *http.Request, params mux.Params) { var fileData []string fileData = make([]string, 0) DocName := params.ByName("DocName") DocFileRoot := this.GetDocFilesRoot(DocName) walkfn := func(path string, info os.FileInfo, err error) error { var text string var nodetype string var root string var name string var ext string var wikilink string path = strings.Replace(path, DocFileRoot, "", -1) path = filepath.ToSlash(path) if info.IsDir() { nodetype = "dir" root = filepath.Dir(path) root = filepath.ToSlash(root) name = filepath.Base(path) text = fmt.Sprintf("{\"type\":\"%s\", \"root\":\"%s\", \"name\":\"%s\"}", nodetype, root, name) } else { nodetype = "file" root = filepath.Dir(path) root = filepath.ToSlash(root) name = filepath.Base(path) ext = filepath.Ext(path) if root == "/" { wikilink = name wikilink = fmt.Sprintf("[[%s]]", wikilink) } else { wikilink = filepath.Join(root, name) wikilink = filepath.ToSlash(wikilink) wikilink = fmt.Sprintf("[[%s]]", wikilink) } text = fmt.Sprintf("{\"type\":\"%s\", \"root\":\"%s\", \"name\":\"%s\", \"ext\":\"%s\", \"wikilink\":\"%s\"}", nodetype, root, name, ext, wikilink) } fileData = append(fileData, text) return nil } if fs_utils.Exists(DocFileRoot) == true { // TODO:MED should probably catch errors here instead // of checking if the directory exists prior. // (It would be the go way!) filepath.Walk(DocFileRoot, walkfn) } rw.Write([]byte("{\"nodes\":[")) c1 := 0 for { if c1 < len(fileData)-1 { rw.Write([]byte(fileData[c1])) rw.Write([]byte(",")) } else if c1 == len(fileData)-1 { rw.Write([]byte(fileData[c1])) } else { break } c1 = c1 + 1 } rw.Write([]byte("]}")) }