Skip to content

Instantly share code, notes, and snippets.

@patrickmn
Created December 27, 2011 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickmn/1524739 to your computer and use it in GitHub Desktop.
Save patrickmn/1524739 to your computer and use it in GitHub Desktop.
Demonstration of Golang weekly.2011-12-22 exp/sql + gopgsqldriver Keep-Alive DoS: *db.Query Rows.Close() is not automatic
package main
// Demonstration of Golang weekly.2011-12-22 exp/sql + gopgsqldriver
// Keep-Alive DoS: *db.Query Rows.Close() is not automatic
import (
"encoding/json"
"exp/sql"
"fmt"
"net/http"
"os"
_ "github.com/jbarham/pgsqldriver"
)
var (
db *sql.DB
checkError = func(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
html = `
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
function poll(interval) {
$.ajax({
url: "http://localhost:9000/",
data: {
name: "Patrick",
},
success: function(food) {
$("div#wholikes").append("<p>Patrick likes "+food+"</p>");
},
});
setTimeout(function() {poll(interval);}, interval);
};
$(document).ready(function() {
poll(20);
});
</script>
</head>
<body>
<div id="wholikes"></div>
</body>
</html>
`
reqCount = 0
)
// # sudo -u postgres psql postgres
// -- DB SQL
// CREATE USER godos;
// ALTER USER godos WITH PASSWORD 'godos';
// CREATE DATABASE godos
// WITH OWNER = godos
// ENCODING = 'UTF8'
// TABLESPACE = pg_default
// LC_COLLATE = 'en_US.UTF-8'
// LC_CTYPE = 'en_US.UTF-8'
// CONNECTION LIMIT = -1;
// GRANT ALL PRIVILEGES ON DATABASE godos TO godos;
func main() {
db, _ = sql.Open("postgres", "host=localhost dbname=godos user=godos password=godos")
db.Exec("DROP TABLE favfood")
db.Exec("CREATE TABLE favfood(name VARCHAR(64), food VARCHAR(64))")
db.Exec("INSERT INTO favfood(name, food) VALUES('Patrick', 'Eggs')")
db.Exec("INSERT INTO favfood(name, food) VALUES('Patrick', 'Bacon')")
http.Handle("/", http.HandlerFunc(Page))
http.ListenAndServe(":9000", nil)
}
func Page(w http.ResponseWriter, req *http.Request) {
// w.Header()["Connection"] = []string{"Close"} // Workaround: This closes the idle DB conn
reqCount++
fmt.Println("Request", reqCount)
name := req.FormValue("name")
if name != "" {
foods := GetFoods(name)
data, _ := json.Marshal(foods)
w.Write(data)
} else {
fmt.Fprint(w, html)
}
}
func GetFoods(name string) []string {
var foods []string
rows, err := db.Query("SELECT food FROM favfood WHERE name = $1", name)
checkError(err)
for rows.Next() {
var food string
err := rows.Scan(&food)
checkError(err)
foods = append(foods, food)
}
// rows.Close() // Should-be-automatic fix: This closes the idle DB conn
return foods
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment