예제 #1
0
func virusTotalHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	filename := sanitize.Path(filepath.Base(vars["filename"]))

	contentLength := r.ContentLength
	contentType := r.Header.Get("Content-Type")

	log.Printf("Submitting to VirusTotal: %s %d %s", filename, contentLength, contentType)

	apikey := config.VIRUSTOTAL_KEY

	vt, err := virustotal.NewVirusTotal(apikey)
	if err != nil {
		http.Error(w, err.Error(), 500)
	}

	var reader io.Reader

	reader = r.Body

	result, err := vt.Scan(filename, reader)
	if err != nil {
		http.Error(w, err.Error(), 500)
	}

	log.Println(result)
	w.Write([]byte(fmt.Sprintf("%v\n", result.Permalink)))
}
예제 #2
0
func scanHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	filename := sanitize.Path(filepath.Base(vars["filename"]))

	contentLength := r.ContentLength
	contentType := r.Header.Get("Content-Type")

	log.Printf("Scanning %s %d %s", filename, contentLength, contentType)

	var reader io.Reader

	reader = r.Body

	c := clamd.NewClamd(config.CLAMAV_DAEMON_HOST)

	response, err := c.ScanStream(reader)
	if err != nil {
		log.Printf("%s", err.Error())
		http.Error(w, err.Error(), 500)
		return
	}

	var b string

	for s := range response {
		b += s

		if !strings.HasPrefix(s, "stream: ") {
			continue
		}

		w.Write([]byte(fmt.Sprintf("%v\n", s[8:])))
	}
}
예제 #3
0
func tarGzHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	files := vars["files"]

	tarfilename := fmt.Sprintf("transfersh-%d.tar.gz", uint16(time.Now().UnixNano()))

	w.Header().Set("Content-Type", "application/x-gzip")
	w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", tarfilename))
	w.Header().Set("Connection", "close")

	os := gzip.NewWriter(w)
	defer os.Close()

	zw := tar.NewWriter(os)
	defer zw.Close()

	for _, key := range strings.Split(files, ",") {
		if strings.HasPrefix(key, "/") {
			key = key[1:]
		}

		key = strings.Replace(key, "\\", "/", -1)

		token := strings.Split(key, "/")[0]
		filename := sanitize.Path(strings.Split(key, "/")[1])

		reader, _, contentLength, err := storage.Get(token, filename)
		if err != nil {
			if err.Error() == "The specified key does not exist." {
				http.Error(w, "File not found", 404)
				return
			} else {
				log.Printf("%s", err.Error())
				http.Error(w, "Could not retrieve file.", 500)
				return
			}
		}

		defer reader.Close()

		header := &tar.Header{
			Name: strings.Split(key, "/")[1],
			Size: int64(contentLength),
		}

		err = zw.WriteHeader(header)
		if err != nil {
			log.Printf("%s", err.Error())
			http.Error(w, "Internal server error.", 500)
			return
		}

		if _, err = io.Copy(zw, reader); err != nil {
			log.Printf("%s", err.Error())
			http.Error(w, "Internal server error.", 500)
			return
		}
	}
}
예제 #4
0
// createDir creates a directory
func (h Handlers) CreateDir(w http.ResponseWriter, r *http.Request) {

	// combine parent and dirname
	parent := mux.Vars(r)["path"]
	dirname := sanitize.Path(r.FormValue("dir[name]"))
	fp := filepath.Join(parent, dirname)

	// check that it is a valid path
	fp, err := h.fixPathWithDir(fp, h.ContentDir)
	if err != nil {
		errInvalidDir.Write(w)
		return
	}

	// check if dir already exists
	if fileExists(fp) || dirExists(fp) {
		errDirConflict.Write(w)
		return
	}

	// make directory
	dir, err := h.Dir.Create(fp)
	if err != nil {
		wrapError(err).Write(w)
		return
	}

	// trim content prefix
	dir.Path = strings.TrimPrefix(dir.Path, h.ContentDir)

	// print info
	printJson(w, &createDirResponse{Dir: dir})
}
예제 #5
0
// CreateAsset uploads a file into the assets directory
func (h Handlers) CreateAsset(w http.ResponseWriter, r *http.Request) {

	// get path to store file in
	dir, err := h.fixPathWithDir(mux.Vars(r)["path"], h.AssetsDir)
	if err != nil {
		fmt.Fprint(w, err)
		return
	}

	// Check page exists [optional]

	// Remove .md extension
	ext := path.Ext(dir)
	dir = dir[0 : len(dir)-len(ext)]

	// Create folder structure in assets folder
	os.MkdirAll(dir, 0755)

	// Get file form request
	file, header, err := r.FormFile("file")
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}
	defer file.Close()

	// Sanitize file name
	filename := sanitize.Path(header.Filename)
	fp := path.Join(dir, filename)

	// Check file name doesn't already exist

	// TODO: save to path based on page name and sanitized file name
	out, err := os.Create(fp)
	if err != nil {
		fmt.Fprintf(w, "Unable to create the file for writing.")
		return
	}
	defer out.Close()

	// write the content from POST to the file
	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Fprintln(w, err)
	}

	asset := &rangolib.Asset{
		Name: filename,
		Path: dir,
	}

	asset.Resample()

	asset.Path = strings.TrimPrefix(asset.Path, h.AssetsDir)

	// TODO: print out proper status message
	printJson(w, &createAssetResponse{Asset: asset})

	// Write filename into page [optional]
}
예제 #6
0
// updateDir renames a directory
func (h Handlers) UpdateDir(w http.ResponseWriter, r *http.Request) {
	fp, err := h.fixPathWithDir(mux.Vars(r)["path"], h.ContentDir)
	if err != nil {
		errInvalidDir.Write(w)
		return
	}

	// check that the specified directory is not the root content folder
	if fp == h.ContentDir {
		errInvalidDir.Write(w)
		return
	}

	// check that directory exists
	if dirExists(fp) == false {
		errDirNotFound.Write(w)
		return
	}

	// combine parent dir with dir name
	parent := filepath.Dir(fp)
	dirname := sanitize.Path(r.FormValue("dir[name]"))
	dest := filepath.Join(parent, dirname)

	// rename directory
	dir, err := h.Dir.Update(fp, dest)
	if err != nil {
		wrapError(err).Write(w)
		return
	}

	// print info
	printJson(w, &updateDirResponse{Dir: dir})
}
예제 #7
0
func download(uri string, folder string, httpClient *http.Client, fileName string) (path string, newEpisode bool, err error) {
	fileName = filepath.Join(folder, fileName)
	fileName = sanitize.Path(fileName)
	logger.Debug.Println("Local resource path : " + fileName)
	tmpFilename := fileName + ".part"
	resourceName := filepath.Base(folder) + " - " + filepath.Base(fileName)
	defer removeTempFile(tmpFilename)

	if !pathExists(fileName) {
		logger.Debug.Println("New resource available : " + resourceName)
		// TODO: check file existence first with io.IsExist
		output, err := os.Create(tmpFilename)
		if err != nil {
			return fileName, newEpisode, err

		}
		defer output.Close()
		req, err := http.NewRequest("GET", uri, nil)
		if err != nil {
			return fileName, newEpisode, err

		}
		req.Close = true
		response, err := httpClient.Do(req)
		if err != nil {
			return fileName, newEpisode, err

		}
		defer response.Body.Close()
		n, err := io.Copy(output, response.Body)
		if err != nil {
			return fileName, newEpisode, err

		}
		logger.Debug.Println("Resource downloaded : " + resourceName + " (" + bytefmt.ByteSize(uint64(n)) + ")")
		os.Rename(tmpFilename, fileName)
		newEpisode = true

	} else {
		logger.Debug.Println("No download since the file exists", fileName)
		newEpisode = false
	}

	return fileName, newEpisode, err
}
예제 #8
0
func (e Episode) file() string {

	fileNamePrefix := EpisodePrefix + e.pubDate() + "-"
	return filepath.Join(e.Podcast.dir(), sanitize.Path(fileNamePrefix+extractResourceNameFromURL(e.enclosure.Url)))
}
예제 #9
0
func zipHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	files := vars["files"]

	zipfilename := fmt.Sprintf("transfersh-%d.zip", uint16(time.Now().UnixNano()))

	w.Header().Set("Content-Type", "application/zip")
	w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipfilename))
	w.Header().Set("Connection", "close")

	zw := zip.NewWriter(w)

	for _, key := range strings.Split(files, ",") {
		if strings.HasPrefix(key, "/") {
			key = key[1:]
		}

		key = strings.Replace(key, "\\", "/", -1)

		token := strings.Split(key, "/")[0]
		filename := sanitize.Path(strings.Split(key, "/")[1])

		reader, _, _, err := storage.Get(token, filename)

		if err != nil {
			if err.Error() == "The specified key does not exist." {
				http.Error(w, "File not found", 404)
				return
			} else {
				log.Printf("%s", err.Error())
				http.Error(w, "Could not retrieve file.", 500)
				return
			}
		}

		defer reader.Close()

		header := &zip.FileHeader{
			Name:         strings.Split(key, "/")[1],
			Method:       zip.Store,
			ModifiedTime: uint16(time.Now().UnixNano()),
			ModifiedDate: uint16(time.Now().UnixNano()),
		}

		fw, err := zw.CreateHeader(header)

		if err != nil {
			log.Printf("%s", err.Error())
			http.Error(w, "Internal server error.", 500)
			return
		}

		if _, err = io.Copy(fw, reader); err != nil {
			log.Printf("%s", err.Error())
			http.Error(w, "Internal server error.", 500)
			return
		}
	}

	if err := zw.Close(); err != nil {
		log.Printf("%s", err.Error())
		http.Error(w, "Internal server error.", 500)
		return
	}
}
예제 #10
0
func putHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	filename := sanitize.Path(filepath.Base(vars["filename"]))

	contentLength := r.ContentLength

	var reader io.Reader

	reader = r.Body

	if contentLength == -1 {
		// queue file to disk, because s3 needs content length
		var err error
		var f io.Reader

		f = reader

		var b bytes.Buffer

		n, err := io.CopyN(&b, f, _24K+1)
		if err != nil && err != io.EOF {
			log.Printf("%s", err.Error())
			http.Error(w, err.Error(), 500)
			return
		}

		if n > _24K {
			file, err := ioutil.TempFile(config.Temp, "transfer-")
			if err != nil {
				log.Printf("%s", err.Error())
				http.Error(w, err.Error(), 500)
				return
			}

			defer file.Close()

			n, err = io.Copy(file, io.MultiReader(&b, f))
			if err != nil {
				os.Remove(file.Name())
				log.Printf("%s", err.Error())
				http.Error(w, err.Error(), 500)
				return
			}

			reader, err = os.Open(file.Name())
		} else {
			reader = bytes.NewReader(b.Bytes())
		}

		contentLength = n
	}

	contentType := r.Header.Get("Content-Type")

	if contentType == "" {
		contentType = mime.TypeByExtension(filepath.Ext(vars["filename"]))
	}

	token := Encode(10000000 + int64(rand.Intn(1000000000)))

	log.Printf("Uploading %s %d %s", token, filename, contentLength, contentType)

	var err error

	if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil {
		log.Printf("%s", err.Error())
		http.Error(w, errors.New("Could not save file").Error(), 500)
		return
	}

	// w.Statuscode = 200

	w.Header().Set("Content-Type", "text/plain")

	fmt.Fprintf(w, "https://%s/%s/%s\n", ipAddrFromRemoteAddr(r.Host), token, filename)
}
예제 #11
0
func postHandler(w http.ResponseWriter, r *http.Request) {
	if err := r.ParseMultipartForm(_24K); nil != err {
		log.Printf("%s", err.Error())
		http.Error(w, "Error occured copying to output stream", 500)
		return
	}

	token := Encode(10000000 + int64(rand.Intn(1000000000)))

	w.Header().Set("Content-Type", "text/plain")

	for _, fheaders := range r.MultipartForm.File {
		for _, fheader := range fheaders {
			filename := sanitize.Path(filepath.Base(fheader.Filename))
			contentType := fheader.Header.Get("Content-Type")

			if contentType == "" {
				contentType = mime.TypeByExtension(filepath.Ext(fheader.Filename))
			}

			var f io.Reader
			var err error

			if f, err = fheader.Open(); err != nil {
				log.Printf("%s", err.Error())
				http.Error(w, err.Error(), 500)
				return
			}

			var b bytes.Buffer

			n, err := io.CopyN(&b, f, _24K+1)
			if err != nil && err != io.EOF {
				log.Printf("%s", err.Error())
				http.Error(w, err.Error(), 500)
				return
			}

			var reader io.Reader

			if n > _24K {
				file, err := ioutil.TempFile(config.Temp, "transfer-")
				if err != nil {
					log.Fatal(err)
				}
				defer file.Close()

				n, err = io.Copy(file, io.MultiReader(&b, f))
				if err != nil {
					os.Remove(file.Name())

					log.Printf("%s", err.Error())
					http.Error(w, err.Error(), 500)
					return
				}

				reader, err = os.Open(file.Name())
			} else {
				reader = bytes.NewReader(b.Bytes())
			}

			contentLength := n

			log.Printf("Uploading %s %s %d %s", token, filename, contentLength, contentType)

			if err = storage.Put(token, filename, reader, contentType, uint64(contentLength)); err != nil {
				log.Printf("%s", err.Error())
				http.Error(w, err.Error(), 500)
				return

			}

			fmt.Fprintf(w, "https://%s/%s/%s\n", ipAddrFromRemoteAddr(r.Host), token, filename)
		}
	}
}
예제 #12
0
func (podcast Podcast) image() string {
	imageName := extractResourceNameFromURL(podcast.feedPodcast.Image.Url)
	imageName = sanitize.Path(imageName)

	return filepath.Join(podcast.dir(), imageName)
}
예제 #13
0
func (podcast Podcast) dir() (path string) {
	podcastFolder := filepath.Join(podcast.baseFolder, podcast.feedPodcast.Title)
	podcastFolder = sanitize.Path(podcastFolder)
	return podcastFolder
}