# How To Setup HTTPS on Go Web Server

# Overview
HTTPS (Hypertext Transfer Protocol Secure) is an extension of HTTP. It extends HTTP to give more security by implementing SSL/TLS to encrypt the connection between client and server. Because of that, HTTPS is often referred to as HTTP over SSL/TSL. HTTPS implementation on a web service makes the system more resilient to web attacks such as man-in-the-middle-attack. By default, HTTPS listen to port 443 instead of port 80 of HTTP. 
# Problem
Here is the code used to build a simple web server written in Go. This web server has only 1 endpoint and listens to port 8081.
```go
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {

	http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "{message: 'Hello Secure World'}")
	})

	log.Fatal(http.ListenAndServe(":8081", nil))

}
```
Let's analyze the packet on Wireshark to see how the packet is transmitted. As a testing ground, I will use the curl command to send HTTP GET requests to go web server. 
```bash
curl http://localhost:8081/hi
```
Here is the screenshot of the packet capture from Wireshark.
![Screenshot_20220107_174144.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641552673321/nZDkpyuuL.png)
As you can see, the payload is clearly shown up at the packet capture. This is a serious issue as someone can tap into your connection and know what kind of data you sent and received.
# Solution
Let's encrypt our connection using HTTPS. But first, we need to generate some files using this command:
```bash
go run $(go env GOROOT)/src/crypto/tls/generate_cert.go --host=localhost
```
In the go code, you need to change `http.ListenAndServe` to `http.ListenAndServeTLS` in order to use the https.
```go
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {

	http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "{message: 'Hello Secure World'}")
	})

	err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	log.Printf("Web server works")
}

```
# Result
Test the following code using the curl command
```bash
# as we self-sign the certificate, our certificate can't be trusted
# worry not, the TLS still applies to our connection
curl -k https://localhost:8443/hi
```
This is the screenshot from Wireshark where we capture the packet.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641559063918/2C8z7kJbv.png)

As you can see, the connection now has been encrypted using TLS.

Thank you, I hope you find this article useful.







