golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
121.44k stars 17.4k forks source link

Proposal: Move http.Client into its own "net/httpc" pkg #25678

Closed VojtechVitek closed 6 years ago

VojtechVitek commented 6 years ago

Rationale: I don't want to pull in a complex server logic (HTTP & HTTP/2) into a code that is supposed to be a pure HTTP client, or when I just want to fetch some data from a remote server. Build speed and size of a final binary matters, especially for GopherJS & WASM target.

 import (
    "io"
    "log"
-   "net/http"
+   "net/httpc"
    "os"
 )

 func main() {
-   resp, err := http.Get("http://example.com/")
+   resp, err := httpc.Get("http://example.com/")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    if _, err := io.Copy(os.Stdout, resp.Body); err != nil {
        log.Fatal(err)
    }
 }

I guess we could use type aliases to keep "net/http" backward compatible:

package "http"

import (
    "net/httpc"
)

type Client = httpc.Client

var DefaultClient = &httpc.Client{}

Should this be a proposal for Go 2.0?

cc @bradfitz

davecheney commented 6 years ago

I am strongly opposed to this proposal.

The http package provides http things, in this case a client and a server. To move the client into its own package would change the name of that package from what it provides, to what it contained, a http client.

This is not a place where the limited number of breaking changes go2 affords should be spent.

On 1 Jun 2018, at 10:26, Vojtech Vitek notifications@github.com wrote:

Rationale: I don't want to pull in a complex server logic (HTTP & HTTP/2) into a code that is supposed to be a pure HTTP client, or when I just want to fetch some data from a remote server. Build speed and size of a final binary matters, especially for GopherJS & WASM target.

import ( "io" "log"

  • "net/http"
  • "net/httpc" "os" )

    func main() {

  • resp, err := http.Get("http://example.com/")
  • resp, err := httpc.Get("http://example.com/") if err != nil { log.Fatal(err) } defer resp.Body.Close()

    if _, err := io.Copy(os.Stdout, resp.Body); err != nil { log.Fatal(err) } } I guess we could use type aliases to keep "net/http" backward compatible:

package "http"

import ( "net/httpc" )

type Client = httpc.Client

var DefaultClient = &httpc.Client{} Should this be a proposal for Go 2.0?

cc @bradfitz

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ianlancetaylor commented 6 years ago

Thanks. The place to discuss any Go 2 changes to net/http is issue #5465. Closing this issue in favor of that one.

bradfitz commented 6 years ago

I don't want to pull in a complex server logic (HTTP & HTTP/2) into a code that is supposed to be a pure HTTP client, or when I just want to fetch some data from a remote server. Build speed and size of a final binary matters, especially for GopherJS & WASM target.

That's a bug in GopherJS, then.

We have an explicit test that using http.Client in a binary doesn't link in http.Server. The linker is smart enough to discard the unused bits.

(We used to have this problem in cmd/go years ago, but the bug doesn't return because we have a test.)

Confirmed:

bradfitz@gdev:~$ go tool nm ./go/bin/go | grep Client | grep http | wc -l
60
bradfitz@gdev:~$ go tool nm ./go/bin/go | grep Client | grep net/http | wc -l
59
bradfitz@gdev:~$ go tool nm ./go/bin/go | grep Server | grep net/http | wc -l
5
bradfitz@gdev:~$ go tool nm ./go/bin/go | grep Server | grep net/http
  948180 R go.itab.net/http.transportReadFromServerError,error
  7983f0 T net/http.(*transportReadFromServerError).Error
  c20860 D net/http.ErrServerClosed
  c20960 D net/http.errServerClosedIdle
  780780 T net/http.transportReadFromServerError.Error

Likewise, wasm should also not have this problem, since it uses the main toolchain.

Sounds like this is really a GopherJS bug.

myitcv commented 6 years ago

@VojtechVitek please raise an issue over at https://github.com/gopherjs/gopherjs/issues if there is something to discuss GopherJS-wise. Happy to help.