|
| 1 | +package handler |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "encoding/json" |
| 6 | + "fmt" |
| 7 | + "net/http" |
| 8 | + "net/url" |
| 9 | + "strings" |
| 10 | + "time" |
| 11 | + |
| 12 | + "io/ioutil" |
| 13 | + "strconv" |
| 14 | + |
| 15 | + "github.com/tencentyun/cos-go-sdk-v5" |
| 16 | + "gopkg.in/yaml.v2" |
| 17 | +) |
| 18 | + |
| 19 | +// Cos 腾讯云Cos服务 |
| 20 | +type Cos struct { |
| 21 | + SecretID string `yaml:"SecretID"` //API密钥ID |
| 22 | + SecretKey string `yaml:"SecretKey"` //API密钥私钥 |
| 23 | + Bucket string `yaml:"Bucket"` //存储桶名称 规则 test-1234567889 |
| 24 | + Region string `yaml:"Region"` //存储桶所属地域 规则 ap-nanjing |
| 25 | + Domain string `yaml:"Domain"` //自定义域名 |
| 26 | + APIAddress string `yaml:"APIAddress"` //API地址(访问域名) 在存储桶列表->配置管理->基础配置中可见 规则 https://<bucket>.cos.<region>.myqcloud.com |
| 27 | +} |
| 28 | + |
| 29 | +// Response 是交付层的基本回应 |
| 30 | +type Response struct { |
| 31 | + Code int `json:"code"` //请求状态代码 |
| 32 | + Message interface{} `json:"message"` //请求结果提示 |
| 33 | + Data interface{} `json:"data"` //请求结果与错误原因 |
| 34 | +} |
| 35 | + |
| 36 | +// List 会返回给交付层一个列表回应 |
| 37 | +type List struct { |
| 38 | + Code int `json:"code"` //请求状态代码 |
| 39 | + Count int `json:"count"` //数据量 |
| 40 | + Message interface{} `json:"message"` //请求结果提示 |
| 41 | + Data interface{} `json:"data"` //请求结果 |
| 42 | +} |
| 43 | + |
| 44 | +// ListObject 对象列表 |
| 45 | +type ListObject struct { |
| 46 | + Filename string `json:"filename"` |
| 47 | + Prefix string `json:"prefix"` |
| 48 | + IsDir bool `json:"is_dir"` |
| 49 | + Size interface{} `json:"size"` |
| 50 | + CreateTime interface{} `json:"create_time"` |
| 51 | +} |
| 52 | + |
| 53 | +// Config 配置文件解析 |
| 54 | +type Config struct { |
| 55 | + Port string `yaml:"Port"` |
| 56 | + Default string `yaml:"Default"` |
| 57 | + Token string `yaml:"Token"` |
| 58 | + UToken string `yaml:"UToken"` |
| 59 | + Cos `yaml:"Cos"` |
| 60 | +} |
| 61 | + |
| 62 | +var ( |
| 63 | + // CosConfig 配置项 |
| 64 | + CosConfig *Config |
| 65 | + // CosClient 客户端 |
| 66 | + CosClient *cos.Client |
| 67 | + //response 返回值 |
| 68 | + response []byte |
| 69 | +) |
| 70 | + |
| 71 | +// GetConfig 调用该方法会实例化conf 项目运行会读取一次配置文件 确保不会有多余的读取损耗 |
| 72 | +func GetConfig() *Config { |
| 73 | + var config = new(Config) |
| 74 | + yamlFile, err := ioutil.ReadFile("config.yaml") |
| 75 | + if err != nil { |
| 76 | + panic(err) |
| 77 | + } |
| 78 | + err = yaml.Unmarshal(yamlFile, config) |
| 79 | + if err != nil { |
| 80 | + //读取配置文件失败,停止执行 |
| 81 | + panic("read config file error:" + err.Error()) |
| 82 | + } |
| 83 | + return config |
| 84 | +} |
| 85 | + |
| 86 | +// Write 输出返回结果 |
| 87 | +func Write(w http.ResponseWriter, response []byte) { |
| 88 | + //公共的响应头设置 |
| 89 | + w.Header().Set("Access-Control-Allow-Origin", "*") |
| 90 | + w.Header().Set("Access-Control-Allow-Headers", "*") |
| 91 | + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, OPTIONS") |
| 92 | + w.Header().Set("Content-Type", "application/json;charset=utf-8") |
| 93 | + w.Header().Set("Content-Length", strconv.Itoa(len(string(response)))) |
| 94 | + _, _ = w.Write(response) |
| 95 | + return |
| 96 | +} |
| 97 | + |
| 98 | +// InitCosClient 初始化操作 |
| 99 | +func InitCosClient() { |
| 100 | + CosConfig = GetConfig() |
| 101 | + CosConfig.APIAddress = fmt.Sprintf("https://%s.cos.%s.myqcloud.com", CosConfig.Bucket, CosConfig.Region) |
| 102 | + u, _ := url.Parse(CosConfig.APIAddress) |
| 103 | + b := &cos.BaseURL{BucketURL: u} |
| 104 | + CosClient = cos.NewClient(b, &http.Client{ |
| 105 | + //设置超时时间 |
| 106 | + Timeout: 100 * time.Second, |
| 107 | + Transport: &cos.AuthorizationTransport{ |
| 108 | + //如实填写账号和密钥,也可以设置为环境变量 |
| 109 | + SecretID: CosConfig.SecretID, |
| 110 | + SecretKey: CosConfig.SecretKey, |
| 111 | + }, |
| 112 | + }) |
| 113 | +} |
| 114 | + |
| 115 | +// Handler 请求参数信息 |
| 116 | +// Operate: 操作类型 [list,delete,upload,domain,mkdir] |
| 117 | +// Prefix: 操作的前缀(前缀意为操作所在的目录) |
| 118 | +// Path: 操作的绝对地址 |
| 119 | + |
| 120 | +// CosHandler 句柄 |
| 121 | +func CosHandler(w http.ResponseWriter, r *http.Request) { |
| 122 | + //初始化 |
| 123 | + InitCosClient() |
| 124 | + var operate = r.URL.Query().Get("operate") |
| 125 | + if operate == "list" { |
| 126 | + // 列举当前目录下的所有文件 |
| 127 | + var result []ListObject //结果集 |
| 128 | + //设置筛选器 |
| 129 | + var prefix = r.URL.Query().Get("prefix") |
| 130 | + opt := &cos.BucketGetOptions{ |
| 131 | + Prefix: prefix, |
| 132 | + Delimiter: "/", |
| 133 | + Marker: prefix, |
| 134 | + } |
| 135 | + //结果入 result |
| 136 | + v, _, err := CosClient.Bucket.Get(context.Background(), opt) |
| 137 | + if err != nil { |
| 138 | + response, _ = json.Marshal(&Response{ |
| 139 | + Code: 500, |
| 140 | + Message: "ErrorListObject:" + err.Error(), |
| 141 | + }) |
| 142 | + Write(w, response) |
| 143 | + return |
| 144 | + } |
| 145 | + for _, dirname := range v.CommonPrefixes { |
| 146 | + result = append(result, ListObject{ |
| 147 | + Filename: strings.Replace(dirname, prefix, "", 1), |
| 148 | + CreateTime: "", |
| 149 | + IsDir: true, |
| 150 | + Prefix: prefix, |
| 151 | + }) |
| 152 | + } |
| 153 | + for _, obj := range v.Contents { |
| 154 | + result = append(result, ListObject{ |
| 155 | + Filename: strings.Replace(obj.Key, prefix, "", 1), |
| 156 | + CreateTime: obj.LastModified, |
| 157 | + IsDir: false, |
| 158 | + Prefix: prefix, |
| 159 | + Size: obj.Size, |
| 160 | + }) |
| 161 | + } |
| 162 | + |
| 163 | + var domain string |
| 164 | + if CosConfig.Domain == "" { |
| 165 | + domain = CosConfig.APIAddress + "/" |
| 166 | + } else { |
| 167 | + domain = CosConfig.Domain |
| 168 | + } |
| 169 | + response, _ = json.Marshal(&List{ |
| 170 | + Code: 200, |
| 171 | + Message: domain, |
| 172 | + Data: result, |
| 173 | + Count: len(result), |
| 174 | + }) |
| 175 | + } else if operate == "delete" { |
| 176 | + //需要删除的文件绝对路径 |
| 177 | + var path = r.URL.Query().Get("path") |
| 178 | + _, err := CosClient.Object.Delete(context.Background(), path) |
| 179 | + if err != nil { |
| 180 | + response, _ = json.Marshal(&Response{ |
| 181 | + Code: 500, |
| 182 | + Message: "ErrorObjectDelete:" + err.Error(), |
| 183 | + }) |
| 184 | + Write(w, response) |
| 185 | + return |
| 186 | + } |
| 187 | + response, _ = json.Marshal(&Response{ |
| 188 | + Code: 200, |
| 189 | + Message: "ok", |
| 190 | + }) |
| 191 | + } else if operate == "upload" { |
| 192 | + var _, header, err = r.FormFile("file") |
| 193 | + var prefix string |
| 194 | + _ = r.ParseMultipartForm(32 << 20) |
| 195 | + if r.MultipartForm != nil { |
| 196 | + values := r.MultipartForm.Value["prefix"] |
| 197 | + if len(values) > 0 { |
| 198 | + prefix = values[0] |
| 199 | + } |
| 200 | + } |
| 201 | + if err != nil { |
| 202 | + response, _ = json.Marshal(&Response{ |
| 203 | + Code: 500, |
| 204 | + Message: "ErrorUpload:" + err.Error(), |
| 205 | + }) |
| 206 | + Write(w, response) |
| 207 | + return |
| 208 | + } |
| 209 | + dst := header.Filename |
| 210 | + source, _ := header.Open() |
| 211 | + _, err = CosClient.Object.Put(context.Background(), prefix+dst, source, nil) |
| 212 | + if err != nil { |
| 213 | + response, _ = json.Marshal(&Response{ |
| 214 | + Code: 500, |
| 215 | + Message: "ErrorObjectUpload:" + err.Error(), |
| 216 | + }) |
| 217 | + Write(w, response) |
| 218 | + return |
| 219 | + } |
| 220 | + var domain string |
| 221 | + if CosConfig.Domain == "" { |
| 222 | + domain = CosConfig.APIAddress + "/" |
| 223 | + } else { |
| 224 | + domain = CosConfig.Domain |
| 225 | + } |
| 226 | + response, _ = json.Marshal(&Response{ |
| 227 | + Code: 200, |
| 228 | + Message: "ok", |
| 229 | + Data: domain + prefix + dst, |
| 230 | + }) |
| 231 | + } else if operate == "domain" { |
| 232 | + var domain string |
| 233 | + if CosConfig.Domain == "" { |
| 234 | + domain = CosConfig.APIAddress + "/" |
| 235 | + } else { |
| 236 | + domain = CosConfig.Domain |
| 237 | + } |
| 238 | + response, _ = json.Marshal(&Response{ |
| 239 | + Code: 200, |
| 240 | + Message: domain, |
| 241 | + }) |
| 242 | + } else if operate == "mkdir" { |
| 243 | + var prefix = r.URL.Query().Get("prefix") |
| 244 | + var dirname = r.URL.Query().Get("dirname") |
| 245 | + _, err := CosClient.Object.Put(context.Background(), prefix+dirname, nil, nil) |
| 246 | + if err != nil { |
| 247 | + response, _ = json.Marshal(&Response{ |
| 248 | + Code: 500, |
| 249 | + Message: "ErrorMkdir:" + err.Error(), |
| 250 | + }) |
| 251 | + Write(w, response) |
| 252 | + return |
| 253 | + } |
| 254 | + response, _ = json.Marshal(&Response{ |
| 255 | + Code: 200, |
| 256 | + Message: "ok", |
| 257 | + }) |
| 258 | + } |
| 259 | + Write(w, response) |
| 260 | +} |
0 commit comments