예제 #1
0
파일: file.go 프로젝트: skycoin/skycoin
func (me *File) prepareReader() (err error) {
	if me.r != nil && me.off != me.rOff {
		me.r.Close()
		me.r = nil
	}
	if me.r != nil {
		return nil
	}
	if me.flags&missinggo.O_ACCMODE == os.O_WRONLY {
		err = errors.New("read flags missing")
		return
	}
	req, err := http.NewRequest("GET", me.url, nil)
	if err != nil {
		return
	}
	if me.off != 0 {
		req.Header.Set("Range", fmt.Sprintf("bytes=%d-", me.off))
	}
	resp, err := me.fs.Client.Do(req)
	if err != nil {
		return
	}
	switch resp.StatusCode {
	case http.StatusPartialContent:
		cr, ok := httptoo.ParseBytesContentRange(resp.Header.Get("Content-Range"))
		if !ok || cr.First != me.off {
			err = errors.New("bad response")
			resp.Body.Close()
			return
		}
		me.length = cr.Length
	case http.StatusOK:
		if me.off != 0 {
			err = errors.New("bad response")
			resp.Body.Close()
			return
		}
		if h := resp.Header.Get("Content-Length"); h != "" {
			var cl uint64
			cl, err = strconv.ParseUint(h, 10, 64)
			if err != nil {
				resp.Body.Close()
				return
			}
			me.length = int64(cl)
		}
	case http.StatusNotFound:
		err = ErrNotFound
		resp.Body.Close()
		return
	default:
		err = errors.New(resp.Status)
		resp.Body.Close()
		return
	}
	me.r = resp.Body
	me.rOff = me.off
	return
}
예제 #2
0
파일: misc.go 프로젝트: skycoin/skycoin
// ok is false if the response just doesn't specify anything we handle.
func instanceLength(r *http.Response) (l int64, err error) {
	switch r.StatusCode {
	case http.StatusOK:
		l, err = strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64)
		return
	case http.StatusPartialContent:
		cr, parseOk := httptoo.ParseBytesContentRange(r.Header.Get("Content-Range"))
		l = cr.Length
		if !parseOk {
			err = errors.New("error parsing Content-Range")
		}
		return
	default:
		err = errors.New("unhandled status code")
		return
	}
}