/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 * All rights reserved
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */

#include "defs.h"

static int
write_cgi(struct stream *stream, const void *buf, size_t len)
{
	assert(stream->chan.sock != -1);
	assert(stream->flags & FLAG_W);

	return (send(stream->chan.sock, buf, len, 0));
}

static int
read_cgi(struct stream *stream, void *buf, size_t len)
{
	struct headers	parsed;
	char		status[4];
	int		n;

	assert(stream->chan.sock != -1);
	assert(stream->flags & FLAG_R);

	stream->flags &= ~FLAG_DONT_CLOSE;

	n = recv(stream->chan.sock, buf, len, 0);

	if (stream->flags & FLAG_HEADERS_PARSED)
		return (n);

	if (n <= 0 && ERRNO != EWOULDBLOCK) {
		_shttpd_send_server_error(stream->conn, 500,
		    "Error running CGI");
		return (n);
	}

	/*
	 * CGI script may output Status: and Location: headers, which
	 * may alter the status code. Buffer in headers, parse
	 * them, send correct status code and then forward all data
	 * from CGI script back to the remote end.
	 * Reply line was alredy appended to the IO buffer in
	 * decide_what_to_do(), with blank status code.
	 */

	stream->flags |= FLAG_DONT_CLOSE;
	io_inc_head(&stream->io, n);

	stream->headers_len = _shttpd_get_headers_len(stream->io.buf,
	    stream->io.head);
	if (stream->headers_len < 0) {
		stream->flags &= ~FLAG_DONT_CLOSE;
		_shttpd_send_server_error(stream->conn, 500,
		    "Bad headers sent");
		_shttpd_elog(E_LOG, stream->conn,
		    "CGI script sent invalid headers: "
		    "[%.*s]", stream->io.head - CGI_REPLY_LEN,
		    stream->io.buf + CGI_REPLY_LEN);
		return (0);
	}

	/*
	 * If we did not received full headers yet, we must not send any
	 * data read from the CGI back to the client. Suspend sending by
	 * setting tail = head, which tells that there is no data in IO buffer
	 */

	if (stream->headers_len == 0) {
		stream->io.tail = stream->io.head;
		return (0);
	}

	/* Received all headers. Set status code for the connection. */
	(void) memset(&parsed, 0, sizeof(parsed));
	_shttpd_parse_headers(stream->io.buf, stream->headers_len, &parsed);
	stream->content_len = parsed.cl.v_big_int;
	stream->conn->status = (int) parsed.status.v_big_int;

	/* If script outputs 'Location:' header, set status code to 302 */
	if (parsed.location.v_vec.len > 0)
		stream->conn->status = 302;

	/*
	 * If script did not output neither 'Location:' nor 'Status' headers,
	 * set the default status code 200, which means 'success'.
	 */
	if (stream->conn->status == 0)
		stream->conn->status = 200;

	/* Append the status line to the beginning of the output */
	(void) _shttpd_snprintf(status,
	    sizeof(status), "%3d", stream->conn->status);
	(void) memcpy(stream->io.buf + 9, status, 3);
	DBG(("read_cgi: content len %lu status %s",
	    stream->content_len, status));

	/* Next time, pass output directly back to the client */
	assert((big_int_t) stream->headers_len <= stream->io.total);
	stream->io.total -= stream->headers_len;
	stream->io.tail = 0;
	stream->flags |= FLAG_HEADERS_PARSED;

	/* Return 0 because we've already shifted the head */
	return (0);
}

static void
close_cgi(struct stream *stream)
{
	assert(stream->chan.sock != -1);
	(void) closesocket(stream->chan.sock);
}

const struct io_class	_shttpd_io_cgi =  {
	"cgi",
	read_cgi,
	write_cgi,
	close_cgi
};
