// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// HTTP server.  See RFC 2616.

// TODO(rsc):
//	logging
//	cgi support
//	post support

package http

import (
	"bufio";
	"fmt";
	"http";
	"io";
	"log";
	"net";
	"os";
	"path";
	"strconv";
	"strings";
)

// Errors introduced by the HTTP server.
var (
	ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush");
	ErrHijacked = os.NewError("Conn has been hijacked");
)

type Conn struct

// Objects implemeting the Handler interface can be
// registered to serve a particular path or subtree
// in the HTTP server.
type Handler interface {
	ServeHTTP(*Conn, *Request);
}

// A Conn represents the server side of a single active HTTP connection.
type Conn struct {
	RemoteAddr string;	// network address of remote side
	Req *Request;		// current HTTP request

	rwc io.ReadWriteCloser;	// i/o connection
	buf *bufio.ReadWriter;	// buffered rwc
	handler Handler;	// request handler
	hijacked bool;	// connection has been hijacked by handler

	// state for the current reply
	closeAfterReply bool;	// close connection after this reply
	chunking bool;	// using chunked transfer encoding for reply body
	wroteHeader bool;	// reply header has been written
	header map[string] string;	// reply header parameters
	written int64;	// number of bytes written in body
	status int;	// status code passed to WriteHeader
}

// Create new connection from rwc.
func newConn(rwc io.ReadWriteCloser, raddr string, handler Handler) (c *Conn, err os.Error) {
	c = new(Conn);
	c.RemoteAddr = raddr;
	c.handler = handler;
	c.rwc = rwc;
	br := bufio.NewReader(rwc);
	bw := bufio.NewWriter(rwc);
	c.buf = bufio.NewReadWriter(br, bw);
	return c, nil
}

func (c *Conn) SetHeader(hdr, val string)

// Read next request from connection.
func (c *Conn) readRequest() (req *Request, err os.Error) {
	if c.hijacked {
		return nil, ErrHijacked
	}
	if req, err = ReadRequest(c.buf.Reader); err != nil {
		return nil, err
	}

	// Reset per-request connection state.
	c.header = make(map[string] string);
	c.wroteHeader = false;
	c.Req = req;

	// Default output is HTML encoded in UTF-8.
	c.SetHeader("Content-Type", "text/html; charset=utf-8");

	if req.ProtoAtLeast(1, 1) {
		// HTTP/1.1 or greater: use chunked transfer encoding
		// to avoid closing the connection at EOF.
		c.chunking = true;
		c.SetHeader("Transfer-Encoding", "chunked");
	} else {
		// HTTP version < 1.1: cannot do chunked transfer
		// encoding, so signal EOF by closing connection.
		// Could avoid closing the connection if there is
		// a Content-Length: header in the response,
		// but everyone who expects persistent connections
		// does HTTP/1.1 now.
		c.closeAfterReply = true;
		c.chunking = false;
	}

	return req, nil
}

// SetHeader sets a header line in the eventual reply.
// For example, SetHeader("Content-Type", "text/html; charset=utf-8")
// will result in the header line
//
//	Content-Type: text/html; charset=utf-8
//
// being sent.  UTF-8 encoded HTML is the default setting for
// Content-Type in this library, so users need not make that
// particular call.  Calls to SetHeader after WriteHeader (or Write)
// are ignored.
func (c *Conn) SetHeader(hdr, val string) {
	c.header[CanonicalHeaderKey(hdr)] = val;
}

// WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
// will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to
// send error codes.
func (c *Conn) WriteHeader(code int) {
	if c.hijacked {
		log.Stderr("http: Conn.WriteHeader on hijacked connection");
		return
	}
	if c.wroteHeader {
		log.Stderr("http: multiple Conn.WriteHeader calls");
		return
	}
	c.wroteHeader = true;
	c.status = code;
	c.written = 0;
	if !c.Req.ProtoAtLeast(1, 0) {
		return
	}
	proto := "HTTP/1.0";
	if c.Req.ProtoAtLeast(1, 1) {
		proto = "HTTP/1.1";
	}
	codestring := strconv.Itoa(code);
	text, ok := statusText[code];
	if !ok {
		text = "status code " + codestring;
	}
	io.WriteString(c.buf, proto + " " + codestring + " " + text + "\r\n");
	for k,v := range c.header {
		io.WriteString(c.buf, k + ": " + v + "\r\n");
	}
	io.WriteString(c.buf, "\r\n");
}

// Write writes the data to the connection as part of an HTTP reply.
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// before writing the data.
func (c *Conn) Write(data []byte) (n int, err os.Error) {
	if c.hijacked {
		log.Stderr("http: Conn.Write on hijacked connection");
		return 0, ErrHijacked
	}
	if !c.wroteHeader {
		c.WriteHeader(StatusOK);
	}
	if len(data) == 0 {
		return 0, nil
	}

	c.written += int64(len(data));	// ignoring errors, for errorKludge

	// TODO(rsc): if chunking happened after the buffering,
	// then there would be fewer chunk headers.
	// On the other hand, it would make hijacking more difficult.
	if c.chunking {
		fmt.Fprintf(c.buf, "%x\r\n", len(data));	// TODO(rsc): use strconv not fmt
	}
	n, err = c.buf.Write(data);
	if err == nil && c.chunking {
		if n != len(data) {
			err = io.ErrShortWrite;
		}
		if err == nil {
			io.WriteString(c.buf, "\r\n");
		}
	}

	return n, err;
}

// If this is an error reply (4xx or 5xx)
// and the handler wrote some data explaining the error,
// some browsers (i.e., Chrome, Internet Explorer)
// will show their own error instead unless the error is
// long enough.  The minimum lengths used in those
// browsers are in the 256-512 range.
// Pad to 1024 bytes.
func errorKludge(c *Conn, req *Request) {
	const min = 1024;

	// Is this an error?
	if kind := c.status/100; kind != 4 && kind != 5 {
		return;
	}

	// Did the handler supply any info?  Enough?
	if c.written == 0 || c.written >= min {
		return;
	}

	// Is it text?  ("Content-Type" is always in the map)
	if s := c.header["Content-Type"]; len(s) < 5 || s[0:5] != "text/" {
		return;
	}

	// Is it a broken browser?
	var msg string;
	switch agent := req.UserAgent; {
	case strings.Index(agent, "MSIE") >= 0:
		msg = "Internet Explorer";
	case strings.Index(agent, "Chrome/") >= 0:
		msg = "Chrome";
	default:
		return;
	}
	msg += " would ignore this error page if this text weren't here.\n";
	io.WriteString(c, "\n");
	for c.written < min {
		io.WriteString(c, msg);
	}
}

func (c *Conn) flush() {
	if !c.wroteHeader {
		c.WriteHeader(StatusOK);
	}
	errorKludge(c, c.Req);
	if c.chunking {
		io.WriteString(c.buf, "0\r\n");
		// trailer key/value pairs, followed by blank line
		io.WriteString(c.buf, "\r\n");
	}
	c.buf.Flush();
}

// Close the connection.
func (c *Conn) close() {
	if c.buf != nil {
		c.buf.Flush();
		c.buf = nil;
	}
	if c.rwc != nil {
		c.rwc.Close();
		c.rwc = nil;
	}
}

// Serve a new connection.
func (c *Conn) serve() {
	for {
		req, err := c.readRequest();
		if err != nil {
			break
		}
		// HTTP cannot have multiple simultaneous active requests.
		// Until the server replies to this request, it can't read another,
		// so we might as well run the handler in this goroutine.
		c.handler.ServeHTTP(c, req);
		if c.hijacked {
			return;
		}
		c.flush();
		if c.closeAfterReply {
			break;
		}
	}
	c.close();
}

// Hijack lets the caller take over the connection.
// After a call to c.Hijack(), the HTTP server library
// will not do anything else with the connection.
// It becomes the caller's responsibility to manage
// and close the connection.
func (c *Conn) Hijack() (rwc io.ReadWriteCloser, buf *bufio.ReadWriter, err os.Error) {
	if c.hijacked {
		return nil, nil, ErrHijacked;
	}
	c.hijacked = true;
	rwc = c.rwc;
	buf = c.buf;
	c.rwc = nil;
	c.buf = nil;
	return;
}

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers.  If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler object that calls f.
type HandlerFunc func(*Conn, *Request)

// ServeHTTP calls f(c, req).
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
	f(c, req);
}

// Helper handlers

// NotFound replies to the request with an HTTP 404 not found error.
func NotFound(c *Conn, req *Request) {
	c.SetHeader("Content-Type", "text/plain; charset=utf-8");
	c.WriteHeader(StatusNotFound);
	io.WriteString(c, "404 page not found\n");
}

// NotFoundHandler returns a simple request handler
// that replies to each request with a ``404 page not found'' reply.
func NotFoundHandler() Handler {
	return HandlerFunc(NotFound)
}

// Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path.
func Redirect(c *Conn, url string, code int) {
	// RFC2616 recommends that a short note "SHOULD" be included in the
	// response because older user agents may not understand 301/307.
	note := "<a href=\"%v\">" + statusText[code] + "</a>.\n";
	if c.Req.Method == "POST" {
		note = "";
	}

	u, err := ParseURL(url);
	if err != nil {
		goto finish
	}

	// If url was relative, make absolute by
	// combining with request path.
	// The browser would probably do this for us,
	// but doing it ourselves is more reliable.

	// NOTE(rsc): RFC 2616 says that the Location
	// line must be an absolute URI, like
	// "http://www.google.com/redirect/",
	// not a path like "/redirect/".
	// Unfortunately, we don't know what to
	// put in the host name section to get the
	// client to connect to us again, so we can't
	// know the right absolute URI to send back.
	// Because of this problem, no one pays attention
	// to the RFC; they all send back just a new path.
	// So do we.
	oldpath := c.Req.Url.Path;
	if oldpath == "" {	// should not happen, but avoid a crash if it does
		oldpath = "/"
	}
	if u.Scheme == "" {
		// no leading http://server
		if url == "" || url[0] != '/' {
			// make relative path absolute
			olddir, oldfile := path.Split(oldpath);
			url = olddir + url;
		}

		// clean up but preserve trailing slash
		trailing := url[len(url) - 1] == '/';
		url = path.Clean(url);
		if trailing && url[len(url) - 1] != '/' {
			url += "/";
		}
	}

finish:
	c.SetHeader("Location", url);
	c.WriteHeader(code);
	fmt.Fprintf(c, note, url);
}

// Redirect to a fixed URL
type redirectHandler struct {
	url string;
	code int;
}
func (rh *redirectHandler) ServeHTTP(c *Conn, req *Request) {
	Redirect(c, rh.url, rh.code);
}

// RedirectHandler returns a request handler that redirects
// each request it receives to the given url using the given
// status code.
func RedirectHandler(url string, code int) Handler {
	return &redirectHandler{ url, code }
}

// ServeMux is an HTTP request multiplexer.
// It matches the URL of each incoming request against a list of registered
// patterns and calls the handler for the pattern that
// most closely matches the URL.
//
// Patterns named fixed paths, like "/favicon.ico",
// or subtrees, like "/images/" (note the trailing slash).
// Patterns must begin with /.
// Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
// former will receiver requests for any other paths in the
// "/images/" subtree.
//
// In the future, the pattern syntax may be relaxed to allow
// an optional host-name at the beginning of the pattern,
// so that a handler might register for the two patterns
// "/codesearch" and "codesearch.google.com/"
// without taking over requests for http://www.google.com/.
//
// ServeMux also takes care of sanitizing the URL request path,
// redirecting any request containing . or .. elements to an
// equivalent .- and ..-free URL.
type ServeMux struct {
	m map[string] Handler
}

// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux {
	return &ServeMux{make(map[string] Handler)};
}

// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux();

// Does path match pattern?
func pathMatch(pattern, path string) bool {
	if len(pattern) == 0 {
		// should not happen
		return false
	}
	n := len(pattern);
	if pattern[n-1] != '/' {
		return pattern == path
	}
	return len(path) >= n && path[0:n] == pattern;
}

// Return the canonical path for p, eliminating . and .. elements.
func cleanPath(p string) string {
	if p == "" {
		return "/";
	}
	if p[0] != '/' {
		p = "/" + p;
	}
	np := path.Clean(p);
	// path.Clean removes trailing slash except for root;
	// put the trailing slash back if necessary.
	if p[len(p)-1] == '/' && np != "/" {
		np += "/";
	}
	return np;
}

// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) {
	// Clean path to canonical form and redirect.
	if p := cleanPath(req.Url.Path); p != req.Url.Path {
		c.SetHeader("Location", p);
		c.WriteHeader(StatusMovedPermanently);
		return;
	}

	// Most-specific (longest) pattern wins.
	var h Handler;
	var n = 0;
	for k, v := range mux.m {
		if !pathMatch(k, req.Url.Path) {
			continue;
		}
		if h == nil || len(k) > n {
			n = len(k);
			h = v;
		}
	}
	if h == nil {
		h = NotFoundHandler();
	}
	h.ServeHTTP(c, req);
}

// Handle registers the handler for the given pattern.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	if pattern == "" || pattern[0] != '/' {
		panicln("http: invalid pattern", pattern);
	}

	mux.m[pattern] = handler;

	// Helpful behavior:
	// If pattern is /tree/, insert permanent redirect for /tree.
	n := len(pattern);
	if n > 0 && pattern[n-1] == '/' {
		mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently);
	}
}

// Handle registers the handler for the given pattern
// in the DefaultServeMux.
func Handle(pattern string, handler Handler) {
	DefaultServeMux.Handle(pattern, handler);
}

// Serve accepts incoming HTTP connections on the listener l,
// creating a new service thread for each.  The service threads
// read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used.
func Serve(l net.Listener, handler Handler) os.Error {
	if handler == nil {
		handler = DefaultServeMux;
	}
	for {
		rw, raddr, e := l.Accept();
		if e != nil {
			return e
		}
		c, err := newConn(rw, raddr, handler);
		if err != nil {
			continue;
		}
		go c.serve();
	}
	panic("not reached")
}

// ListenAndServe listens on the TCP network address addr
// and then calls Serve with handler to handle requests
// on incoming connections.  Handler is typically nil,
// in which case the DefaultServeMux is used.
//
// A trivial example server is:
//
//	package main
//
//	import (
//		"http";
//		"io";
//	)
//
//	// hello world, the web server
//	func HelloServer(c *http.Conn, req *http.Request) {
//		io.WriteString(c, "hello, world!\n");
//	}
//
//	func main() {
//		http.Handle("/hello", http.HandlerFunc(HelloServer));
//		err := http.ListenAndServe(":12345", nil);
//		if err != nil {
//			panic("ListenAndServe: ", err.String())
//		}
//	}
func ListenAndServe(addr string, handler Handler) os.Error {
	l, e := net.Listen("tcp", addr);
	if e != nil {
		return e
	}
	e = Serve(l, handler);
	l.Close();
	return e
}

