client.go
func (c *Client) PostForm(ctx context.Context, endpoint string, vals url.Values, files ...File) (*Response, error) {
	// If the sanitizer is enabled, make sure the requested path is safe.
	if c.sanitizerEnabled {
		err := isPathSafe(endpoint)
		if err != nil {
			return nil, err
		}
	}

	return c.RoundTrip(func() (*http.Response, error) {
		if len(files) == 0 {
			req, err := http.NewRequest(http.MethodPost, endpoint, strings.NewReader(vals.Encode()))
			if err != nil {
				return nil, err
			}
			req = req.WithContext(ctx)
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			c.addAuth(req)
			return c.client.Do(req)
		}

		var buf bytes.Buffer
		buf.Grow(bufferSize)

		// Cache file reads in case we reach the memory limit
		// and need to rewind
		buffers := newBuffersFromFiles(files)
		writer := multipart.NewWriter(&limitWriter{&buf, bufferSize})
		err := writeForm(writer, vals, buffers...)
		writer.Close()
		if err != nil && err != errShortWrite {
			return nil, err
		}

		if err == errShortWrite {
			// Switch to io.Pipe as the data is larger than the memory limit
			for i := range buffers {
				buffers[i].rewind()
			}
			return c.writeWithPipe(endpoint, vals, buffers...)
		}

		req, err := http.NewRequest(http.MethodPost, endpoint, &buf)
		if err != nil {
			return nil, err
		}
		req = req.WithContext(ctx)
		req.Header.Set("Content-Type",
			fmt.Sprintf(`multipart/form-data;boundary="%v"`, writer.Boundary()))
		c.addAuth(req)
		return c.client.Do(req)
	})
}
func (c *Client) PostForm(ctx context.Context, endpoint string, vals url.Values, files ...File) (*Response, error) {
	// If the sanitizer is enabled, make sure the requested path is safe.
	if c.sanitizerEnabled {
		err := isPathSafe(endpoint)
		if err != nil {
			return nil, err
		}
	}

	return c.RoundTrip(func() (*http.Response, error) {
		if len(files) == 0 {
			req, err := http.NewRequest(http.MethodPost, endpoint, strings.NewReader(vals.Encode()))
			if err != nil {
				return nil, err
			}
			req = req.WithContext(ctx)
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
			c.addAuth(req)
			return c.client.Do(req)
		}

		var buf bytes.Buffer
		buf.Grow(bufferSize)

		// Cache file reads in case we reach the memory limit
		// and need to rewind
		buffers := newBuffersFromFiles(files)
		writer := multipart.NewWriter(&limitWriter{&buf, bufferSize})
		err := writeForm(writer, vals, buffers...)
		writer.Close()
		if err != nil && err != errShortWrite {
			return nil, err
		}

		if err == errShortWrite {
			// Switch to io.Pipe as the data is larger than the memory limit
			for i := range buffers {
				buffers[i].rewind()
			}
			return c.writeWithPipe(endpoint, vals, buffers...)
		}

		req, err := http.NewRequest(http.MethodPost, endpoint, &buf)
		if err != nil {
			return nil, err
		}
		req = req.WithContext(ctx)
		req.Header.Set("Content-Type",
			fmt.Sprintf(`multipart/form-data;boundary="%v"`, writer.Boundary()))
		c.addAuth(req)
		return c.client.Do(req)
	})
}
// PostForm posts urlencoded form with values and returns the result
//
// c.PostForm(c.Endpoint("users"), url.Values{"name": []string{"John"}})
//