Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang HTTPS/TLS POST client/server

Tags:

post

https

go

I have written a simple client/server in Go that will do an HTTP GET over TLS, but I'm trying to also make it capable of doing an HTTP POST over TLS.

In the example below index.html just contains the text hello, and the HTTP GET is working fine. I want the client to get the HTTP GET and write back, hello world to the server.

client

package main

import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
)

func main() {
    link := "https://10.0.0.1/static/index.html"

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    response, err := client.Get(link)
    if err != nil {
        fmt.Println(err)
    }
    defer response.Body.Close()

    content, _ := ioutil.ReadAll(response.Body)
    s := strings.TrimSpace(string(content))

    fmt.Println(s)

    // out := s + " world"      
    // Not working POST...
    // resp, err := client.Post(link, "text/plain", &out)

}

server

package main

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

func main() {
    http.HandleFunc("/static/", func (w http.ResponseWriter, r *http.Request) {
        fmt.Println("Got connection!")
        http.ServeFile(w, r, r.URL.Path[1:])
    })
    log.Fatal(http.ListenAndServeTLS(":443", "server.crt", "server.key", nil))
}

I also currently have nothing to handle the POST on the server side, but I just want it to print it out to the screen so when I run the client I will see the server print hello world.

How should I fix my client code to do a proper POST? And what should the corresponding server code look like to accept the POST? Any help would be appreciated, I'm having trouble finding HTTPS/TLS POST examples.

like image 472
vesche Avatar asked Oct 29 '22 18:10

vesche


1 Answers

You didn't share the error message, but I assume the client.Post call wasn't allowing a string as its third parameter, because it requires an io.Reader. Try this instead:

out := s + " world"     
resp, err := client.Post(link, "text/plain", bytes.NewBufferString(out))

On the server side, you already have the right code set up to handle the POST request. Just check the method:

http.HandleFunc("/static/", func (w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        // handle POST requests
    } else {
        // handle all other requests
    }
})

I noticed one other issue. Using index.html probably won't work here. http.ServeFile will redirect that path. See https://golang.org/pkg/net/http/#ServeFile:

As a special case, ServeFile redirects any request where r.URL.Path ends in "/index.html" to the same path, without the final "index.html". To avoid such redirects either modify the path or use ServeContent.

I'd suggest just using a different file name to avoid that issue.

like image 82
user94559 Avatar answered Nov 10 '22 01:11

user94559