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)
    }
    
    
  • 相关阅读:
    第十五篇: Ajax Control Toolkit 控件包3. DragPanel (拖动效果)
    希望找人一起写个 Ajax 的封装
    第三篇: Silverlight 2.0 下载与安装
    ASP.NET AJAX 1.0 英文文档,视频教程
    第十四篇: 建立 AJAX 母版页 (为了后面例子方便)
    第十三篇: Ajax Control Toolkit 控件包2. CollapsiblePanel (展开和折叠效果)
    几种流行的JS框架的选择
    第二篇: Silverlight 下载与安装
    (原创)WINCE流驱动的动态加载调试
    SQL语法,SQL语句大全,SQL基础(转载)
  • 原文地址:https://www.cnblogs.com/zolo/p/14579904.html
Copyright © 2011-2022 走看看