On Wed, Feb 6, 2019 at 2:50 PM robert engels <reng...@ix.netcom.com> 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.
Len() cannot be part of Reader. Not all readers can support it. Len() can be a part of the implementation that can be set as Body. Currently, the http implementation is checking for known Reader implementations to figure out the length of data. That's a hack. Checking if the reader supports Len() would fix that without any API changes. > > > 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 <rengels@ix.netcom.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.netcom. > >>>>> 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.netco > >>>>>> 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...@kortschak. > >>>>>> 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/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...@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...@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...@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. > > -- > 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.