momos

package module
v0.0.0-...-7d97fe8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2019 License: MIT Imports: 18 Imported by: 0

README

Momos logo

License MIT Build Status

Momos - Reverse proxy to define server-side-includes with HTML5 and attributes. No html comments or complicated configurations. This is a proof-of-concept.

  • Cache: Requests are cached with RFC7234.
  • Fast: SSI Fragments are loaded in parallel.
  • No proxy configs: Everything is configurable via HTML5 attributes.
  • Dev-friendly: Frontend developer can create fragments easily.
  • Fallback: Define default content or an error template with <ssi-error>.
  • Reliable: Define a timeout message with <ssi-timeout>.
  • Just HTML: Define SSI fragments with pure HTML <ssi>.
  • Templating: Use Go Templates inside fragments and ssi tags.
  • Operational: Easy to start and maintain. Single binary.

Why you don't use Nginx?

Good point. Nginx is a great proxy and although it already provides robust SSI directives I would like to see a solution which doesn't require a restart or reload of the proxy when parameters has to be changed. The transition between defining SSI fragments and configure them should be smooth for any kind of developer. Momos should provide a proxy with advanced SSI functionality. Any developer should be able to place and configure SSI fragments with html knowledge.

Momos is compiled to a single binary. It provides great debugging experience to understand how your page is build which is often difficult in proxys like Nginx or Apache.

What are SSI?

SSI (Server Side Includes) are directives that are placed in HTML pages, and evaluated on the server while the pages are being served. They let you add dynamically generated content to an existing HTML page, without having to serve the entire page via a CGI program, or other dynamic technology. Reference

Advantages

  • Easy integration of html fragments from external services
  • Share all layout html fragments to keep them DRY
  • Insert fragments in pages which are usually static (e.g landing)
  • In highly distributed environments it can be an advantage to integrate services on data content

Example

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
<body>

  <ssi
    name="basket"
    timeout="2000"
    template="true"
    src="http://starptech.de">

    <!-- Used when no error or timeout field was set default empty space -->
    Default content!
    
    <!-- Timeout errors based on the timeout duration-->
    <ssi-timeout>
    <span>Please try it again! {{.DateLocal}}</span>
    </ssi-timeout>
    
    <!-- None 2xx status code or any other error -->
    <ssi-error>
    <span>Please call the support!</span>
    </ssi-error>
  </ssi>
  
</body>
</html>
  • name : The name of the fragment (default unique-id)
  • timeout : The maximum request timeout (default 2000)
  • no-scripts: Filter javascript and css includes from the fragment (default true)
  • src : The url of the server-side-include
  • template : Enables template rendering via go templates (default false)

Run it

$ go test
$ go run examples/server.go
$ go run examples/client.go

Expected output

Requests are cached for 10 seconds max-age=10

__  ___
/  |/  /__  __ _  ___  ___
/ /|_/ / _ \/  ' \/ _ \(_-<
/_/  /_/\___/_/_/_/\___/___/ 1.0.0
High performance, reverse proxy for advanced SSI
2017/08/22 20:10:48.367828 [INF] Fragment "basket3" was cached
2017/08/22 20:10:48.367828 [INF] Fragment "basket4" was cached
2017/08/22 20:10:48.367828 [INF] Fragment "basket5" was cached
2017/08/22 20:10:48.367828 [INF] Fragment "basket2" was cached
2017/08/22 20:10:48.367828 [INF] Fragment "basket" was cached
2017/08/22 20:10:48.367828 [TRC] Call fragment basket3, url: http://localhost:8081/b, duration: 999.5µs
2017/08/22 20:10:48.367828 [TRC] Call fragment basket4, url: http://localhost:8081/c, duration: 999.5µs
2017/08/22 20:10:48.367828 [TRC] Call fragment basket5, url: http://localhost:8081/d, duration: 999.5µs
2017/08/22 20:10:48.367828 [TRC] Call fragment basket2, url: http://localhost:8081/a, duration: 999.5µs
2017/08/22 20:10:48.367828 [TRC] Call fragment basket, url: https://google.de, duration: 999.5µs
2017/08/22 20:10:48.368827 [TRC] Processing complete "http://127.0.0.1:8080/favicon.ico" took "1.9983ms"

Run in production

Momos is no replacement for a reverse proxy like Nginx or Apache. Only the calls to the SSI Services are cached.

TODO

  • Generate useful debug informations about the fragment structure of your page
  • Collect metrics
  • Add headers attribute to pass custom headers to the upstream proxy.
  • Allow fragments to consume specific custom headers from request.

References

Credits

Icon made by author from www.flaticon.com

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrRequest            = errors.New("request error")
	ErrTimeout            = errors.New("timeout error")
	ErrInvalidStatusCode  = errors.New("invalid status code")
	ErrInvalidContentType = errors.New("invalid content type")
)
View Source
var ServerLogging = false

Functions

This section is empty.

Types

type Proxy

type Proxy struct {
	ReverseProxy *httputil.ReverseProxy

	ProxyURL string
	Handler  *httpcache.Handler
	// contains filtered or unexported fields
}

func New

func New(targetUrl string) *Proxy

func (*Proxy) Shutdown

func (p *Proxy) Shutdown(ctx context.Context) error

func (*Proxy) Start

func (p *Proxy) Start(addr string) error

type SSIAttributes

type SSIAttributes map[string]string

type SSIElement

type SSIElement struct {
	Tag         string
	HasErrorTag bool

	HasTimeoutTag bool

	Attributes SSIAttributes
	Element    *goquery.Selection
	// contains filtered or unexported fields
}

func (*SSIElement) GetErrorTag

func (s *SSIElement) GetErrorTag() error

GetErrorTag find the error tag

func (*SSIElement) GetTimeoutTag

func (s *SSIElement) GetTimeoutTag() error

GetTimeoutTag find the timeout tag

func (*SSIElement) ReplaceWithHTML

func (s *SSIElement) ReplaceWithHTML(html string) error

ReplaceWithHTML use the content from the ssi service and parse the fragment as go template (optionally)

func (*SSIElement) SetFilterIncludes

func (s *SSIElement) SetFilterIncludes(h string) error

SetFilterIncludes enable filter of dynamic includes like <script> and <link> tags

func (*SSIElement) SetName

func (s *SSIElement) SetName(name string) error

SetName set the name of the ssi fragment

func (*SSIElement) SetSrc

func (s *SSIElement) SetSrc(src string) error

SetSrc set the source of the ssi fragment

func (*SSIElement) SetTemplate

func (s *SSIElement) SetTemplate(h string) error

SetTemplate enables go templating

func (*SSIElement) SetTimeout

func (s *SSIElement) SetTimeout(t string) error

SetTimeout set the timeout

func (*SSIElement) SetupFallback

func (s *SSIElement) SetupFallback(err error) error

SetupFallback replace the fragment with the correct fallback content

func (*SSIElement) SetupSuccess

func (s *SSIElement) SetupSuccess(body []byte) error

SetupSuccess replace the fragment with the correct content

type TemplateContext

type TemplateContext struct {
	DateLocal string
	Date      string
	RequestId string
	Name      string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL