I am trying to learn systems programming. I was wondering how I could place a GET request for a URL without using any libraries like HTTP for the same. Any help would be much appreciated!
Asked
Active
Viewed 922 times
-1
-
1Your are basically asking on how to implement the HTTP protocol, which is a very broad question. There are actual standards for this, see RFC 7230 for HTTP/1.1. Which means you need to read the documentation in order to understand the protocol and then you need to implement this protocol on top of sockets. If you want to implement HTTPS without libraries too you also need to implement TLS yourself - which is even more complex than HTTP. To get an idea just have a look at the existing implementation of the protocol in Go, these are all open source. – Steffen Ullrich Oct 18 '20 at 21:20
-
You want to create an HTTP client by yourself from scratch? – Z. Kosanovic Oct 18 '20 at 21:21
1 Answers
4
It's surprisingly easy if you're using sockets directly; HTTP is a very simple protocol. Here's an HTTP GET (with HTTP 1.1) to a given host at port 80:
package main
import (
"fmt"
"io/ioutil"
"log"
"net"
"net/url"
"os"
)
func main() {
s := os.Args[1]
u, err := url.Parse(s)
if err != nil {
log.Fatal(err)
}
conn, err := net.Dial("tcp", u.Host+":80")
if err != nil {
log.Fatal(err)
}
rt := fmt.Sprintf("GET %v HTTP/1.1\r\n", u.Path)
rt += fmt.Sprintf("Host: %v\r\n", u.Host)
rt += fmt.Sprintf("Connection: close\r\n")
rt += fmt.Sprintf("\r\n")
_, err = conn.Write([]byte(rt))
if err != nil {
log.Fatal(err)
}
resp, err := ioutil.ReadAll(conn)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(resp))
conn.Close()
}
That said, the whole HTTP protocol has many different options and variants and takes a lot of time, effort and tuning to implement.
The Go source code is fairly approachable usually, so you could read the code of net/http
. There are also alternative HTTP packages implemented using lower layers, like https://github.com/valyala/fasthttp

Eli Bendersky
- 263,248
- 89
- 350
- 412
-
Thank you so much for your help! How do I get the error code or the response code from the whole response and even just the HTML? Is there a way to get this other than normal text parsing? – Aditya Gaikwad Oct 18 '20 at 22:36
-
@AdityaGaikwad: you just parse it from the first line in the response – Eli Bendersky Oct 18 '20 at 23:01
-
Thanks a lot again! If I use - var buf bytes.Buffer io.Copy(&buf, conn) and then check length of buf, it is not the same as length of resp. Could you tell me why that could be? And which would be the better or more accurate reading of number of bytes of response? – Aditya Gaikwad Oct 18 '20 at 23:30
-
@AdityaGaikwad: I'm not sure which code you're referring to, but this sounds like a completely separate question. `io.Copy` and `ioutil.ReadAll` both read until EOF, the difference is just how the data is returned / where it's written. – Eli Bendersky Oct 19 '20 at 13:59