[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [snowflake/main] Move http handlers to a separate file
commit 0ced1cc32497f3b47a614ef4a526af7925447252
Author: Arlo Breault <abreault@xxxxxxxxxxxxx>
Date: Thu May 20 08:31:30 2021 -0400
Move http handlers to a separate file
---
broker/broker.go | 196 ----------------------------------------------------
broker/http.go | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 205 insertions(+), 196 deletions(-)
diff --git a/broker/broker.go b/broker/broker.go
index 58f3955..437a4d1 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -8,10 +8,8 @@ package main
import (
"container/heap"
"crypto/tls"
- "errors"
"flag"
"io"
- "io/ioutil"
"log"
"net/http"
"os"
@@ -21,17 +19,12 @@ import (
"syscall"
"time"
- "git.torproject.org/pluggable-transports/snowflake.git/common/messages"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"golang.org/x/crypto/acme/autocert"
)
-const (
- readLimit = 100000 // Maximum number of bytes to be read from an HTTP request
-)
-
type BrokerContext struct {
snowflakes *SnowflakeHeap
restrictedSnowflakes *SnowflakeHeap
@@ -69,38 +62,6 @@ func NewBrokerContext(metricsLogger *log.Logger) *BrokerContext {
}
}
-// Implements the http.Handler interface
-type SnowflakeHandler struct {
- *IPC
- handle func(*IPC, http.ResponseWriter, *http.Request)
-}
-
-// Implements the http.Handler interface
-type MetricsHandler struct {
- logFilename string
- handle func(string, http.ResponseWriter, *http.Request)
-}
-
-func (sh SnowflakeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Session-ID")
- // Return early if it's CORS preflight.
- if "OPTIONS" == r.Method {
- return
- }
- sh.handle(sh.IPC, w, r)
-}
-
-func (mh MetricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Session-ID")
- // Return early if it's CORS preflight.
- if "OPTIONS" == r.Method {
- return
- }
- mh.handle(mh.logFilename, w, r)
-}
-
// Proxies may poll for client offers concurrently.
type ProxyPoll struct {
id string
@@ -178,169 +139,12 @@ func (ctx *BrokerContext) AddSnowflake(id string, proxyType string, natType stri
return snowflake
}
-/*
-For snowflake proxies to request a client from the Broker.
-*/
-func proxyPolls(i *IPC, w http.ResponseWriter, r *http.Request) {
- body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
- if err != nil {
- log.Println("Invalid data.")
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- arg := messages.Arg{
- Body: body,
- RemoteAddr: r.RemoteAddr,
- NatType: "",
- }
-
- var response []byte
- err = i.ProxyPolls(arg, &response)
- switch {
- case err == nil:
- case errors.Is(err, messages.ErrBadRequest):
- w.WriteHeader(http.StatusBadRequest)
- return
- case errors.Is(err, messages.ErrInternal):
- fallthrough
- default:
- log.Println(err)
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
-
- if _, err := w.Write(response); err != nil {
- log.Printf("proxyPolls unable to write offer with error: %v", err)
- }
-}
-
// Client offer contains an SDP and the NAT type of the client
type ClientOffer struct {
natType string
sdp []byte
}
-/*
-Expects a WebRTC SDP offer in the Request to give to an assigned
-snowflake proxy, which responds with the SDP answer to be sent in
-the HTTP response back to the client.
-*/
-func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) {
- body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
- if err != nil {
- log.Printf("Error reading client request: %s", err.Error())
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- arg := messages.Arg{
- Body: body,
- RemoteAddr: "",
- NatType: r.Header.Get("Snowflake-NAT-Type"),
- }
-
- var response []byte
- err = i.ClientOffers(arg, &response)
- switch {
- case err == nil:
- case errors.Is(err, messages.ErrUnavailable):
- w.WriteHeader(http.StatusServiceUnavailable)
- return
- case errors.Is(err, messages.ErrTimeout):
- w.WriteHeader(http.StatusGatewayTimeout)
- return
- default:
- log.Println(err)
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
-
- if _, err := w.Write(response); err != nil {
- log.Printf("clientOffers unable to write answer with error: %v", err)
- }
-}
-
-/*
-Expects snowflake proxes which have previously successfully received
-an offer from proxyHandler to respond with an answer in an HTTP POST,
-which the broker will pass back to the original client.
-*/
-func proxyAnswers(i *IPC, w http.ResponseWriter, r *http.Request) {
- body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
- if err != nil {
- log.Println("Invalid data.")
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- arg := messages.Arg{
- Body: body,
- RemoteAddr: "",
- NatType: "",
- }
-
- var response []byte
- err = i.ProxyAnswers(arg, &response)
- switch {
- case err == nil:
- case errors.Is(err, messages.ErrBadRequest):
- w.WriteHeader(http.StatusBadRequest)
- return
- case errors.Is(err, messages.ErrInternal):
- fallthrough
- default:
- log.Println(err)
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
-
- if _, err := w.Write(response); err != nil {
- log.Printf("proxyAnswers unable to write answer response with error: %v", err)
- }
-}
-
-func debugHandler(i *IPC, w http.ResponseWriter, r *http.Request) {
- var response string
-
- err := i.Debug(new(interface{}), &response)
- if err != nil {
- log.Println(err)
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
-
- if _, err := w.Write([]byte(response)); err != nil {
- log.Printf("writing proxy information returned error: %v ", err)
- }
-}
-
-func robotsTxtHandler(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- if _, err := w.Write([]byte("User-agent: *\nDisallow: /\n")); err != nil {
- log.Printf("robotsTxtHandler unable to write, with this error: %v", err)
- }
-}
-
-func metricsHandler(metricsFilename string, w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-
- if metricsFilename == "" {
- http.NotFound(w, r)
- return
- }
- metricsFile, err := os.OpenFile(metricsFilename, os.O_RDONLY, 0644)
- if err != nil {
- log.Println("Error opening metrics file for reading")
- http.NotFound(w, r)
- return
- }
-
- if _, err := io.Copy(w, metricsFile); err != nil {
- log.Printf("copying metricsFile returned error: %v", err)
- }
-}
-
func main() {
var acmeEmail string
var acmeHostnamesCommas string
diff --git a/broker/http.go b/broker/http.go
new file mode 100644
index 0000000..6555d7a
--- /dev/null
+++ b/broker/http.go
@@ -0,0 +1,205 @@
+package main
+
+import (
+ "errors"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+
+ "git.torproject.org/pluggable-transports/snowflake.git/common/messages"
+)
+
+const (
+ readLimit = 100000 // Maximum number of bytes to be read from an HTTP request
+)
+
+// Implements the http.Handler interface
+type SnowflakeHandler struct {
+ *IPC
+ handle func(*IPC, http.ResponseWriter, *http.Request)
+}
+
+func (sh SnowflakeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Session-ID")
+ // Return early if it's CORS preflight.
+ if "OPTIONS" == r.Method {
+ return
+ }
+ sh.handle(sh.IPC, w, r)
+}
+
+// Implements the http.Handler interface
+type MetricsHandler struct {
+ logFilename string
+ handle func(string, http.ResponseWriter, *http.Request)
+}
+
+func (mh MetricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Session-ID")
+ // Return early if it's CORS preflight.
+ if "OPTIONS" == r.Method {
+ return
+ }
+ mh.handle(mh.logFilename, w, r)
+}
+
+func robotsTxtHandler(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ if _, err := w.Write([]byte("User-agent: *\nDisallow: /\n")); err != nil {
+ log.Printf("robotsTxtHandler unable to write, with this error: %v", err)
+ }
+}
+
+func metricsHandler(metricsFilename string, w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+
+ if metricsFilename == "" {
+ http.NotFound(w, r)
+ return
+ }
+ metricsFile, err := os.OpenFile(metricsFilename, os.O_RDONLY, 0644)
+ if err != nil {
+ log.Println("Error opening metrics file for reading")
+ http.NotFound(w, r)
+ return
+ }
+
+ if _, err := io.Copy(w, metricsFile); err != nil {
+ log.Printf("copying metricsFile returned error: %v", err)
+ }
+}
+
+func debugHandler(i *IPC, w http.ResponseWriter, r *http.Request) {
+ var response string
+
+ err := i.Debug(new(interface{}), &response)
+ if err != nil {
+ log.Println(err)
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ if _, err := w.Write([]byte(response)); err != nil {
+ log.Printf("writing proxy information returned error: %v ", err)
+ }
+}
+
+/*
+For snowflake proxies to request a client from the Broker.
+*/
+func proxyPolls(i *IPC, w http.ResponseWriter, r *http.Request) {
+ body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
+ if err != nil {
+ log.Println("Invalid data.")
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ arg := messages.Arg{
+ Body: body,
+ RemoteAddr: r.RemoteAddr,
+ NatType: "",
+ }
+
+ var response []byte
+ err = i.ProxyPolls(arg, &response)
+ switch {
+ case err == nil:
+ case errors.Is(err, messages.ErrBadRequest):
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ case errors.Is(err, messages.ErrInternal):
+ fallthrough
+ default:
+ log.Println(err)
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ if _, err := w.Write(response); err != nil {
+ log.Printf("proxyPolls unable to write offer with error: %v", err)
+ }
+}
+
+/*
+Expects a WebRTC SDP offer in the Request to give to an assigned
+snowflake proxy, which responds with the SDP answer to be sent in
+the HTTP response back to the client.
+*/
+func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) {
+ body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
+ if err != nil {
+ log.Printf("Error reading client request: %s", err.Error())
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ arg := messages.Arg{
+ Body: body,
+ RemoteAddr: "",
+ NatType: r.Header.Get("Snowflake-NAT-Type"),
+ }
+
+ var response []byte
+ err = i.ClientOffers(arg, &response)
+ switch {
+ case err == nil:
+ case errors.Is(err, messages.ErrUnavailable):
+ w.WriteHeader(http.StatusServiceUnavailable)
+ return
+ case errors.Is(err, messages.ErrTimeout):
+ w.WriteHeader(http.StatusGatewayTimeout)
+ return
+ default:
+ log.Println(err)
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ if _, err := w.Write(response); err != nil {
+ log.Printf("clientOffers unable to write answer with error: %v", err)
+ }
+}
+
+/*
+Expects snowflake proxes which have previously successfully received
+an offer from proxyHandler to respond with an answer in an HTTP POST,
+which the broker will pass back to the original client.
+*/
+func proxyAnswers(i *IPC, w http.ResponseWriter, r *http.Request) {
+ body, err := ioutil.ReadAll(http.MaxBytesReader(w, r.Body, readLimit))
+ if err != nil {
+ log.Println("Invalid data.")
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ arg := messages.Arg{
+ Body: body,
+ RemoteAddr: "",
+ NatType: "",
+ }
+
+ var response []byte
+ err = i.ProxyAnswers(arg, &response)
+ switch {
+ case err == nil:
+ case errors.Is(err, messages.ErrBadRequest):
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ case errors.Is(err, messages.ErrInternal):
+ fallthrough
+ default:
+ log.Println(err)
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ if _, err := w.Write(response); err != nil {
+ log.Printf("proxyAnswers unable to write answer response with error: %v", err)
+ }
+}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits