// 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 Request reading and parsing.

package http

import (
	"bufio";
	"http";
	"os";
	"strings"
)

const (
	MaxLineLength = 1024;	// assumed < bufio.DefaultBufSize
	MaxValueLength = 1024;
	MaxHeaderLines = 1024;
)

export var (
	LineTooLong = os.NewError("http header line too long");
	ValueTooLong = os.NewError("http header value too long");
	HeaderTooLong = os.NewError("http header too long");
	BadHeader = os.NewError("malformed http header");
	BadRequest = os.NewError("invalid http request");
	BadHTTPVersion = os.NewError("unsupported http version");
)

// HTTP Request
export type Request struct {
	method string;		// GET, PUT,etc.
	rawurl string;
	url *URL;		// URI after GET, PUT etc.
	proto string;	// "HTTP/1.0"
	pmajor int;	// 1
	pminor int;	// 0

	header map[string] string;

	close bool;
	host string;
	referer string;
	useragent string;
}

// Read a line of bytes (up to \n) from b.
// Give up if the line exceeds MaxLineLength.
// The returned bytes are a pointer into storage in
// the bufio, so they are only valid until the next bufio read.
func ReadLineBytes(b *bufio.BufRead) (p []byte, err *os.Error) {
	if p, err = b.ReadLineSlice('\n'); err != nil {
		return nil, err
	}
	if len(p) >= MaxLineLength {
		return nil, LineTooLong
	}

	// Chop off trailing white space.
	var i int;
	for i = len(p); i > 0; i-- {
		if c := p[i-1]; c != ' ' && c != '\r' && c != '\t' && c != '\n' {
			break
		}
	}
	return p[0:i], nil
}

// ReadLineByte, but convert the bytes into a string.
func ReadLine(b *bufio.BufRead) (s string, err *os.Error) {
	p, e := ReadLineBytes(b);
	if e != nil {
		return "", e
	}
	return string(p), nil
}

// Read a key/value pair from b.
// A key/value has the form Key: Value\r\n
// and the Value can continue on multiple lines if each continuation line
// starts with a space.
func ReadKeyValue(b *bufio.BufRead) (key, value string, err *os.Error) {
	line, e := ReadLineBytes(b);
	if e != nil {
		return "", "", e
	}
	if len(line) == 0 {
		return "", "", nil
	}

	// Scan first line for colon.
	for i := 0; i < len(line); i++ {
		switch line[i] {
		case ' ':
			// Key field has space - no good.
			return "", "", BadHeader;
		case ':':
			key = string(line[0:i]);
			// Skip initial space before value.
			for i++; i < len(line); i++ {
				if line[i] != ' ' {
					break
				}
			}
			value = string(line[i:len(line)]);

			// Look for extension lines, which must begin with space.
			for {
				var c byte;

				if c, e = b.ReadByte(); e != nil {
					return "", "", e
				}
				if c != ' ' {
					// Not leading space; stop.
					b.UnreadByte();
					break
				}

				// Eat leading space.
				for c == ' ' {
					if c, e = b.ReadByte(); e != nil {
						return "", "", e
					}
				}
				b.UnreadByte();

				// Read the rest of the line and add to value.
				if line, e = ReadLineBytes(b); e != nil {
					return "", "", e
				}
				value += " " + string(line);

				if len(value) >= MaxValueLength {
					return "", "", ValueTooLong
				}
			}
			return key, value, nil
		}
	}

	// Line ended before space or colon.
	return "", "", BadHeader;
}

// Convert decimal at s[i:len(s)] to integer,
// returning value, string position where the digits stopped,
// and whether there was a valid number (digits, not too big).
func atoi(s string, i int) (n, i1 int, ok bool) {
	const Big = 1000000;
	if i >= len(s) || s[i] < '0' || s[i] > '9' {
		return 0, 0, false
	}
	n = 0;
	for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
		n = n*10 + int(s[i]-'0');
		if n > Big {
			return 0, 0, false
		}
	}
	return n, i, true
}

// Parse HTTP version: "HTTP/1.2" -> (1, 2, true).
func ParseHTTPVersion(vers string) (int, int, bool) {
	if vers[0:5] != "HTTP/" {
		return 0, 0, false
	}
	major, i, ok := atoi(vers, 5);
	if !ok || i >= len(vers) || vers[i] != '.' {
		return 0, 0, false
	}
	var minor int;
	minor, i, ok = atoi(vers, i+1);
	if !ok || i != len(vers) {
		return 0, 0, false
	}
	return major, minor, true
}

// Read and parse a request from b.
export func ReadRequest(b *bufio.BufRead) (req *Request, err *os.Error) {
	req = new(Request);

	// First line: GET /index.html HTTP/1.0
	var s string;
	if s, err = ReadLine(b); err != nil {
		return nil, err
	}

	var f []string;
	if f = strings.split(s, " "); len(f) != 3 {
		return nil, BadRequest
	}
	req.method, req.rawurl, req.proto = f[0], f[1], f[2];
	var ok bool;
	if req.pmajor, req.pminor, ok = ParseHTTPVersion(req.proto); !ok {
		return nil, BadHTTPVersion
	}

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

	// Subsequent lines: Key: value.
	nheader := 0;
	req.header = make(map[string] string);
	for {
		var key, value string;
		if key, value, err = ReadKeyValue(b); err != nil {
			return nil, err
		}
		if key == "" {
			break
		}
		if nheader++; nheader >= MaxHeaderLines {
			return nil, HeaderTooLong
		}

		// RFC 2616 says that if you send the same header key
		// multiple times, it has to be semantically equivalent
		// to concatenating the values separated by commas.
		oldvalue, present := req.header[key];
		if present {
			req.header[key] = oldvalue+","+value
		} else {
			req.header[key] = value
		}
	}

	// RFC2616: Must treat
	//	GET /index.html HTTP/1.1
	//	Host: www.google.com
	// and
	//	GET http://www.google.com/index.html HTTP/1.1
	//	Host: doesntmatter
	// the same.  In the second case, any Host line is ignored.
	if v, have := req.header["Host"]; have && req.url.host == "" {
		req.host = v
	}

	// RFC2616: Should treat
	//	Pragma: no-cache
	// like
	//	Cache-control: no-cache
	if v, have := req.header["Pragma"]; have && v == "no-cache" {
		if cc, havecc := req.header["Cache-control"]; !havecc {
			req.header["Cache-control"] = "no-cache"
		}
	}

	// Determine whether to hang up after sending the reply.
	if req.pmajor < 1 || (req.pmajor == 1 && req.pminor < 1) {
		req.close = true
	} else if v, have := req.header["Connection"]; have {
		// TODO: Should split on commas, toss surrounding white space,
		// and check each field.
		if v == "close" {
			req.close = true
		}
	}

	// Pull out useful fields as a convenience to clients.
	if v, have := req.header["Referer"]; have {
		req.referer = v
	}
	if v, have := req.header["User-Agent"]; have {
		req.useragent = v
	}


	// TODO: Parse specific header values:
	//	Accept
	//	Accept-Encoding
	//	Accept-Language
	//	Authorization
	//	Cache-Control
	//	Connection
	//	Date
	//	Expect
	//	From
	//	If-Match
	//	If-Modified-Since
	//	If-None-Match
	//	If-Range
	//	If-Unmodified-Since
	//	Max-Forwards
	//	Proxy-Authorization
	//	Referer [sic]
	//	TE (transfer-codings)
	//	Trailer
	//	Transfer-Encoding
	//	Upgrade
	//	User-Agent
	//	Via
	//	Warning

	return req, nil;
}
