kuda.ai

Thoughts on programming and music theory.

How Form Submissions Are Represented In HTTP

Created on April 6, 2025
Updated on April 7, 2025
networking/http

When you look at what arrives at the server over the wire (HTTP is just plain text, no special wire-format) in HTTP form submissions, it looks something like this:

POST /admin/login HTTP/1.1
Host: localhost:8873
Connection: keep-alive
Content-Length: 41
Content-Type: application/x-www-form-urlencoded
Origin: http://localhost:8873
[... a bunch of additional headers]
email=david%40gmail.com&password=abc

You notice that it’s a string (or []byte) after the headers where each special character is url-encoded and each field is divided by an &.

How to work with form submissions in Go

In Golang, you call err := r.ParseForm() which iterates the form submission and parses it into a map (r.PostForm). Once that’s done, you can access the form data with r.PostForm.Get("email").

In the HTML, you need to define the name="name" property in each form field, see for instance this login form (notice the <input> tags):

<h3>Login:</h3>
<form action="/admin/login" method="post">
  <fieldset>
    <label>email:
      <input type="email" name="email">
    </label>
    <label>password:
      <input type="password" name="password">
    </label>
  </fieldset>
  <button type="submit">
    Login
  </button>
</form>

And here is a snippet how you can work with it in Go:

func (app *application) adminLoginPost(w http.ResponseWriter, r *http.Request) {

	type userLoginForm struct {
		email    string
		password string
	}

	// Here, you call r.ParseForm()
	// This will take the data from the POST request
	// (email=david%40gmail.com&password=pa55word)
	// and make it available in r.PostForm as a map. (see below)
	err := r.ParseForm()
	if err != nil {
		log.Printf("Failed parsing form: %v", err)
		http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
		return
	}

	// Here, email and password are available from r.PostForm:
	form := userLoginForm{
		email:    r.PostForm.Get("email"),
		password: r.PostForm.Get("password"),
	}
    ...
}