Redirect from one page to another not working

542 Views Asked by At

I am trying to Insert the scan results using the Scan func and once done I want to redirect to show results which are nothing but a select query to the inserts done ever. Both functions are working properly when tested separately. Is this not the correct way to redirect from the first page to the next?

package main

import (
    "bytes"
    "database/sql"
    "fmt"
    "html/template"
    "log"
    "net/http"
    "os/exec"
    "regexp"
    "strconv"
    "strings"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

func dbConn() (db *sql.DB) {
    dbDriver := "mysql"
    dbUser := "root"
    dbPass := "root"
    dbName := "test"
    db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName+"?parseTime=true")
    if err != nil {
        log.Fatal(err)
    }
    return db
}

var tmpl = template.Must(template.ParseGlob("form/*"))
var hostnameInput string

func main() {

    http.HandleFunc("/login", login)
    http.HandleFunc("/show", Show)

    lerr := http.ListenAndServe(":9090", nil) // setting listening port
    if lerr != nil {
        log.Fatal("ListenAndServe: ", lerr)
    }

}

func Insert(hostname string, ports []int) {
    db := dbConn()

    // INSERT INTO DB
    // prepare
    stmt, e := db.Prepare("insert into nmap_reports(reported_at,  host_address) values ( ?, ?)")
    if e != nil {
        log.Fatal(e)
    }

    //execute
    res, er := stmt.Exec(time.Now(), hostname)
    if er != nil {
        log.Fatal(er)
    }

    for _, v := range ports {
        insForm, err := db.Prepare("INSERT INTO nmap_report_ports(nmap_report_id,port) VALUES (?,?)")
        if err != nil {
            log.Fatal(err)
        }
        id, fail := res.LastInsertId()
        if fail != nil {
            log.Fatal(fail)
        }
        _, er := insForm.Exec(id, v)
        if er != nil {
            log.Fatal(er)
        }
    }
    defer db.Close()
}
func Select(hostname string) []Result {
    db := dbConn()

    // query all data
    stmt, err := db.Prepare("SELECT nm.nmap_report_id, nm.host_address,nm.reported_at,GROUP_CONCAT(port) AS `Ports` FROM nmap_reports nm left join  nmap_report_ports nrp on nm.nmap_report_id = nrp.nmap_report_id where nm.host_address = ? group by nm.nmap_report_id order by nmap_report_id desc")
    if err != nil {
        log.Fatal(err)
    }
    rows, er := stmt.Query(hostname)
    if er != nil {
        log.Fatal(er)
    }

    // declare empty result variable
    var resultI = Result{}

    // iterate over rows
    resultSet := make([]Result, 0)
    for rows.Next() {
        e := rows.Scan(&resultI.ReportId, &resultI.Hostname, &resultI.Date, &resultI.Ports)
        if e != nil {
            log.Fatal(er)
        }
        resultSet = append(resultSet, resultI)
    }
    defer db.Close()
    return resultSet
}

type Result struct {
    ReportId int       `json:"reportId"`
    Hostname string    `json:"hostname"`
    Date     time.Time `json:"date"`
    Ports    string    `json:"ports"`
}

func Show(w http.ResponseWriter, r *http.Request) {

    data := Select(hostnameInput)
    temp, temperr := template.ParseFiles("form/show.tmpl")
    if temperr != nil {
        log.Fatal(temperr)
    }

    temp.ExecuteTemplate(w, "show", data)

}

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //get request method
    if r.Method == "GET" {
        t, _ := template.ParseFiles("form/input.tmpl")
        t.Execute(w, nil)
    } else {
        //if r.Method == "POST" {
        r.ParseForm()

        fmt.Println("hostname:", r.Form["hname"])

        var rxHostIP = regexp.MustCompile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)+([A-Za-z]|[A-Za-z][A-Za-z0-9\\-]*[A-Za-z0-9])$")
        hostnameInput = strings.Join(r.Form["hname"], "")
        fmt.Println("hnmae is:" + hostnameInput)
        if !rxHostIP.MatchString(hostnameInput) {
            w.WriteHeader(400)
            w.Write([]byte("Invalid Ip/hostname"))
        }

        command := []string{"nmap", "-p", "1-1000"}
        command = append(command, r.Form["hname"]...)
        finalcommand := strings.Join(command, " ")
        fmt.Println(finalcommand)
        cmd := exec.Command(`C:\Windows\System32\cmd.exe`, "/c", finalcommand)
        cmdOutput := &bytes.Buffer{}
        cmd.Stdout = cmdOutput

        err := cmd.Run()
        if err != nil {
            log.Fatal(err)
        }
        check := string(cmdOutput.Bytes())

        re := regexp.MustCompile(`([0-9]+)./`)

        stringArr := re.FindAllString(check, -1)

        intArr := make([]int, 0)

        for _, v := range stringArr {
            n := strings.Replace(v, "/", "", -1)

            i, cerr := strconv.Atoi(n)
            if cerr != nil {
                log.Fatal(cerr)
            }
            intArr = append(intArr, i)
        }

        Insert(hostnameInput, intArr)
    }
    http.Redirect(w, r, "/show", 301)
}

Trying to redirect from login page to show page using

http.Redirect(w, r, "/show", 301)
1

There are 1 best solutions below

0
On

I think the redirect code is fine. There might be something going inside the login handler that prevents the redirect from happening.

I've annotated and modified some parts of the login handler below, if it might be helpful to you.

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //get request method
    if r.Method == "GET" {
        // note#1: don't ignore the error
        t, err := template.ParseFiles("form/input.tmpl")
        if err != nil {
            log.Fatal(err)
        }

        // note#2: check the error
        err = t.Execute(w, nil)
        if err != nil {
            log.Fatal(err)
        }
    } else {
        var err error
        // note#3: check the error
        err = r.ParseForm()
        if err != nil {
            log.Fatal(err)
        }

        // ...
        // other code, omitted for brevity
        // ...
    }

    // note#4: this is fine if you intend to redirect all the request,
    // regardless of the method, to the `/show` endpoint
    http.Redirect(w, r, "/show", 301)
}