// 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 = new(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;
}
