zoukankan      html  css  js  c++  java
  • 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)
    }
    
    
  • 相关阅读:
    mybatis-plus 错误 java.lang.NoClassDefFoundError
    MySQL+navicat-1064 Error解决方案
    cnblogs博客园修改网站图标icon
    python+pycharm+PyQt5 图形化界面安装教程
    vuex的安装与使用
    vue-router的安装和使用
    VUE-CLI3如何更改配置
    VUE-CL3创建项目
    VUE-CLI2的初始化项目过程
    vuecli脚手架的安装与配置
  • 原文地址:https://www.cnblogs.com/zolo/p/14579904.html
Copyright © 2011-2022 走看看