Addressing the first sentence, it was a direct answer to a comment you
made:

> But is it really? If you read the description for Len() on
> bytes.Buffer it is the length of unread portion. But that doesn’t
> mean the buffer isn’t just a portion of the entire body - it can be a
> chunk which is continually reloaded.

As far as the claim that there is a need to have a Len method in
io.Reader, have a look at the code in question. It type asserts on
three concrete types that are known to the function, all three have a
Len method and this is used to obtain the known length. All other
io.Readers are considered to have an unknown length.

Whether it's wrong to use Len depends on whether there is a generally
accepted and consistent set of semantics to Len() int. There is. This
is strengthened if the use of an existing Len method is noted in the
docs.

On Wed, 2019-02-06 at 15:50 -0600, robert engels wrote:
> I am not sure what that has to do with the discussion. My point was
> that for it to be applicable here, it needs to be defined as part of
> io.Reader, since that is what Body is declared as. It is not, so
> using in the manner outlined is not correct IMO.
> 
> > 
> > On Feb 6, 2019, at 3:37 PM, Dan Kortschak <d...@kortschak.io> wrote:
> > 
> > The generalised semantics of Len are that it returns the number of
> > available elements in the collection, being a cognate of the len
> > built-
> > in. This means that as you consume elements from a buffer, the Len
> > value reduces. This is directly equivalent to
> > 
> > for len(buf) != 0 {
> >     println(buf[0])
> >     buf = buf[1:]
> > }
> > 
> > On Wed, 2019-02-06 at 08:56 -0600, Robert Engels wrote:
> > > 
> > > But is it really? If you read the description for Len() on
> > > bytes.Buffer it is the length of unread portion. But that doesn’t
> > > mean the buffer isn’t just a portion of the entire body - it can
> > > be a
> > > chunk which is continually reloaded. 
> > > 
> > > This is the danger in using private APIs publically based upon
> > > the
> > > existence of a method - it leads to very brittle code - and there
> > > are
> > > almost certainly better ways to design it to avoid these issues.
> > > If
> > > the core api is not expressive enough then it will be more
> > > difficult. 
> > > 
> > > > 
> > > > 
> > > > On Feb 6, 2019, at 8:30 AM, Burak Serdar <bser...@ieee.org>
> > > > wrote:
> > > > 
> > > > > 
> > > > > 
> > > > > On Wed, Feb 6, 2019 at 5:15 AM Robert Engels <reng...@ix.netc
> > > > > om.c
> > > > > om> wrote:
> > > > > 
> > > > > I see now, but if that can be the case, shouldn’t the Body be
> > > > > documented that the Reader may be a ReaderWithLen, and the
> > > > > consumer is free to type check/cast? If not, you are using
> > > > > internal details that you should not be.
> > > > Yes, the documentation should say if the reader has a Len()
> > > > method
> > > > it
> > > > would be used to set the ContentLength. Len is no longer an
> > > > internal
> > > > detail then.
> > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > > This is a problem with Go in general. Because the returned
> > > > > object
> > > > > “implements” some interface because it happens to have the
> > > > > required method, doesn’t mean it was designed to be used that
> > > > > way, or that it has the required semantics - unless
> > > > > documented to
> > > > > have them.
> > > > I agree with you there. Len() is straight forward, but in
> > > > general
> > > > just
> > > > because a function is named something doesn't mean it'll do the
> > > > same
> > > > thing for all implementations. On the other end of the spectrum
> > > > is
> > > > Java-like interfaces where you want explicit inheritance of a
> > > > specific
> > > > interface. I don't know if there's anything in between, but I
> > > > like
> > > > Go's approach much better.
> > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > > On Feb 6, 2019, at 2:22 AM, Matteo Biagetti <matteo.biagetti@
> > > > > gmai
> > > > > l.com> wrote:
> > > > > 
> > > > > Make sense, thanks for explanation
> > > > > 
> > > > > 
> > > > > 
> > > > > Il giorno mercoledì 6 febbraio 2019 07:28:54 UTC+1, Burak
> > > > > Serdar
> > > > > ha scritto:
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > On Tue, Feb 5, 2019 at 8:13 PM robert engels <ren...@ix.net
> > > > > > com.
> > > > > > com> wrote:
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > That’s what I was trying to point out. Your design is not
> > > > > > > correct. The Body is a Reader, not a Buffer - the length
> > > > > > > of
> > > > > > > the request/body may be indeterminate - that is, a
> > > > > > > stream.
> > > > > > > Attempting to get the length of an underlying buffer is
> > > > > > > not
> > > > > > > only probably not possible, but not correct in many
> > > > > > > situations.
> > > > > > The length of the body *may* be indeterminate, and if
> > > > > > that's
> > > > > > the case,
> > > > > > the underlying Reader will not have a Len method. The
> > > > > > design is
> > > > > > to
> > > > > > handle the case where the underlying Reader is a Buffer
> > > > > > with a
> > > > > > Len
> > > > > > method. If the Reader has Len, then the NopCloser derived
> > > > > > from
> > > > > > that
> > > > > > will also have a Len, and NewRequest can set the content
> > > > > > length. If
> > > > > > the Reader does not have Len, then the content length is
> > > > > > unknown.
> > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > There is a reason the Body is a ReaderCloser and not a
> > > > > > > buffer. It is part of the http specification.
> > > > > > > 
> > > > > > > On Feb 5, 2019, at 9:00 PM, Burak Serdar <bse...@ieee.org
> > > > > > > >
> > > > > > > wrote:
> > > > > > > 
> > > > > > > On Tue, Feb 5, 2019 at 7:00 PM Robert Engels <ren...@ix.n
> > > > > > > etco
> > > > > > > m.com> wrote:
> > > > > > > 
> > > > > > > 
> > > > > > > Shouldn’t you just be taking the content length from the
> > > > > > > header if forwarding the same body. There is no need for
> > > > > > > the
> > > > > > > length of the body.
> > > > > > > 
> > > > > > > 
> > > > > > > True. What I was suggesting is a fix for the general
> > > > > > > case.
> > > > > > > 
> > > > > > > 
> > > > > > > On Feb 5, 2019, at 6:53 PM, Burak Serdar <bse...@ieee.org
> > > > > > > >
> > > > > > > wrote:
> > > > > > > 
> > > > > > > On Tue, Feb 5, 2019 at 5:18 PM Dan Kortschak <d...@kortsc
> > > > > > > hak.
> > > > > > > io> wrote:
> > > > > > > 
> > > > > > > Personally, I think this is a bug in the behaviour of
> > > > > > > NewRequest. See h
> > > > > > > ttps://github.com/golang/go/issues/18117 for some
> > > > > > > additional
> > > > > > > context.
> > > > > > > 
> > > > > > > 
> > > > > > > Agreed. One solution could be to have:
> > > > > > > 
> > > > > > > type HasLen interface {
> > > > > > > int Len()
> > > > > > > }
> > > > > > > 
> > > > > > > Then have NopCloser return a nopCloser with len if the
> > > > > > > underlying
> > > > > > > implementation has len, with the obvious changes to
> > > > > > > NewRequest.Ugly,
> > > > > > > but can be done without API changes.
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > On Tue, 2019-02-05 at 05:18 -0800, matteo....@gmail.com
> > > > > > > wrote:
> > > > > > > I've the following situation:
> > > > > > > I proxy a request to another server and when I made a
> > > > > > > POST
> > > > > > > and create
> > > > > > > a new
> > > > > > > request, the contentLength is zero:
> > > > > > > 
> > > > > > >      req2, _ := http.NewRequest(req.Method, newApiUrl ,
> > > > > > > req.Body)
> > > > > > >      fmt.Println("New request from body:",
> > > > > > > req2.ContentLength) //
> > > > > > > print 0
> > > > > > > 
> > > > > > > Checking in the source code of the NewRequest func Body
> > > > > > > don't
> > > > > > > respect
> > > > > > > some
> > > > > > > interface and populate the ContentLength field.
> > > > > > > 
> > > > > > > Could be a bug? Which could be a valid approach in order
> > > > > > > to
> > > > > > > create a
> > > > > > > new
> > > > > > > request from an existing one and correct set the Body
> > > > > > > length?
> > > > > > > 
> > > > > > > A working example here:
> > > > > > > 
> > > > > > > https://play.golang.org/p/SvCDLj0NrXb
> > > > > > > 
> > > > > > > Thanks!
> > > > > > > 
> > > > > > > 
> > > > > > > --
> > > > > > > You received this message because you are subscribed to
> > > > > > > the
> > > > > > > Google Groups "golang-nuts" group.
> > > > > > > To unsubscribe from this group and stop receiving emails
> > > > > > > from
> > > > > > > it, send an email to golang-nuts...@googlegroups.com.
> > > > > > > For more options, visit https://groups.google.com/d/optou
> > > > > > > t.
> > > > > > > 
> > > > > > > 
> > > > > > > --
> > > > > > > You received this message because you are subscribed to
> > > > > > > the
> > > > > > > Google Groups "golang-nuts" group.
> > > > > > > To unsubscribe from this group and stop receiving emails
> > > > > > > from
> > > > > > > it, send an email to golang-nuts...@googlegroups.com.
> > > > > > > For more options, visit https://groups.google.com/d/optou
> > > > > > > t.
> > > > > > > 
> > > > > > > 
> > > > > > > --
> > > > > > > You received this message because you are subscribed to
> > > > > > > the
> > > > > > > Google Groups "golang-nuts" group.
> > > > > > > To unsubscribe from this group and stop receiving emails
> > > > > > > from
> > > > > > > it, send an email to golang-nuts...@googlegroups.com.
> > > > > > > For more options, visit https://groups.google.com/d/optou
> > > > > > > t.
> > > > > > > 
> > > > > > > 
> > > > > > > --
> > > > > > > You received this message because you are subscribed to
> > > > > > > the
> > > > > > > Google Groups "golang-nuts" group.
> > > > > > > To unsubscribe from this group and stop receiving emails
> > > > > > > from
> > > > > > > it, send an email to golang-nuts...@googlegroups.com.
> > > > > > > For more options, visit https://groups.google.com/d/optou
> > > > > > > t.
> > > > > > > 
> > > > > > > 
> > > > > --
> > > > > You received this message because you are subscribed to the
> > > > > Google Groups "golang-nuts" group.
> > > > > To unsubscribe from this group and stop receiving emails from
> > > > > it,
> > > > > send an email to golang-nuts+unsubscr...@googlegroups.com.
> > > > > For more options, visit https://groups.google.com/d/optout.
> > > > > 
> > > > > --
> > > > > You received this message because you are subscribed to the
> > > > > Google Groups "golang-nuts" group.
> > > > > To unsubscribe from this group and stop receiving emails from
> > > > > it,
> > > > > send an email to golang-nuts+unsubscr...@googlegroups.com.
> > > > > For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to