JobServer
Landscape
JobServer 包含 Schedulers 及 Workers。Scheduler 中包含一组 Scheduler 实例,用于定时调度 Job。Workers 包含了固定种类的 Worker 实例,每个实例独自工作。JobServer 用于创建、查询、更改 Job 状态,并持久化到 Store 中。
Worker 的实现通过向 JobServer 注册 Worker Generator 来实现。具体的实现不在开源项目中。同时,Worker 与 Scheduler 成对出现,均由使用者自己实现,因此,细节不能继续讨论。
var accountMigrationInterface func(*Server) einterfaces.AccountMigrationInterfacefunc RegisterAccountMigrationInterface(f func(*Server) einterfaces.AccountMigrationInterface) {accountMigrationInterface = f}
HTTPService
Landscape
Core
首先创建基础的 Dialer 结构,并配置参数。
dialContext := (&net.Dialer{Timeout: ConnectTimeout,KeepAlive: 30 * time.Second,}).DialContext
将基础的 DialContext 传入,进行增强后,返回新的 DialContext。
func dialContextFilter(dial DialContextFunction, allowHost func(host string) bool, allowIP func(ip net.IP) bool) DialContextFunction {return func(ctx context.Context, network, addr string) (net.Conn, error) {host, port, err := net.SplitHostPort(addr)if err != nil {return nil, err}if allowHost != nil && allowHost(host) {return dial(ctx, network, addr)}ips, err := net.LookupIP(host)if err != nil {return nil, err}var firstErr errorfor _, ip := range ips {select {case <-ctx.Done():return nil, ctx.Err()default:}if allowIP == nil || !allowIP(ip) {continue}conn, err := dial(ctx, network, net.JoinHostPort(ip.String(), port))if err == nil {return conn, nil}if firstErr == nil {firstErr = err}}if firstErr == nil {return nil, AddressForbidden}return nil, firstErr}}
File Store
Landscape
FileBackend 接口如下
type FileBackend interface {TestConnection() *model.AppErrorReader(path string) (ReadCloseSeeker, *model.AppError)ReadFile(path string) ([]byte, *model.AppError)FileExists(path string) (bool, *model.AppError)CopyFile(oldPath, newPath string) *model.AppErrorMoveFile(oldPath, newPath string) *model.AppErrorWriteFile(fr io.Reader, path string) (int64, *model.AppError)RemoveFile(path string) *model.AppErrorListDirectory(path string) (*[]string, *model.AppError)RemoveDirectory(path string) *model.AppError}
Image Proxy
References
- willnorris/imageproxy: A caching, resizing image proxy written in Go
Landscape
Details
LocalBackend 获取图片的处理,注意其中的 Headers。
func (backend *LocalBackend) GetImage(w http.ResponseWriter, r *http.Request, imageURL string) {// The interface to the proxy only exposes a ServeHTTP method, so fake a request to itreq, err := http.NewRequest(http.MethodGet, "/"+imageURL, nil)if err != nil {// http.NewRequest should only return an error on an invalid URLmlog.Error("Failed to create request for proxied image", mlog.String("url", imageURL), mlog.Err(err))w.WriteHeader(http.StatusBadRequest)w.Write([]byte{})return}w.Header().Set("X-Frame-Options", "deny")w.Header().Set("X-XSS-Protection", "1; mode=block")w.Header().Set("X-Content-Type-Options", "nosniff")w.Header().Set("Content-Security-Policy", "default-src 'none'; img-src data:; style-src 'unsafe-inline'")backend.impl.ServeHTTP(w, req)}
