Created
December 27, 2011 18:41
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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