- برگشت به خانه
- درباره ذخیرهسازی ابری
- راهاندازی سریع!
- آپلود فایل
- دانلود فایل
- مشاهده فایل
- اشتراکگذاری فایل
- حذف فایل
- تغییر سطح دسترسی
- ایجاد کلید
- ساخت کلید جدید
- ویرایش کلید
- حذف کلید
- انتقال فایل از باکت به باکت دیگر
- تهیه فایلپشتیبان با rclone
- تهیه فایلپشتیبان با S3 Browser
- دانلود مستقیم فایل
- NodeJS
- NextJS
- Laravel
- PHP
- Python
- Django
- Flask
- NET.
- Go
- Imgproxy
- Strapi
- جزئیات فضای ذخیرهسازی ابری
- اتصال دامنه به باکت
اتصال به فضای ذخیرهسازی ابری در برنامههای go
برای استفاده از Object Storage در برنامههای go، بایستی پکیج مورد نیاز را با اجرای دستور زیر، نصب کنید:
go get github.com/aws/aws-sdk-go
پس از آن، کافیست تا طبق مستندات ایجاد کلید، یک کلید جدید برای باکت خود بسازید. اطلاعات مربوط به ENDPOINT و نام باکت نیز در صفحه تنظیمات، در بخش دسترسی با SDK، برای شما قرار گرفته است. در نهایت نیز، بایستی اطلاعات مربوط به Object Storage خود را به متغیرهای محیطی برنامه خود، اضافه کنید؛ به عنوان مثال:
LIARA_ENDPOINT_URL=https://storage.iran.liara.space
LIARA_ACCESS_KEY=nieiou08cnbod58p
LIARA_SECRET_KEY=20b71a4c-1168-4945-8ed3-4724dbf9e997
BUCKET_NAME=bucket-name
تمامی کارها انجام شده است و میتوانید از Object Storage در برنامه خود، استفاده کنید؛ در ادامه، مثالهایی از نحوه استفاده از Object Storage در برنامههای go برای شما قرار گرفته است.
پیکربندی اولیه، ساخت نشست و کلاینت S3
// s3client.go
package main
import (
"log"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/joho/godotenv"
)
var s3Client *s3.S3
var bucket string
func initS3Client() {
// Load environment variables from .env file
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
endpoint := os.Getenv("LIARA_ENDPOINT_URL")
accessKey := os.Getenv("LIARA_ACCESS_KEY")
secretKey := os.Getenv("LIARA_SECRET_KEY")
bucket = os.Getenv("BUCKET_NAME")
if endpoint == "" || accessKey == "" || secretKey == "" || bucket == "" {
log.Fatal("Environment variables are not set properly")
}
// Create a new AWS session
sess, err := session.NewSession(&aws.Config{
Endpoint: aws.String(endpoint),
Region: aws.String("us-east-1"), // Region is required but can be arbitrary for S3-compatible storage
Credentials: credentials.NewStaticCredentials(accessKey, secretKey, ""),
})
if err != nil {
log.Fatalf("Failed to create AWS session: %v", err)
}
// Create S3 client
s3Client = s3.New(sess)
}
آپلود کردن فایل
// upload.go
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func uploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20) // 10 MB limit
file, handler, err := r.FormFile("file")
if err != nil {
http.Redirect(w, r, "/list?message="+url.QueryEscape("Error: Unable to parse file."), http.StatusSeeOther)
return
}
defer file.Close()
buf := bytes.NewBuffer(nil)
io.Copy(buf, file)
_, err = s3Client.PutObject(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(handler.Filename),
Body: bytes.NewReader(buf.Bytes()),
})
if err != nil {
http.Redirect(w, r, "/list?message="+url.QueryEscape("Error: Failed to upload file."), http.StatusSeeOther)
return
}
// Redirect with success message
http.Redirect(w, r, "/list?message="+url.QueryEscape(fmt.Sprintf("File '%s' uploaded successfully.", handler.Filename)), http.StatusSeeOther)
}
دریافت لینک دائمی
// permanent.go
package main
import "fmt"
var endpointURL string
// SetEndpointURL sets the endpoint URL for generating permanent URLs
func setEndpointURL(url string) {
endpointURL = url
}
// GeneratePermanentURL generates the permanent URL for a file
func GeneratePermanentURL(fileKey string) string {
return fmt.Sprintf("%s/%s/%s", endpointURL, bucket, fileKey)
}
دریافت لینک موقتی
// presigned.go
package main
import (
"fmt"
"net/http"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func generatePreSignedURL(w http.ResponseWriter, r *http.Request) {
fileKey := r.URL.Query().Get("key")
if fileKey == "" {
http.Error(w, "Missing 'key' query parameter", http.StatusBadRequest)
return
}
req, _ := s3Client.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(fileKey),
})
urlStr, err := req.Presign(15 * time.Minute)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to generate pre-signed URL: %v", err), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Pre-signed URL for file '%s': %s
", fileKey, urlStr)
}
دانلود فایل
// download.go
package main
import (
"fmt"
"io"
"net/http"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func downloadFile(w http.ResponseWriter, r *http.Request) {
fileKey := r.URL.Query().Get("key")
if fileKey == "" {
http.Error(w, "Missing 'key' query parameter", http.StatusBadRequest)
return
}
resp, err := s3Client.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(fileKey),
})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to download file: %v", err), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileKey))
w.Header().Set("Content-Type", "application/octet-stream")
io.Copy(w, resp.Body)
}
حذف فایل
// delete.go
package main
import (
"fmt"
"net/http"
"net/url"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func deleteFile(w http.ResponseWriter, r *http.Request) {
fileKey := r.URL.Query().Get("key")
if fileKey == "" {
http.Redirect(w, r, "/list?message="+url.QueryEscape("Error: Missing 'key' query parameter."), http.StatusSeeOther)
return
}
_, err := s3Client.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(fileKey),
})
if err != nil {
http.Redirect(w, r, "/list?message="+url.QueryEscape(fmt.Sprintf("Error: Failed to delete file '%s'.", fileKey)), http.StatusSeeOther)
return
}
// Redirect with success message
http.Redirect(w, r, "/list?message="+url.QueryEscape(fmt.Sprintf("File '%s' deleted successfully.", fileKey)), http.StatusSeeOther)
}
لیستکردن فایلها
// list.go
package main
import (
"bytes"
"fmt"
"net/http"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func listFiles(w http.ResponseWriter, r *http.Request) {
// Fetch optional message or link from query parameters
message := r.URL.Query().Get("message")
permanentLink := r.URL.Query().Get("permanent_link")
presignedURL := r.URL.Query().Get("presigned_url")
// Fetch files from the S3 bucket
result, err := s3Client.ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to list files: %v", err), http.StatusInternalServerError)
return
}
// Generate HTML dynamically
var html bytes.Buffer
html.WriteString(`
<h1>File Manager</h1>`)
// Display message if present
if message != "" {
html.WriteString(fmt.Sprintf(`<p>%s</p>`, message))
}
// Display permanent link if present
if permanentLink != "" {
html.WriteString(fmt.Sprintf(`<p><strong>Permanent Link:</strong> <a href="%s" target="_blank">%s</a></p>`, permanentLink, permanentLink))
}
// Display pre-signed URL if present
if presignedURL != "" {
html.WriteString(fmt.Sprintf(`<p><strong>Pre-Signed URL:</strong> <a href="%s" target="_blank">%s</a></p>`, presignedURL, presignedURL))
}
// Upload form
html.WriteString(`
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="file">Upload File:</label>
<input type="file" name="file" id="file" required>
<button type="submit">Upload</button>
</form>
<table border="1">
<tr>
<th>File Name</th>
<th>Actions</th>
</tr>`)
for _, item := range result.Contents {
fileKey := *item.Key
// Add table row
html.WriteString(fmt.Sprintf(`
<tr>
<td>%s</td>
<td>
<form action="/get-permanent-link" method="get" style="display:inline;">
<input type="hidden" name="key" value="%s">
<button type="submit">Get Permanent Link</button>
</form>
<form action="/get-presigned-url" method="get" style="display:inline;">
<input type="hidden" name="key" value="%s">
<button type="submit">Get Pre-Signed URL</button>
</form>
<form action="/delete" method="get" style="display:inline;">
<input type="hidden" name="key" value="%s">
<button type="submit">Delete</button>
</form>
</td>
</tr>`, fileKey, fileKey, fileKey, fileKey))
}
html.WriteString(`</table>`)
w.Header().Set("Content-Type", "text/html")
w.Write(html.Bytes())
}
تجمیع قابلیتها
برای استفاده از تمامی کدهای ذکر شده، یک فایل به اسم main.go ایجاد کنید و کدهای زیر را در آن قرار دهید:
// main.go
package main
import (
"fmt"
"log"
"net/http"
"net/url"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func main() {
// Initialize S3 client
initS3Client()
// Set the endpoint URL for generating permanent URLs
setEndpointURL(os.Getenv("LIARA_ENDPOINT_URL"))
// Define routes
http.HandleFunc("/", mainPage)
http.HandleFunc("/upload", uploadFile)
http.HandleFunc("/download", downloadFile)
http.HandleFunc("/delete", deleteFile)
http.HandleFunc("/list", listFiles)
// New routes for getting links
http.HandleFunc("/get-permanent-link", getPermanentLink)
http.HandleFunc("/get-presigned-url", getPreSignedURL)
// Start the server
port := "8080"
fmt.Printf("Server started on port %s
", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
func getPermanentLink(w http.ResponseWriter, r *http.Request) {
fileKey := r.URL.Query().Get("key")
if fileKey == "" {
http.Redirect(w, r, "/list?message=Error: Missing file key.", http.StatusSeeOther)
return
}
// Generate permanent link
permanentLink := GeneratePermanentURL(fileKey)
// Redirect back to /list with the permanent link
redirectURL := fmt.Sprintf("/list?permanent_link=%s", url.QueryEscape(permanentLink))
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
}
func getPreSignedURL(w http.ResponseWriter, r *http.Request) {
fileKey := r.URL.Query().Get("key")
if fileKey == "" {
http.Redirect(w, r, "/list?message=Error: Missing file key.", http.StatusSeeOther)
return
}
// Generate pre-signed URL
req, _ := s3Client.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(fileKey),
})
presignedURL, _ := req.Presign(15 * time.Minute)
// Redirect back to /list with the pre-signed URL
redirectURL := fmt.Sprintf("/list?presigned_url=%s", url.QueryEscape(presignedURL))
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
}
در ادامه، یک فایل به اسم templates.go ایجاد کنید و کدهای زیر را در آن قرار دهید:
// templates.go
package main
import "net/http"
func mainPage(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/list", http.StatusSeeOther)
}
تمامی کارها انجام شده است و میتوانید با اجرای دستور زیر، برنامه خود را اجرا کنید:
go run .
یک پروژه آماده استقرار در گیتهاب لیارا وجود دارد که میتوانید از آن، استفاده کنید.