I didn't mention the word internal, nor did I imply it; with documentation stating that it would be used, it is clearly *not* internal.
If you look at the code in question, you can see a probable reason why a Lener interface is not used; for each of the blessed types, a concrete copy of the pointed-to-value is made to allow GetBody to return it. This cannot be done with an interface value without the use of reflect. Please show me a Len method in the standard library that does not return the number of available-to-access elements in a collection. On Thu, 2019-02-07 at 13:27 -0600, robert engels wrote: > I am not following. You stated that the usage of Len was internal and > a type switch on known concrete types, so how is related to how the > OP was attempting to have things work? > > There is no “generally accepted use of Len()”, otherwise it would not > need to perform a type switch on known concrete types - it would cast > to an interface declaring Len(), and use the interface, and then it > would work with any type. > > > > > On Feb 7, 2019, at 1:07 PM, Dan Kortschak <d...@kortschak.io> wrote: > > > > Yeah, I'm not agreeing with you. > > > > On Thu, 2019-02-07 at 07:07 -0600, Robert Engels wrote: > > > > > > You are agreeing with me. A type switch on concrete types (that > > > you > > > control) is far different than using an available Len() method > > > and > > > assuming the same semantics. > > > > > > > > > > > > > > > On Feb 7, 2019, at 1:05 AM, Dan Kortschak <d...@kortschak.io> > > > > wrote: > > > > > > > > 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 <bserdar@ieee. > > > > > > > > org> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Wed, Feb 6, 2019 at 5:15 AM Robert Engels <rengels > > > > > > > > > @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.. > > > > > > > > > > > .@ko > > > > > > > > > > > rtsc > > > > > > > > > > > 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....@gma > > > > > > > > > > > il.c > > > > > > > > > > > om > > > > > > > > > > > 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/o > > > > > > > > > > > ptou > > > > > > > > > > > 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/o > > > > > > > > > > > ptou > > > > > > > > > > > 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/o > > > > > > > > > > > ptou > > > > > > > > > > > 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/o > > > > > > > > > > > ptou > > > > > > > > > > > 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+unsubscribe@googlegroups > > > > > > > > > .com > > > > > > > > > . > > > > > > > > > For more options, visit https://groups.google.com/d/o > > > > > > > > > ptou > > > > > > > > > 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+unsubscribe@googlegroups > > > > > > > > > .com > > > > > > > > > . > > > > > > > > > For more options, visit https://groups.google.com/d/o > > > > > > > > > ptou > > > > > > > > > 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.