I agree that this is a brittle API and it's one that has bitten us
twice (partly because - I beleive - the dev_appserver.py development
server is broken in how it deals with the cases here. This is why I
filed an issue - though not with great hope of a fix other than maybe
improving the documentation.

On Thu, 2019-02-07 at 16:10 -0600, robert engels wrote:
> So GetBody just fails… It returns NoBody in this case.. which means
> calling code will just break (when the original request is not one of
> the known types).
> 
> So, according to the referenced issue, 307/308 redirects won’t work
> when the underlying request is not a known type.
> 
> This is a very brittle API IMO. If you need to do stuff like this,
> the readers should be using mark/reset etc with buffered streams, not
> relying on special cased functions like GetBody that don’t work in
> all cases.
> 
> > 
> > On Feb 7, 2019, at 3:42 PM, Dan Kortschak <d...@kortschak.io> wrote:
> > 
> > Keeping a zeroed state is important for the GetBody func because
> > the
> > io.ReadCloser returned by GetBody can be read and closed. If there
> > is
> > no zero state for the next time GetBody is called, it is not
> > idempotent. This would break the whole point of it existing.
> > 
> > See https://go-review.googlesource.com/c/go/+/31733/
> > 
> > On Thu, 2019-02-07 at 15:33 -0600, robert engels wrote:
> > > 
> > > I agree with you on the correct solution - vs. the OP’s request
> > > of
> > > the GetWrappedXXXX method.
> > > 
> > > I guess I still don’t understand the “zeroed” concern though. If
> > > you
> > > adhere to the “don’t mutate values…” then why do the zero copy at
> > > all
> > > ? The state of the body should still be the state it was passed
> > > in as
> > > (unless the caller was breaking the aforementioned rule anyway…).
> > > 
> > > Having “blessed types” is not a good design IMO - better to just
> > > declare the required interfaces and use those - especially when
> > > the
> > > object being provided as a parameter is already an interface…
> > > just
> > > seems lazy… (and long-term error prone).
> > > 
> > > 
> > > 
> > > > 
> > > > 
> > > > On Feb 7, 2019, at 3:05 PM, Dan Kortschak <d...@kortschak.io>
> > > > wrote:
> > > > 
> > > > Their is an assumption in the code that users don't mutate
> > > > values
> > > > under
> > > > the feet of routines that have been called. The copy does not
> > > > protect
> > > > against that and is not designed for that purpose; it is there
> > > > to
> > > > make
> > > > the GetBody function return a zeroed copy of the body (for some
> > > > definition of zeroed - zero is the state that was handed in to
> > > > the
> > > > NewRequest call). If the behaviour of the copy here is broken,
> > > > any
> > > > Go
> > > > code that causes a slice, map or pointer to be retained is
> > > > broken
> > > > since
> > > > the user can mutate the backing data after the call has done
> > > > work
> > > > on
> > > > it. This becomes a philosophical point.
> > > > 
> > > > There is a simple work around (not as simple as having
> > > > NewRequest
> > > > Just
> > > > Do The Right Thing™, but reasonable) that does not require
> > > > reflect
> > > > and
> > > > puts the control in the users' hands. Since the ContentLength
> > > > and
> > > > GetBody fields are exported, they can be set after the return
> > > > of
> > > > NewRequest in the same way that NewRequest does for the blessed
> > > > types,
> > > > but with the users' knowledge of internal behaviours of their
> > > > types.
> > > > 
> > > > An example of this is here https://bitbucket.org/ausocean/iot/p
> > > > ull-
> > > > requ
> > > > ests/42
> > > > 
> > > > On Thu, 2019-02-07 at 14:55 -0600, robert engels wrote:
> > > > > 
> > > > > 
> > > > > I see the documented use of the types in NewRequest - you are
> > > > > correct
> > > > > - I was wrong.
> > > > > 
> > > > > But, it could of easily also declared that if the provided
> > > > > Reader
> > > > > is
> > > > > also a Lener, it uses it to determine the content length. Why
> > > > > have
> > > > > this behavior for Closer and not for Lener? Then you don’t
> > > > > need
> > > > > the
> > > > > type switch. You say, well the copy...
> > > > > 
> > > > > The current code with the copy is broken - the caller could
> > > > > continue
> > > > > to modify the contents of the bytes.Buffer and things would
> > > > > not
> > > > > work
> > > > > as expected since the backing array of the slice is shared -
> > > > > so
> > > > > how
> > > > > is the copy helping ? The length will remain the same, but
> > > > > the
> > > > > data
> > > > > represented could be corrupted.
> > > > > 
> > > > > The correct solution is to declare that NewRequest takes an
> > > > > interface
> > > > > Content, that has both Reader and ContentLength methods,
> > > > > where
> > > > > ContentLength() can return -1 if the content length is
> > > > > indeterminate.
> > > > > Then declare simple facades for Content from bytes.Buffer, a
> > > > > string,
> > > > > etc. And also declare that continued use of the Content after
> > > > > NewRequest is undefined. And if you wanted to retain the
> > > > > simplicity,
> > > > > just declare it uses ContentLength like it uses Closer.
> > > > > 
> > > > > I am all for the simplicity of Go, but “solutions" like
> > > > > NewRequest
> > > > > are not the way modern software should be developed. Casting
> > > > > an
> > > > > interface to a concrete type is a sign of code that needs
> > > > > design
> > > > > work. Having to read the doc in addition to the method
> > > > > signature
> > > > > is
> > > > > also a sign the interface needs work (primarily since changes
> > > > > to
> > > > > the
> > > > > doc can/will/might change behavior but it avoids compile time
> > > > > type
> > > > > checking = brittle code with obscure bugs).
> > > > > 
> > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > On Feb 7, 2019, at 1:56 PM, Dan Kortschak <d...@kortschak.io
> > > > > > >
> > > > > > wrote:
> > > > > > 
> > > > > > 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 <dan@kortscha
> > > > > > > > k.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 <dan@kort
> > > > > > > > > > scha
> > > > > > > > > > k.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 <dan@
> > > > > > > > > > > > kort
> > > > > > > > > > > > scha
> > > > > > > > > > > > k.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
> > > > > > > > > > > > > > <bserd
> > > > > > > > > > > > > > ar@i
> > > > > > > > > > > > > > eee.
> > > > > > > > > > > > > > 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/18
> > > > > > > > > > > > > > > > > 117
> > > > > > > > > > > > > > > > > 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...@g
> > > > > > > > > > > > > > > > > oogl
> > > > > > > > > > > > > > > > > egro
> > > > > > > > > > > > > > > > > ups.
> > > > > > > > > > > > > > > > > com.
> > > > > > > > > > > > > > > > > For more options, visit https://group
> > > > > > > > > > > > > > > > > s.go
> > > > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > > > .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...@g
> > > > > > > > > > > > > > > > > oogl
> > > > > > > > > > > > > > > > > egro
> > > > > > > > > > > > > > > > > ups.
> > > > > > > > > > > > > > > > > com.
> > > > > > > > > > > > > > > > > For more options, visit https://group
> > > > > > > > > > > > > > > > > s.go
> > > > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > > > .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...@g
> > > > > > > > > > > > > > > > > oogl
> > > > > > > > > > > > > > > > > egro
> > > > > > > > > > > > > > > > > ups.
> > > > > > > > > > > > > > > > > com.
> > > > > > > > > > > > > > > > > For more options, visit https://group
> > > > > > > > > > > > > > > > > s.go
> > > > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > > > .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...@g
> > > > > > > > > > > > > > > > > oogl
> > > > > > > > > > > > > > > > > egro
> > > > > > > > > > > > > > > > > ups.
> > > > > > > > > > > > > > > > > com.
> > > > > > > > > > > > > > > > > For more options, visit https://group
> > > > > > > > > > > > > > > > > s.go
> > > > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > > > .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@
> > > > > > > > > > > > > > > goog
> > > > > > > > > > > > > > > legr
> > > > > > > > > > > > > > > oups
> > > > > > > > > > > > > > > .com
> > > > > > > > > > > > > > > .
> > > > > > > > > > > > > > > For more options, visit https://groups.go
> > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > .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@
> > > > > > > > > > > > > > > goog
> > > > > > > > > > > > > > > legr
> > > > > > > > > > > > > > > oups
> > > > > > > > > > > > > > > .com
> > > > > > > > > > > > > > > .
> > > > > > > > > > > > > > > For more options, visit https://groups.go
> > > > > > > > > > > > > > > ogle
> > > > > > > > > > > > > > > .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.

Reply via email to