import "net/http"\r
import "os"\r
import "strings"\r
+import "time"\r
import _ "github.com/mattn/go-sqlite3"\r
\r
// HTML templates\r
func main() {\r
port := flag.Int("port", 6543, "Default port on which to accept requests")\r
url := flag.String("url", "http://localhost:6543/stats/submit", "URL to send POST requests against")\r
- flag.Usage = usage\r
+ flag.Usage = usage\r
flag.Parse()\r
\r
if len(flag.Args()) < 1 {\r
// override the default Usage function to show the different "commands"\r
// that are in the switch statement in main()\r
func usage() {\r
- fmt.Fprintf(os.Stderr, "Usage of xs_interceptor:\n")\r
- fmt.Fprintf(os.Stderr, " xs_interceptor [options] <command>\n\n")\r
- fmt.Fprintf(os.Stderr, "Where <command> is one of the following:\n")\r
- fmt.Fprintf(os.Stderr, " create - create the requests db (sqlite3 db file)\n")\r
- fmt.Fprintf(os.Stderr, " drop - remove the requests db\n")\r
- fmt.Fprintf(os.Stderr, " list - lists the requests in the db\n")\r
- fmt.Fprintf(os.Stderr, " serve - listens for stats requests, storing them if found\n")\r
- fmt.Fprintf(os.Stderr, " resubmit - resubmits the requests to another URL\n\n")\r
- fmt.Fprintf(os.Stderr, "Where [options] is one or more of the following:\n")\r
- fmt.Fprintf(os.Stderr, " -port - port number (int) to listen on for 'serve' command\n")\r
- fmt.Fprintf(os.Stderr, " -url - url (string) to submit requests\n\n")\r
+ fmt.Fprintf(os.Stderr, "Usage of xs_interceptor:\n")\r
+ fmt.Fprintf(os.Stderr, " xs_interceptor [options] <command>\n\n")\r
+ fmt.Fprintf(os.Stderr, "Where <command> is one of the following:\n")\r
+ fmt.Fprintf(os.Stderr, " create - create the requests db (sqlite3 db file)\n")\r
+ fmt.Fprintf(os.Stderr, " drop - remove the requests db\n")\r
+ fmt.Fprintf(os.Stderr, " list - lists the requests in the db\n")\r
+ fmt.Fprintf(os.Stderr, " serve - listens for stats requests, storing them if found\n")\r
+ fmt.Fprintf(os.Stderr, " resubmit - resubmits the requests to another URL\n\n")\r
+ fmt.Fprintf(os.Stderr, "Where [options] is one or more of the following:\n")\r
+ fmt.Fprintf(os.Stderr, " -port - port number (int) to listen on for 'serve' command\n")\r
+ fmt.Fprintf(os.Stderr, " -url - url (string) to submit requests\n\n")\r
}\r
\r
// removes the requests database. it is just a file, so this is really easy.\r
// routing\r
http.HandleFunc("/", defaultHandler)\r
http.HandleFunc("/stats/submit", makeSubmitHandler(requests))\r
- http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))\r
+ http.Handle("/m/", http.StripPrefix("/m/", http.FileServer(http.Dir("m"))))\r
\r
// serving\r
fmt.Printf("Serving on port %d...\n", port)\r
addr := fmt.Sprintf(":%d", port)\r
- http.ListenAndServe(addr, nil)\r
+ for true {\r
+ http.ListenAndServe(addr, nil)\r
+ time.Sleep(100*time.Millisecond)\r
+ }\r
}\r
\r
// intercepts all URLs, displays a landing page\r
body := make([]byte, r.ContentLength)\r
r.Body.Read(body)\r
\r
- db := getDBConn()\r
- defer db.Close()\r
+ db := getDBConn()\r
+ defer db.Close()\r
\r
- _, err := db.Exec("INSERT INTO requests(blind_id_header, ip_addr, body, bodylength) VALUES(?, ?, ?, ?)", blind_id_header, remoteAddr, string(body), r.ContentLength)\r
+ _, err := db.Exec("INSERT INTO requests(blind_id_header, ip_addr, body, bodylength) VALUES(?, ?, ?, ?)", blind_id_header, remoteAddr, string(body), r.ContentLength)\r
if err != nil {\r
fmt.Println("Unable to insert request.")\r
fmt.Println(err)\r
// resubmits stats request to a particular URL. this is intended to be used when\r
// you want to write back to the "real" XonStat\r
func resubmit(url string) {\r
- db := getDBConn()\r
+ db := getDBConn()\r
defer db.Close()\r
\r
rows, err := db.Query("SELECT request_id, ip_addr, blind_id_header, body, bodylength FROM requests ORDER BY request_id")\r
}\r
defer rows.Close()\r
\r
- successfulRequests := make([]int, 0, 10)\r
+ successfulRequests := make([]int, 0, 10)\r
for rows.Next() {\r
// could use a struct here, but isntead just a bunch of vars\r
var request_id int\r
}\r
\r
req, _ := http.NewRequest("POST", url, strings.NewReader(body))\r
- req.ContentLength = int64(bodylength)\r
+ //req.ContentLength = int64(bodylength)\r
+ //req.ContentLength = 0\r
+ req.ContentLength = int64(len([]byte(body)))\r
\r
header := map[string][]string{\r
"X-D0-Blind-Id-Detached-Signature": {blind_id_header},\r
req.Header = header\r
\r
res, err := http.DefaultClient.Do(req)\r
- if err != nil {\r
- fmt.Printf("Error submitting request #%d. Continuing...\n", request_id)\r
- continue\r
- }\r
+ if err != nil {\r
+ fmt.Printf("Error submitting request #%d. Continuing...\n", request_id)\r
+ fmt.Println(err)\r
+ continue\r
+ }\r
defer res.Body.Close()\r
\r
fmt.Printf("Request #%d: %s\n", request_id, res.Status)\r
\r
- if res.StatusCode < 500 {\r
- successfulRequests = append(successfulRequests, request_id)\r
- }\r
+ // undeliverables requests will still live in the database,\r
+ // but we can clear out the 200 ones for sure\r
+ if res.StatusCode == 200 {\r
+ successfulRequests = append(successfulRequests, request_id)\r
+ }\r
}\r
\r
- // now that we're done resubmitting, let's clean up the successful requests\r
- // by deleting them outright from the database\r
- for _, val := range(successfulRequests) {\r
- deleteRequest(db, val)\r
- }\r
+ // now that we're done resubmitting, let's clean up the successful requests\r
+ // by deleting them outright from the database\r
+ for _, val := range successfulRequests {\r
+ deleteRequest(db, val)\r
+ }\r
}\r
\r
// lists all the requests and their information *in the XonStat log format* in\r
// order to 1) show what's in the db and 2) to be able to save/parse it (with\r
// xs_parse) for later use.\r
func list() {\r
- db := getDBConn()\r
+ db := getDBConn()\r
defer db.Close()\r
\r
rows, err := db.Query("SELECT request_id, ip_addr, blind_id_header, body FROM requests ORDER BY request_id")\r
\r
// hard-coded sqlite database connection retriever to keep it simple\r
func getDBConn() *sql.DB {\r
- conn, err := sql.Open("sqlite3", "./middleman.db")\r
+ conn, err := sql.Open("sqlite3", "./middleman.db")\r
\r
if err != nil {\r
fmt.Println("Error opening middleman.db. Did you create it?")\r
os.Exit(1)\r
}\r
\r
- return conn\r
+ return conn\r
}\r
\r
// removes reqeusts from the database by request_id\r
func deleteRequest(db *sql.DB, request_id int) {\r
- _, err := db.Exec("delete from requests where request_id = ?", request_id)\r
- if err != nil {\r
- fmt.Printf("Could not remove request_id %d from the database. Reason: %v\n", request_id, err)\r
- } else {\r
- fmt.Printf("Request #%d removed from the database.\n", request_id)\r
- }\r
+ _, err := db.Exec("delete from requests where request_id = ?", request_id)\r
+ if err != nil {\r
+ fmt.Printf("Could not remove request_id %d from the database. Reason: %v\n", request_id, err)\r
+ } else {\r
+ fmt.Printf("Request #%d removed from the database.\n", request_id)\r
+ }\r
}\r