How to save remote IP address in Postgres with Go?

894 views Asked by At

I am trying to save incoming request's remote IP address into Postgres. I am using chi and sqlc.

Here's the migration:

CREATE TABLE IF NOT EXISTS ips (
    id bigserial PRIMARY KEY,
    ip INET
);

And this is the insert query:

-- name: CreateIp :one
INSERT INTO ips (
    ip
) VALUES (
    $1
) RETURNING *;

This is the struct for params:

type CreateIpParams struct {
    Ip        net.IP         `json:"ip"`
}

Get the IP and parse it:

...

    // Get IP from RemoteAddr
    ip, _, _ := net.SplitHostPort(r.RemoteAddr)
    log.Println(" >> ip:", reflect.ValueOf(ip)) // ::1
    log.Println(" >> ip.TypeOf:", reflect.TypeOf(ip)) // string

    if netIp := net.ParseIP(ip); netIp != nil {
        params.Ip = netIp
        log.Println(" >> netIp:", reflect.ValueOf(netIp)) // ::1
        log.Println(" >> netIp.TypeOf:", reflect.TypeOf(netIp)) // net.IP
    }

...

When I made a POST request, it returns:

    "error": "pq: invalid byte sequence for encoding \"UTF8\": 0x00"

If I removed the that code block without saving ip at all:

    "error": "pq: invalid input syntax for type inet: \"\""

I tried trimming the ip with strings.TrimSpace(ip) but doesn't help.

Code with sqlc save.

...
    params := &db.CreateIpParams{}

    // Get IP from RemoteAddr
    ip, _, _ := net.SplitHostPort(r.RemoteAddr)
    if netIp := net.ParseIP(ip); netIp != nil {
        params.Ip = netIp
    }

    if _, err := db.NewPg(pg).CreateIp(context.Background(), *params); err != nil {
        render.Render(w, r, ErrRender(err))
        return
    }

CreateIp code and Ip struct:

// db/user.sql.go

func (q *Queries) CreateIp(ctx context.Context, arg CreateIpParams) (Ip, error) {
    row := q.queryRow(ctx, q.createIpStmt, createIp,
        arg.Ip,
    )
    var i Ip
    err := row.Scan(
        &i.Ip,
    )
    return i, err
}

// db/models.go

type Ip struct {
    ID         int64          `json:"id"`
    Ip         net.IP         `json:"ip"`
}
0

There are 0 answers