Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
99 lines (87 sloc) 2.31 KB
// HTTP server implementations
//
// The application that does not use this middleware, Request.Session is alwasy nil.
//
// Copyright (C) 2014 Yohei Sasaki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package wcg
import (
"errors"
"fmt"
"net"
"net/http"
)
type serverConfig struct {
Scheme string `ini:"scheme" default:"http"`
Host string `ini:"host" default:"localhost"`
Port int `ini:"port" default:"3000"`
}
var ServerConfig = &serverConfig{}
func init() {
RegisterProcessConfig(ServerConfig, "wcg.server", nil)
}
// WCG server
type Server interface {
Routes() *Router
Run() error
}
// LocalServer is a Server implementation using http.Server.
type LocalServer struct {
Addr string
routes *Router
server *http.Server
listener net.Listener
}
func NewLocalServer() *LocalServer {
s := new(LocalServer)
s.Addr = fmt.Sprintf("%s:%d", ServerConfig.Host, ServerConfig.Port)
s.server = new(http.Server)
s.routes = NewRouter()
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
r := NewRequest(req)
s.routes.Dispatch(NewResponse(w, r), r)
})
s.server.Handler = mux
return s
}
func (s *LocalServer) Routes() *Router {
return s.routes
}
func (s *LocalServer) Run() error {
var err error
if s.Addr == "" {
s.listener, err = net.Listen("tcp", ":0")
s.Addr = s.listener.Addr().String()
} else {
s.listener, err = net.Listen("tcp", s.Addr)
}
if err != nil {
return err
} else {
go s.server.Serve(s.listener)
return nil
}
}
// Stop the server.
// TODO: When `graceful` is true, this would wait for all incoming requests being completed.
func (s *LocalServer) Stop(graceful bool) error {
if s.listener == nil {
return errors.New("Server already stopped.")
}
err := s.listener.Close()
s.listener = nil
return err
}