hnakra/service/http.go

98 lines
2.3 KiB
Go

package service
import "log"
import "errors"
import "net/http"
import "hnakra/protocol"
// HTTP is an https:// mount.
type HTTP struct {
MountInfo
// AllowInsecure allows this mount to respond to plain-text HTTP
// requests. You can get a TLS cert for free nowadays so there are very
// few cases where you'd want this on.
AllowInsecure bool
// Handler specifies the handler to invoke. If it is nil,
// http.DefaultServeMux is used.
Handler http.Handler
conn *Conn
running bool
requests requestManager
}
// Close closes the mount abruptly, interrupting any active connections.
func (htmount *HTTP) Close () error {
htmount.running = false
return htmount.conn.Close()
}
// Shutdown gracefully shuts down the service without interrupting any active
// connections.
func (htmount *HTTP) Shutdown () error {
// TODO
return htmount.Close()
}
// Run connects to the router, and blocks while fulfilling requests. This method
// will only return when the connection to the router has been closed.
func (htmount *HTTP) Run (service ServiceInfo) (err error) {
if htmount.AllowInsecure {
htmount.MountInfo.Scheme = "http"
} else {
htmount.MountInfo.Scheme = "https"
}
htmount.conn, err = Dial(htmount.MountInfo, service)
if err != nil { return }
htmount.running = true
htmount.requests.init()
for {
message, err := htmount.conn.Receive()
if err != nil {
if htmount.running {
return err
} else {
return nil
}
}
switch message.(type) {
case protocol.MessageHTTPRequest:
request := message.(protocol.MessageHTTPRequest)
htmount.requests.add(request.ID)
go htmount.handle(request)
case protocol.MessageHTTPBodySegment:
segment := message.(protocol.MessageHTTPBodySegment)
htmount.requests.feed(segment.ID, segment.Data)
case protocol.MessageHTTPBodyEnd:
end := message.(protocol.MessageHTTPBodyEnd)
htmount.requests.end(end.ID)
case protocol.MessageStatus:
status := message.(protocol.MessageStatus)
log.Println("router says:", status.Status)
default:
htmount.Close()
return errors.New("router sent unknown type code")
}
}
}
// NewHTTP creates a new HTTPS mount that uses the specified handler.
func NewHTTP (host, path string, handler http.Handler) *HTTP {
return &HTTP {
MountInfo: MountInfo {
Host: host,
Path: path,
},
Handler: handler,
}
}