[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [check/master] Start an API.



commit 940a0ab0e048913272e4bbfa1b75ac14a456b33e
Author: Arlo Breault <arlolra@xxxxxxxxx>
Date:   Tue Nov 19 00:00:59 2013 -0800

    Start an API.
    
    One route, /api/bulk
---
 check.go     |    1 +
 datastore.go |   36 ++++++++++++++++++++++++++++++++----
 handlers.go  |   18 +++++++++++++-----
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/check.go b/check.go
index 73e6a7c..00b25b6 100644
--- a/check.go
+++ b/check.go
@@ -60,6 +60,7 @@ func main() {
 	// routes
 	http.HandleFunc("/", RootHandler(CompileTemplate(*basePath, domain, "index.html"), exits, domain, Phttp, Locales))
 	bulk := BulkHandler(CompileTemplate(*basePath, domain, "bulk.html"), exits, domain)
+	http.HandleFunc("/api/bulk", bulk)
 	http.HandleFunc("/torbulkexitlist", bulk)
 	http.HandleFunc("/cgi-bin/TorBulkExitList.py", bulk)
 
diff --git a/datastore.go b/datastore.go
index c01acc6..c23109b 100644
--- a/datastore.go
+++ b/datastore.go
@@ -84,6 +84,19 @@ func (p PolicyList) Swap(i, j int) {
 	p[i], p[j] = p[j], p[i]
 }
 
+type ExitInfo struct {
+	Address     string
+	Fingerprint string
+}
+
+func (e ExitInfo) toJSON() (b []byte) {
+	j, err := json.MarshalIndent(e, "", "  ")
+	if err != nil {
+		return
+	}
+	return j
+}
+
 type Exits struct {
 	List        PolicyList
 	UpdateTime  time.Time
@@ -93,15 +106,30 @@ type Exits struct {
 
 func (e *Exits) Dump(w io.Writer, tminus int, ip string, port int) {
 	ap := AddressPort{ip, port}
-	e.GetAllExits(ap, tminus, func(exit string, _ string) {
+	e.GetAllExits(ap, tminus, func(exit string, _ string, _ int) {
 		w.Write([]byte(exit + "\n"))
 	})
 }
 
-func (e *Exits) GetAllExits(ap AddressPort, tminus int, fn func(string, string)) {
+func (e *Exits) DumpJSON(w io.Writer, tminus int, ip string, port int) {
+	ap := AddressPort{ip, port}
+	Prefix := []byte(",\n")
+	w.Write([]byte("["))
+	e.GetAllExits(ap, tminus, func(address string, fingerprint string, ind int) {
+		if ind > 0 {
+			w.Write(Prefix)
+		}
+		w.Write(ExitInfo{address, fingerprint}.toJSON())
+	})
+	w.Write([]byte("]"))
+}
+
+func (e *Exits) GetAllExits(ap AddressPort, tminus int, fn func(string, string, int)) {
+	ind := 0
 	for _, val := range e.List {
 		if val.Tminus <= tminus && val.CanExit(ap) {
-			fn(val.Address, val.Fingerprint)
+			fn(val.Address, val.Fingerprint, ind)
+			ind += 1
 		}
 	}
 }
@@ -110,7 +138,7 @@ var DefaultTarget = AddressPort{"38.229.70.31", 443}
 
 func (e *Exits) PreComputeTorList() {
 	newmap := make(map[string]string)
-	e.GetAllExits(DefaultTarget, 16, func(ip string, fingerprint string) {
+	e.GetAllExits(DefaultTarget, 16, func(ip string, fingerprint string, _ int) {
 		newmap[ip] = fingerprint
 	})
 	e.IsTorLookup = newmap
diff --git a/handlers.go b/handlers.go
index eee6948..9342ff8 100644
--- a/handlers.go
+++ b/handlers.go
@@ -9,6 +9,7 @@ import (
 	"log"
 	"net"
 	"net/http"
+	"regexp"
 	"strconv"
 	"time"
 )
@@ -89,6 +90,8 @@ func RootHandler(Layout *template.Template, Exits *Exits, domain *gettext.Domain
 
 func BulkHandler(Layout *template.Template, Exits *Exits, domain *gettext.Domain) http.HandlerFunc {
 
+	ApiPath := regexp.MustCompile("^/api/")
+
 	return func(w http.ResponseWriter, r *http.Request) {
 		q := r.URL.Query()
 
@@ -103,12 +106,17 @@ func BulkHandler(Layout *template.Template, Exits *Exits, domain *gettext.Domain
 
 		w.Header().Set("Last-Modified", Exits.UpdateTime.UTC().Format(http.TimeFormat))
 
-		str := fmt.Sprintf("# This is a list of all Tor exit nodes from the past %d hours that can contact %s on port %d #\n", n, ip, port)
-		str += fmt.Sprintf("# You can update this list by visiting https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=%s%s%s #\n", ip, port_str, n_str)
-		str += fmt.Sprintf("# This file was generated on %v #\n", Exits.UpdateTime.UTC().Format(time.UnixDate))
-		fmt.Fprintf(w, str)
+		if q.Get("format") == "json" || ApiPath.MatchString(r.URL.Path) {
+			w.Header().Set("Content-Type", "application/json")
+			Exits.DumpJSON(w, n, ip, port)
+		} else {
+			str := fmt.Sprintf("# This is a list of all Tor exit nodes from the past %d hours that can contact %s on port %d #\n", n, ip, port)
+			str += fmt.Sprintf("# You can update this list by visiting https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=%s%s%s #\n", ip, port_str, n_str)
+			str += fmt.Sprintf("# This file was generated on %v #\n", Exits.UpdateTime.UTC().Format(time.UnixDate))
+			fmt.Fprintf(w, str)
+			Exits.Dump(w, n, ip, port)
+		}
 
-		Exits.Dump(w, n, ip, port)
 	}
 
 }

_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits