package main import ( "bufio" "errors" "fmt" "io" "net/http" "os" "path/filepath" "io/ioutil" "strings" ) const mediaDir = "media/" func LoadServersFromFile(filename string) ([]string, error) { // Open the text file for reading file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() // Create a slice to store IP addresses var ips []string // Create a scanner to read the file line by line scanner := bufio.NewScanner(file) for scanner.Scan() { // Extract the IP from the line ip := scanner.Text() // Append the IP address to the slice ips = append(ips, ip) } // Check for any errors during scanning if err := scanner.Err(); err != nil { return nil, fmt.Errorf("error reading file: %w", err) } return ips, nil } func AddServerToFile(filename, ip string) error { // Open the text file for appending file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0644) if err != nil { return err } defer file.Close() // Write the new IP to the file _, err = fmt.Fprintln(file, ip) if err != nil { return err } return nil } func getRoot(w http.ResponseWriter, r *http.Request) { fmt.Printf("got / request\n") io.WriteString(w, "This is my website!\n") } func getHello(w http.ResponseWriter, r *http.Request) { fmt.Printf("got /hello request\n") io.WriteString(w, "Hello, HTTP!\n") } func getData(w http.ResponseWriter, r *http.Request) { fmt.Printf("got /data request\n") // Set the content type header w.Header().Set("Content-Type", "application/json") // Write your data to the response writer // Here we're just returning a simple JSON response io.WriteString(w, `{"message": "Hello, this is your data!"}`) } func getIPs(w http.ResponseWriter, r *http.Request) { fmt.Printf("got /ips request\n") // Set the content type header w.Header().Set("Content-Type", "text/plain") // Load IPs from file ips, err := LoadServersFromFile("servers.txt") if err != nil { http.Error(w, fmt.Sprintf("Error loading IPs: %s", err), http.StatusInternalServerError) return } // Write IPs to the response writer separated by newline for _, ip := range ips { io.WriteString(w, ip+"\n") } } func addIP(w http.ResponseWriter, r *http.Request) { fmt.Printf("got /addip request\n") // Check if the request method is POST if r.Method != http.MethodPost { http.Error(w, "Only POST requests are allowed", http.StatusMethodNotAllowed) return } // Parse the IP address from the request body ip := r.FormValue("ip") if ip == "" { http.Error(w, "IP address is required", http.StatusBadRequest) return } // Add the IP address to the file err := AddServerToFile("servers.txt", ip) if err != nil { http.Error(w, fmt.Sprintf("Error adding IP: %s", err), http.StatusInternalServerError) return } // Respond with a success message io.WriteString(w, "IP address added successfully\n") } func RemoveIPFromFile(filename, ipToRemove string) error { // Open the original file for reading file, err := os.Open(filename) if err != nil { return err } defer file.Close() // Create a new file to store the updated IP addresses newFilename := filename + ".tmp" newFile, err := os.Create(newFilename) if err != nil { return err } defer newFile.Close() // Create a scanner to read the file line by line scanner := bufio.NewScanner(file) for scanner.Scan() { // Extract the IP from the line ip := scanner.Text() // Check if the IP matches the one to remove if ip != ipToRemove { // Write the IP to the new file _, err := fmt.Fprintln(newFile, ip) if err != nil { return err } } } // Check for any errors during scanning if err := scanner.Err(); err != nil { return fmt.Errorf("error reading file: %w", err) } // Close the new file if err := newFile.Close(); err != nil { return err } // Replace the original file with the new file if err := os.Rename(newFilename, filename); err != nil { return err } return nil } func removeIP(w http.ResponseWriter, r *http.Request) { fmt.Printf("got /removeip request\n") // Check if the request method is POST if r.Method != http.MethodPost { http.Error(w, "Only POST requests are allowed", http.StatusMethodNotAllowed) return } // Parse the IP address from the request body ip := r.FormValue("ip") if ip == "" { http.Error(w, "IP address is required", http.StatusBadRequest) return } // Remove the IP address from the file err := RemoveIPFromFile("servers.txt", ip) if err != nil { http.Error(w, fmt.Sprintf("Error removing IP: %s", err), http.StatusInternalServerError) return } // Respond with a success message io.WriteString(w, "IP address removed successfully\n") } func uploadFileHandler(w http.ResponseWriter, r *http.Request) { // Parse the multipart form err := r.ParseMultipartForm(10 << 20) // 10 MB limit if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Get the file from the form file, handler, err := r.FormFile("file") if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } defer file.Close() // Get the path from the form or set a default path path := r.FormValue("path") if path == "" { path = mediaDir + handler.Filename // Default path } else { path = mediaDir + path } // Create the directory if it doesn't exist err = os.MkdirAll(filepath.Dir(path), 0755) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Save the file to the specified path outFile, err := os.Create(path) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer outFile.Close() // Copy the file content _, err = io.Copy(outFile, file) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Return success response fmt.Fprintf(w, "File uploaded successfully\n") } func downloadFileHandler(w http.ResponseWriter, r *http.Request) { // Get the file path from the URL parameter filePath := strings.TrimPrefix(r.URL.Path, "/download/") if filePath == "" { http.Error(w, "File path is required", http.StatusBadRequest) return } filePath = mediaDir + filePath // prepend media directory // Read the file content fileBytes, err := ioutil.ReadFile(filePath) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Set the appropriate headers w.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(filePath)) w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Length", fmt.Sprintf("%d", len(fileBytes))) // Write the file content to the response body _, err = w.Write(fileBytes) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } func listFilesHandler(w http.ResponseWriter, r *http.Request) { // Get the path from the query parameter or set the default path path := r.URL.Query().Get("path") if path == "" { path = mediaDir } else { path = mediaDir + path } // List files in the specified directory files, err := ioutil.ReadDir(path) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Build the response var fileNames []string for _, file := range files { fileNames = append(fileNames, file.Name()) } // Write the file list as a response fmt.Fprintf(w, "Files in directory %s:\n", path) for _, name := range fileNames { fmt.Fprintf(w, "%s\n", name) } } func deleteFileHandler(w http.ResponseWriter, r *http.Request) { // Get the file path from the URL parameter filePath := strings.TrimPrefix(r.URL.Path, "/delete/") if filePath == "" { http.Error(w, "File path is required", http.StatusBadRequest) return } filePath = mediaDir + filePath // prepend media directory // Delete the file err := os.Remove(filePath) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Return success response fmt.Fprintf(w, "File deleted successfully\n") } func main() { ips, err := LoadServersFromFile("servers.txt") if err != nil { fmt.Println("Error:", err) return } // Print the loaded IP addresses fmt.Println("Loaded servers:") for _, ip := range ips { fmt.Println(ip) } http.HandleFunc("/", getRoot) http.HandleFunc("/hello", getHello) http.HandleFunc("/data", getData) http.HandleFunc("/ips", getIPs) http.HandleFunc("/addip", addIP) http.HandleFunc("/removeip", removeIP) http.HandleFunc("/upload", uploadFileHandler) http.HandleFunc("/download/", downloadFileHandler) http.HandleFunc("/list", listFilesHandler) http.HandleFunc("/delete/", deleteFileHandler) err = http.ListenAndServe(":3333", nil) if errors.Is(err, http.ErrServerClosed) { fmt.Printf("server closed\n") } else if err != nil { fmt.Printf("error starting server: %s\n", err) os.Exit(1) } }