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/pull-
>>> 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 <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 <dan@kortscha
>>>>>>>>> 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/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...@googl
>>>>>>>>>>>>>>>> egro
>>>>>>>>>>>>>>>> ups.
>>>>>>>>>>>>>>>> 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...@googl
>>>>>>>>>>>>>>>> egro
>>>>>>>>>>>>>>>> ups.
>>>>>>>>>>>>>>>> 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...@googl
>>>>>>>>>>>>>>>> egro
>>>>>>>>>>>>>>>> ups.
>>>>>>>>>>>>>>>> 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...@googl
>>>>>>>>>>>>>>>> egro
>>>>>>>>>>>>>>>> ups.
>>>>>>>>>>>>>>>> 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.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@goog
>>>>>>>>>>>>>> legr
>>>>>>>>>>>>>> oups
>>>>>>>>>>>>>> .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.

Reply via email to