// 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"
	"io"
	"log"
	"net"
	"os"
	"path"
	"strconv"
	"strings"
)

// Errors introduced by the HTTP server.
var (
	ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush")
	ErrBodyNotAllowed  = os.NewError("http: response status code does not allow body")
	ErrHijacked        = os.NewError("Conn has been hijacked")
)

// Objects implementing the Handler interface can be
// registered to serve a particular path or subtree
// in the HTTP server.
//
// ServeHTTP should write reply headers and data to the Conn
// and then return.  Returning signals that the request is finished
// and that the HTTP server can move on to the next request on
// the connection.
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
	wroteContinue   bool              // 100 Continue response was 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 net.Conn, handler Handler) (c *Conn, err os.Error) {
	c = new(Conn)
	if a := rwc.RemoteAddr(); a != nil {
		c.RemoteAddr = a.String()
	}
	c.handler = handler
	c.rwc = rwc
	br := bufio.NewReader(rwc)
	bw := bufio.NewWriter(rwc)
	c.buf = bufio.NewReadWriter(br, bw)
	return c, nil
}

// wrapper around io.ReaderCloser which on first read, sends an
// HTTP/1.1 100 Continue header
type expectContinueReader struct {
	conn       *Conn
	readCloser io.ReadCloser
}

func (ecr *expectContinueReader) Read(p []byte) (n int, err os.Error) {
	if !ecr.conn.wroteContinue && !ecr.conn.hijacked {
		ecr.conn.wroteContinue = true
		if ecr.conn.Req.ProtoAtLeast(1, 1) {
			io.WriteString(ecr.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n")
			ecr.conn.buf.Flush()
		}
	}
	return ecr.readCloser.Read(p)
}

func (ecr *expectContinueReader) Close() os.Error {
	return ecr.readCloser.Close()
}

// 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.wroteContinue = false
	c.Req = req

	// Expect 100 Continue support
	if req.expectsContinue() {
		// Wrap the Body reader with one that replies on the connection
		req.Body = &expectContinueReader{readCloser: req.Body, conn: c}
	}

	// 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
	if code == StatusNotModified {
		// Must not have body.
		c.header["Content-Type"] = "", false
		c.header["Transfer-Encoding"] = "", false
	}
	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
	}

	if c.status == StatusNotModified {
		// Must not have body.
		return 0, ErrBodyNotAllowed
	}

	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 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"

	// Is it text?  ("Content-Type" is always in the map)
	baseType := strings.Split(c.header["Content-Type"], ";", 2)[0]
	switch baseType {
	case "text/html":
		io.WriteString(c, "<!-- ")
		for c.written < min {
			io.WriteString(c, msg)
		}
		io.WriteString(c, " -->")
	case "text/plain":
		io.WriteString(c, "\n")
		for c.written < min {
			io.WriteString(c, msg)
		}
	}
}

func (c *Conn) finishRequest() {
	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()
}

// Flush sends any buffered data to the client.
func (c *Conn) Flush() {
	if !c.wroteHeader {
		c.WriteHeader(StatusOK)
	}
	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.finishRequest()
		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

// Error replies to the request with the specified error message and HTTP code.
func Error(c *Conn, error string, code int) {
	c.SetHeader("Content-Type", "text/plain; charset=utf-8")
	c.WriteHeader(code)
	fmt.Fprintln(c, error)
}

// NotFound replies to the request with an HTTP 404 not found error.
func NotFound(c *Conn, req *Request) { Error(c, "404 page not found", StatusNotFound) }

// 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, _ := 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] != '/' {
		panic("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)
	}
}

// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(*Conn, *Request)) {
	mux.Handle(pattern, HandlerFunc(handler))
}

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

// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
func HandleFunc(pattern string, handler func(*Conn, *Request)) {
	DefaultServeMux.HandleFunc(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, e := l.Accept()
		if e != nil {
			return e
		}
		c, err := newConn(rw, 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"
//		"log"
//	)
//
//	// hello world, the web server
//	func HelloServer(c *http.Conn, req *http.Request) {
//		io.WriteString(c, "hello, world!\n")
//	}
//
//	func main() {
//		http.HandleFunc("/hello", HelloServer)
//		err := http.ListenAndServe(":12345", nil)
//		if err != nil {
//			log.Exit("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
}
