ChatGPT 寫的,還沒看能不能動...
package main
import (
"html/template"
"io"
"net/http"
"os"
"path/filepath"
)
func main() {
http.HandleFunc("/", handleFileServer)
http.HandleFunc("/upload", handleUpload)
// Start the server on port 8080
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
func handleFileServer(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
dirPath := "." // Current directory
filePath := filepath.Join(dirPath, r.URL.Path)
file, err := os.Open(filePath)
if err != nil {
http.Error(w, "File not found", http.StatusNotFound)
return
}
defer file.Close()
// Check if the path is a directory
fileInfo, err := file.Stat()
if err != nil {
http.Error(w, "Failed to get file info", http.StatusInternalServerError)
return
}
if fileInfo.IsDir() {
renderDirectory(w, filePath)
return
}
// Serve the file if it's not a directory
http.ServeFile(w, r, filePath)
}
func renderDirectory(w http.ResponseWriter, dirPath string) {
tmpl, err := template.New("directory").Parse(directoryTemplate)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
// Read the directory content
dir, err := os.ReadDir(dirPath)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
data := struct {
DirectoryName string
Files []string
}{
DirectoryName: dirPath,
Files: make([]string, 0),
}
for _, entry := range dir {
data.Files = append(data.Files, entry.Name())
}
// Render the template
err = tmpl.Execute(w, data)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
func handleUpload(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Limit the maximum file size to 10 MB
r.ParseMultipartForm(10 << 20)
// Get the uploaded file
file, handler, err := r.FormFile("file")
if err != nil {
http.Error(w, "Failed to get file from request", http.StatusBadRequest)
return
}
defer file.Close()
// Create the file in the current directory
f, err := os.Create(handler.Filename)
if err != nil {
http.Error(w, "Failed to create file on server", http.StatusInternalServerError)
return
}
defer f.Close()
// Copy the uploaded file to the server
_, err = io.Copy(f, file)
if err != nil {
http.Error(w, "Failed to save file on server", http.StatusInternalServerError)
return
}
// Redirect back to the directory listing
http.Redirect(w, r, "/", http.StatusFound)
}
const directoryTemplate = `
<!DOCTYPE html>
<html>
<head>
<title>Directory Listing: {{ .DirectoryName }}</title>
</head>
<body>
<h1>Directory Listing: {{ .DirectoryName }}</h1>
<ul>
{{ range .Files }}
<li><a href="{{ . }}">{{ . }}</a></li>
{{ end }}
</ul>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
</body>
</html>
`