// 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.

// Primitive HTTP client. See RFC 2616.

package http

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

// Response represents the response from an HTTP request.
type Response struct {
	Status		string;	// e.g. "200 OK"
	StatusCode	int;	// e.g. 200

	// Header maps header keys to values.  If the response had multiple
	// headers with the same key, they will be concatenated, with comma
	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
	// be semantically equivalent to a comma-delimited sequence.)
	//
	// Keys in the map are canonicalized (see CanonicalHeaderKey).
	Header	map[string]string;

	// Stream from which the response body can be read.
	Body	io.ReadCloser;
}

// GetHeader returns the value of the response header with the given
// key, and true.  If there were multiple headers with this key, their
// values are concatenated, with a comma delimiter.  If there were no
// response headers with the given key, it returns the empty string and
// false.  Keys are not case sensitive.
func (r *Response) GetHeader(key string) (value string) {
	value, _ = r.Header[CanonicalHeaderKey(key)];
	return;
}

// AddHeader adds a value under the given key.  Keys are not case sensitive.
func (r *Response) AddHeader(key, value string) {
	key = CanonicalHeaderKey(key);

	oldValues, oldValuesPresent := r.Header[key];
	if oldValuesPresent {
		r.Header[key] = oldValues + "," + value
	} else {
		r.Header[key] = value
	}
}

// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
// return true if the string includes a port.
func hasPort(s string) bool	{ return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }

// Used in Send to implement io.ReadCloser by bundling together the
// io.BufReader through which we read the response, and the underlying
// network connection.
type readClose struct {
	io.Reader;
	io.Closer;
}

// ReadResponse reads and returns an HTTP response from r.
func ReadResponse(r *bufio.Reader) (*Response, os.Error) {
	resp := new(Response);

	// Parse the first line of the response.
	resp.Header = make(map[string]string);

	line, err := readLine(r);
	if err != nil {
		return nil, err
	}
	f := strings.Split(line, " ", 3);
	if len(f) < 3 {
		return nil, &badStringError{"malformed HTTP response", line}
	}
	resp.Status = f[1] + " " + f[2];
	resp.StatusCode, err = strconv.Atoi(f[1]);
	if err != nil {
		return nil, &badStringError{"malformed HTTP status code", f[1]}
	}

	// Parse the response headers.
	for {
		key, value, err := readKeyValue(r);
		if err != nil {
			return nil, err
		}
		if key == "" {
			break	// end of response header
		}
		resp.AddHeader(key, value);
	}

	return resp, nil;
}


// Send issues an HTTP request.  Caller should close resp.Body when done reading it.
//
// TODO: support persistent connections (multiple requests on a single connection).
// send() method is nonpublic because, when we refactor the code for persistent
// connections, it may no longer make sense to have a method with this signature.
func send(req *Request) (resp *Response, err os.Error) {
	if req.URL.Scheme != "http" {
		return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
	}

	addr := req.URL.Host;
	if !hasPort(addr) {
		addr += ":http"
	}
	conn, err := net.Dial("tcp", "", addr);
	if err != nil {
		return nil, err
	}

	err = req.Write(conn);
	if err != nil {
		conn.Close();
		return nil, err;
	}

	reader := bufio.NewReader(conn);
	resp, err = ReadResponse(reader);
	if err != nil {
		conn.Close();
		return nil, err;
	}

	r := io.Reader(reader);
	if v := resp.GetHeader("Transfer-Encoding"); v == "chunked" {
		r = newChunkedReader(reader)
	} else if v := resp.GetHeader("Content-Length"); v != "" {
		n, err := strconv.Atoi64(v);
		if err != nil {
			return nil, &badStringError{"invalid Content-Length", v}
		}
		r = io.LimitReader(r, n);
	}
	resp.Body = readClose{r, conn};

	return;
}

// True if the specified HTTP status code is one for which the Get utility should
// automatically redirect.
func shouldRedirect(statusCode int) bool {
	switch statusCode {
	case StatusMovedPermanently, StatusFound, StatusSeeOther, StatusTemporaryRedirect:
		return true
	}
	return false;
}

// Get issues a GET to the specified URL.  If the response is one of the following
// redirect codes, it follows the redirect, up to a maximum of 10 redirects:
//
//    301 (Moved Permanently)
//    302 (Found)
//    303 (See Other)
//    307 (Temporary Redirect)
//
// finalURL is the URL from which the response was fetched -- identical to the input
// URL unless redirects were followed.
//
// Caller should close r.Body when done reading it.
func Get(url string) (r *Response, finalURL string, err os.Error) {
	// TODO: if/when we add cookie support, the redirected request shouldn't
	// necessarily supply the same cookies as the original.
	// TODO: set referrer header on redirects.
	for redirect := 0; ; redirect++ {
		if redirect >= 10 {
			err = os.ErrorString("stopped after 10 redirects");
			break;
		}

		var req Request;
		if req.URL, err = ParseURL(url); err != nil {
			break
		}
		if r, err = send(&req); err != nil {
			break
		}
		if shouldRedirect(r.StatusCode) {
			r.Body.Close();
			if url = r.GetHeader("Location"); url == "" {
				err = os.ErrorString(fmt.Sprintf("%d response missing Location header", r.StatusCode));
				break;
			}
			continue;
		}
		finalURL = url;
		return;
	}

	err = &URLError{"Get", url, err};
	return;
}


// Post issues a POST to the specified URL.
//
// Caller should close r.Body when done reading it.
func Post(url string, bodyType string, body io.Reader) (r *Response, err os.Error) {
	var req Request;
	req.Method = "POST";
	req.Body = body;
	req.Header = map[string]string{
		"Content-Type": bodyType,
		"Transfer-Encoding": "chunked",
	};

	req.URL, err = ParseURL(url);
	if err != nil {
		return nil, err
	}

	return send(&req);
}
