summary refs log tree commit diff stats
BranchCommit messageAuthorAge
masterremove remote registry list push to leveldb because that doesn't work right nowBenjamin Morrison3 years
 
TagDownloadAuthorAge
v0.5.0getwtxt-0.5.0.tar.gz  Benjamin Morrison3 years
v0.4.15getwtxt-0.4.15.tar.gz  Ben Morrison4 years
v0.4.14getwtxt-0.4.14.tar.gz  Ben Morrison4 years
v0.4.13getwtxt-0.4.13.tar.gz  Ben Morrison4 years
v0.4.12getwtxt-0.4.12.tar.gz  Ben Morrison5 years
v0.4.11getwtxt-0.4.11.tar.gz  Ben Morrison5 years
v0.4.10getwtxt-0.4.10.tar.gz  Ben Morrison5 years
v0.4.9getwtxt-0.4.9.tar.gz  Ben Morrison5 years
v0.4.8getwtxt-0.4.8.tar.gz  Ben Morrison5 years
v0.4.7getwtxt-0.4.7.tar.gz  Ben Morrison5 years
v0.4.6getwtxt-0.4.6.tar.gz  Ben Morrison5 years
v0.4.5getwtxt-0.4.5.tar.gz  Ben Morrison5 years
v0.4.4getwtxt-0.4.4.tar.gz  Ben Morrison5 years
v0.4.3getwtxt-0.4.3.tar.gz  Ben Morrison5 years
v0.4.2getwtxt-0.4.2.tar.gz  Ben Morrison5 years
v0.4.1getwtxt-0.4.1.tar.gz  Ben Morrison5 years
v0.4.0getwtxt-0.4.0.tar.gz  Ben Morrison5 years
v0.3.3getwtxt-0.3.3.tar.gz  Ben Morrison5 years
v0.3.2getwtxt-0.3.2.tar.gz  Ben Morrison5 years
v0.3.1getwtxt-0.3.1.tar.gz  Ben Morrison5 years
v0.3.0getwtxt-0.3.0.tar.gz  Ben Morrison5 years
v0.2.4getwtxt-0.2.4.tar.gz  Ben Morrison5 years
v0.2.3getwtxt-0.2.3.tar.gz  Ben Morrison5 years
v0.2.2getwtxt-0.2.2.tar.gz  Ben Morrison5 years
v0.2.1getwtxt-0.2.1.tar.gz  Ben Morrison5 years
v0.2.0getwtxt-0.2.0.tar.gz  Ben Morrison5 years
v0.1.1getwtxt-0.1.1.tar.gz  Ben Morrison5 years
v0.1getwtxt-0.1.tar.gz  Ben Morrison5 years
olor: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
package svc // import "github.com/getwtxt/getwtxt/svc"

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
)

// Start is the initialization function for getwtxt
func Start() {
	initSvc()

	// StrictSlash(true) allows /api and /api/
	// to serve the same content without duplicating
	// handlers/paths
	index := mux.NewRouter().StrictSlash(true)
	api := index.PathPrefix("/api").Subrouter()

	setIndexRouting(index)
	setEndpointRouting(api)

	confObj.Mu.RLock()
	portnum := fmt.Sprintf(":%v", confObj.Port)
	confObj.Mu.RUnlock()

	server := newServer(portnum, index)

	log.Printf("*** Listening on %v\n", portnum)
	log.Printf("*** getwtxt %v Started :: %v ::\n\n", Vers, time.Now().Format(time.RFC3339))
	errLog("", server.ListenAndServe())

	closeLog <- true
}

func newServer(port string, index *mux.Router) *http.Server {
	// handlers.CompressHandler gzips all responses.
	// Write/Read timeouts are self explanatory.
	return &http.Server{
		Handler:      handlers.CompressHandler(ipMiddleware(index)),
		Addr:         port,
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}
}

func setIndexRouting(index *mux.Router) {
	index.Path("/").
		Methods("GET", "HEAD").
		HandlerFunc(indexHandler)

	index.Path("/css").
		Methods("GET", "HEAD").
		HandlerFunc(cssHandler)

	index.Path("/api").
		Methods("GET", "HEAD").
		HandlerFunc(apiBaseHandler)
}

func setEndpointRouting(api *mux.Router) {
	// twtxt will add support for other formats later.
	// Maybe json? Making this future-proof.
	api.Path("/{format:(?:plain)}").
		Methods("GET", "HEAD").
		HandlerFunc(apiFormatHandler)

	// Non-standard API call to list *all* tweets
	// in a single request.
	api.Path("/{format:(?:plain)}/tweets/all").
		Methods("GET", "HEAD").
		HandlerFunc(apiAllTweetsHandler)

	// Specifying the endpoint with and without query information.
	// Will return 404 on empty queries otherwise.
	api.Path("/{format:(?:plain)}/{endpoint:(?:mentions|users|tweets)}").
		Methods("GET", "HEAD").
		HandlerFunc(apiEndpointHandler)

	api.Path("/{format:(?:plain)}/{endpoint:(?:mentions|users|tweets)}").
		Queries("url", "{url}", "q", "{query}", "page", "{[0-9]+}").
		Methods("GET", "HEAD").
		HandlerFunc(apiEndpointHandler)

	// This is for submitting new users. Both query variables must exist
	// in the request for this to match.
	api.Path("/{format:(?:plain)}/{endpoint:users}").
		Queries("url", "{url}", "nickname", "{nickname:[a-zA-Z0-9_-]+}").
		Methods("POST").
		HandlerFunc(apiEndpointPOSTHandler)

	// This is for submitting new users incorrectly
	// and letting the requester know about their error.
	api.Path("/{format:(?:plain)}/{endpoint:users}").
		Queries("url", "{url}").
		Methods("POST").
		HandlerFunc(apiEndpointPOSTHandler)

	// This is also for submitting new users incorrectly
	// and letting the requester know about their error.
	api.Path("/{format:(?:plain)}/{endpoint:users}").
		Queries("nickname", "{nickname:[a-zA-Z0-9_-]+}").
		Methods("POST").
		HandlerFunc(apiEndpointPOSTHandler)

	// Show all observed tags
	api.Path("/{format:(?:plain)}/tags").
		Methods("GET", "HEAD").
		HandlerFunc(apiTagsBaseHandler)

	// Show Nth page of all observed tags
	api.Path("/{format:(?:plain)}/tags").
		Queries("page", "{[0-9]+}").
		Methods("GET", "HEAD").
		HandlerFunc(apiTagsBaseHandler)

	// Requests statuses with a specific tag
	api.Path("/{format:(?:plain)}/tags/{tags:[a-zA-Z0-9_-]+}").
		Methods("GET", "HEAD").
		HandlerFunc(apiTagsHandler)

	// Requests Nth page of statuses with a specific tag
	api.Path("/{format:(?:plain)}/tags/{tags:[a-zA-Z0-9_-]+}").
		Queries("page", "{[0-9]+}").
		Methods("GET", "HEAD").
		HandlerFunc(apiTagsHandler)
}