• golang MissingContentLength error


    问题

    金山云对象存储(KS3)的"PUT Object" API老是抛"MissingContentLength"!

    原因

    • go http.NewRequest()接收os.File等非bytes.Buffer, strings.Buffer类型时无法设置ContentLength

    注意: req.Header.set("Content-Length", xxx)是无效的! 最终以http.Request.ContentLength为准!

    解决

    • 在http.NewRequest()时传递http.NoBody构建req对象后再自行设置ContentLength与GetBody
    	req, err := http.NewRequest(http.MethodPut, getUrl("test2.go"), file)
    	if err != nil {
    		panic(err)
    	}
    	sta, _ := file.Stat()
    
    	req.ContentLength = sta.Size()
    
    

    完整源码

    
    func main() {
    	upload()
    }
    
    func upload() {
    
    	file, err := os.Open(`C:UsersJasonDesktopstructmap.go`)
    	if err != nil {
    		panic(err)
    	}
    	defer file.Close()
    
    	file.Seek(0, io.SeekStart)
    	req, err := http.NewRequest(http.MethodPut, getUrl("test2.go"), file)
    	if err != nil {
    		panic(err)
    	}
    	sta, _ := file.Stat()
    
    	req.ContentLength = sta.Size()
    	//req.Header.Set("Content-Length", strconv.FormatInt(sta.Size(), 10)) // 见上,设置Content-Length毛用...
    	date := utcNow()
    	req.Header.Set("Date", date)
    	req.Header.Set("x-kss-acl", "private")
    	req.Header.Set("Authorization", "KSS "+AK+":"+signature(http.MethodPut, "", "", date, "/hezhaowu/test2.go", "x-kss-acl:private"))
    
    	bs, _ := httputil.DumpRequest(req, false)
    
    	fmt.Printf("%s
    ", bs)
    
    	rsp, err := http.DefaultClient.Do(req)
    	if err != nil {
    		panic(err)
    	}
    	defer rsp.Body.Close()
    
    	fmt.Println(rsp.Proto, rsp.Status)
    	io.Copy(os.Stdout, rsp.Body)
    }
    
    func download() {
    	req, err := http.NewRequest(http.MethodGet, getUrl("struct.go"), nil)
    	if err != nil {
    		panic(err)
    	}
    
    	date := utcNow()
    
    	req.Header.Set("Date", date)
    	req.Header.Set("Authorization", "KSS "+AK+":"+signature(http.MethodGet, "", "", date, "/hezhaowu/struct.go"))
    
    	rsp, err := http.DefaultClient.Do(req)
    	if err != nil {
    		panic(err)
    	}
    	defer rsp.Body.Close()
    
    	fmt.Println(rsp.Proto, rsp.Status)
    	io.Copy(os.Stdout, rsp.Body)
    }
    
    func signature(method string, contentMd5 string, contentType string, date string, name string, xobs ...string) string {
    	var sb bytes.Buffer
    	sb.WriteString(method)
    	sb.WriteByte('
    ')
    	sb.WriteString(contentMd5)
    	sb.WriteByte('
    ')
    	sb.WriteString(contentType)
    	sb.WriteByte('
    ')
    	sb.WriteString(date)
    	sb.WriteByte('
    ')
    	for _, v := range xobs {
    		sb.WriteString(v)
    		sb.WriteByte('
    ')
    	}
    	sb.WriteString(name)
    
    	h := hmac.New(sha1.New, []byte(SK))
    	h.Write(sb.Bytes())
    	return base64.StdEncoding.EncodeToString(h.Sum(nil))
    }
    
    func getUrl(name string) string {
    	return "https://" + DM + "/" + name
    }
    
    func utcNow() string {
    	const layout = "Mon, 2 Jan 2006 15:04:05 GMT"
    	return time.Now().UTC().Format(layout)
    }
    
    
  • 相关阅读:
    visual basic VB.NET实例系列教程第三节(常用循环结构之乘法表与数列)
    visual basic VB.NET实例系列教程第二节(好玩又有趣的龟兔赛跑程序)
    visual basic VB.NET实例系列教程第一节(简单实用抽奖程序)
    对DevSecOps的一点认识
    轻便的一句话反弹shell语句
    ActiveMQ 反序列化漏洞(CVE-2015-5254)复现
    《信息安全风险管理》梗概
    微信服务商分账功能开发(PHP)
    哈夫曼编码—文件的压缩与解压(Java)
    哈夫曼编码—数据压缩与解压(Java)
  • 原文地址:https://www.cnblogs.com/zolo/p/14579904.html
Copyright © 2020-2023  润新知