func (fe *FrontEnd) serve(q *http.Query) { req := q.GetRequest() //fmt.Printf("Request: %v·%v·%v·%v\n", // req.URL.Scheme, req.URL.Host, req.URL.Path, req.URL.RawQuery) fe.lk.Lock() fe.useragent = req.UserAgent fe.lk.Unlock() rtype, _ := getRequestType(req) switch { case rtype == feWWWReq: fe.serveWWW(q) case rtype == feAdminReq: fe.serveAdmin(q) case rtype == feTonikaReq: fe.serveViaVault(q) default: q.Continue() if req.Body != nil { req.Body.Close() } q.Write(newRespBadRequest()) } }
func serveUserMsg(msg string, q *http.Query) { q.Continue() req := q.GetRequest() if req.Body != nil { req.Body.Close() } q.Write(buildResp(msg)) }
func (fe *FrontEnd) serveViaVault(q *http.Query) { req := q.GetRequest() resp, err := fe.vault.Serve(req) if err != nil { serveUserMsg("Could not fetch data from "+sys.Name+".", q) return } q.Continue() if req.Body != nil { req.Body.Close() } q.Write(resp) }
func (fe *FrontEnd) wwwConnect(q *http.Query) { req := q.GetRequest() resp, conn2 := fe.wwwclient.Connect(req) if conn2 == nil { q.Continue() q.Write(resp) return } err := q.Write(resp) if err != nil { return } asc := q.Hijack() conn1, r1, _ := asc.Close() if conn1 == nil { conn2.Close() return } http.MakeBridge(conn1, r1, conn2, nil) }
func (fe *FrontEnd) serveAdmin(q *http.Query) { req := q.GetRequest() q.Continue() if req.Body != nil { req.Body.Close() } if req.URL == nil { q.Write(newRespBadRequest()) return } // Static files path := path.Clean(req.URL.Path) req.URL.Path = path const pfxStatic = "/static/" if strings.HasPrefix(path, pfxStatic) { q.Write(fe.replyStatic(path[len(pfxStatic):])) return } var resp *http.Response switch { case strings.HasPrefix(path, "/api/"): resp = fe.replyAPI(req) case strings.HasPrefix(path, "/accept"): resp = fe.replyAdminAccept(req) case strings.HasPrefix(path, "/add"): resp = fe.replyAdminAdd(req) case strings.HasPrefix(path, "/bug"): resp = fe.replyAdminBug(req) case strings.HasPrefix(path, "/edit"): resp = fe.replyAdminEdit(req) case strings.HasPrefix(path, "/monitor"): resp = fe.replyAdminMonitor(req) case strings.HasPrefix(path, "/neighbors"): resp = fe.replyRoot() case strings.HasPrefix(path, "/reinvite"): resp = fe.replyAdminReinvite(req) case strings.HasPrefix(path, "/"): resp = fe.replyAdminMain() default: q.Write(newRespNotFound()) return } //dresp, _ := http.DumpResponse(resp, false) //fmt.Printf("RESP:\n%s\n", string(dresp)) q.Write(resp) }
func (fe *FrontEnd) serveWWW(q *http.Query) { req := q.GetRequest() if req.Method == "CONNECT" { go fe.wwwConnect(q) return } q.Continue() // Rewrite request req.Header["Proxy-Connection"] = "", false req.Header["Connection"] = "Keep-Alive" //req.Header["Keep-Alive"] = "30" url := req.URL req.URL = nil req.RawURL = url.RawPath if url.RawQuery != "" { req.RawURL += "?" + url.RawQuery } if url.Fragment != "" { req.RawURL += "#" + url.Fragment } // Dump request, use for debugging // dreq, _ := DumpRequest(req, false) // fmt.Printf("REQ:\n%s\n", string(dreq)) resp := fe.wwwclient.Fetch(req) // Dump response, use for debugging // dresp, _ := DumpResponse(resp, false) // fmt.Printf("RESP:\n%s\n", string(dresp)) resp.Close = false if resp.Header != nil { resp.Header["Connection"] = "", false } q.Write(resp) }
func (s *Server) serve(q *http.Query) { q.Continue() req := q.GetRequest() if req.Body != nil { req.Body.Close() } s.log(req, q.RemoteAddr()) // Path cleanup path := path.Clean(req.URL.Path) if path == "" { path = "/" } // Host analysis hostport := strings.Split(req.Host, ":", 2) if len(hostport) == 0 { q.Write(newRespBadRequest()) return } hostparts := misc.ReverseHost(strings.Split(hostport[0], ".", -1)) // http://5ttt.org, http://www.5ttt.org if len(hostparts) < 3 || hostparts[2] == "www" { if path == "/" { path = "/index.html" } if isIndex(path) { s.lk.Lock() s.stats.Views++ s.lk.Unlock() } var resp *http.Response if isIndex(path) { resp = s.replyIndex() } else { resp = s.replyStatic(path) } if isDownload(path) && resp.Body != nil { resp.Body = http.NewRunOnClose(resp.Body, func() { // TODO: This also counts incomplete downloads, but for now // it's fine. s.lk.Lock() s.stats.Downloads++ s.lk.Unlock() }) } q.Write(resp) return } // Remove 5ttt.org from host hostparts = hostparts[2:] // http://*.a.5ttt.org/* if hostparts[0] == "a" { q.Write(s.replyStatic("/tadmin.html")) // Trying to access a Tonika Admin return } // http://*.[id].5ttt.org if _, err := sys.ParseId(hostparts[0]); err == nil { q.Write(s.replyStatic("/turl.html")) // Trying to access a Tonika URL return } // Otherwise q.Write(newRespNotFound()) }