Files
SoftwareProject/server.go
2024-03-15 07:22:34 -07:00

364 lines
9.1 KiB
Go

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)
}
}