/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */

#include "config.h"

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif

#include "processor.h"
#include "base64.h"

// libmonit
#include "util/Str.h"


/**
 *  A naive quasi HTTP Processor module that can handle HTTP requests
 *  received from a client, and return responses based on those
 *  requests.
 *
 *  This Processor delegates the actual handling of the request and
 *  reponse to so called cervlets, which must implement two methods;
 *  doGet and doPost. 
 *
 *  NOTES
 *    This Processor is command oriented and if a second slash '/' is
 *    found in the URL it's asumed to be the PATHINFO. In other words
 *    this processor perceive an URL as:
 *
 *                      /COMMAND?QUERYSTRING/PATHINFO
 *
 *     The doGet/doPost routines act's on the COMMAND. See the
 *     cervlet.c code in this dir. for an example. 
 *
 *  @file
 */


/* -------------------------------------------------------------- Prototypes */


static void do_service(Socket_T);
static void destroy_entry(void *);
static char *get_date(char *, int);
static char *get_server(char *, int); 
static void create_headers(HttpRequest);
static void send_response(HttpResponse);
static int basic_authenticate(HttpRequest);
static void done(HttpRequest, HttpResponse);
static void destroy_HttpRequest(HttpRequest);
static void reset_response(HttpResponse res);
static HttpParameter parse_parameters(char *);
static int create_parameters(HttpRequest req);
static void destroy_HttpResponse(HttpResponse);
static HttpRequest create_HttpRequest(Socket_T);
static void internal_error(Socket_T, int, char *);
static HttpResponse create_HttpResponse(Socket_T);
static int is_authenticated(HttpRequest, HttpResponse);
static int get_next_token(char *s, int *cursor, char **r);


/* ------------------------------------------------------------------ Public */


/**
 * Process a HTTP request. This is done by dispatching to the service
 * function. 
 * @param s A Socket_T representing the client connection
 */
void *http_processor(Socket_T s) {

  if(! can_read(socket_get_socket(s), REQUEST_TIMEOUT)) {
    internal_error(s, SC_REQUEST_TIMEOUT, "Time out when handling the Request");
  } else {
    do_service(s);
  }
  socket_free(&s);

  return NULL;

}


/**
 * Callback for implementors of cervlet functions.
 * @param doGetFunc doGet function
 * @param doPostFunc doPost function 
 */
void add_Impl(void(*doGet)(HttpRequest, HttpResponse), void(*doPost)(HttpRequest, HttpResponse)) {
  Impl.doGet= doGet;
  Impl.doPost= doPost;
}


/**
 * Send an error message
 * @param res HttpResponse object
 * @param code Error Code to lookup and send
 * @param msg Optional error message (may be NULL)
 */
void send_error(HttpResponse res, int code, const char *msg) {
  char server[STRLEN];
  const char *err= get_status_string(code);

  reset_response(res);
  set_content_type(res, "text/html");
  set_status(res, code);
  StringBuffer_append(res->outputbuffer,
	   "<html><head><title>%d %s</title></head>"\
	   "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"\
	   "<hr><a href='%s'><font size=-1>%s</font></a>"\
	   "</body></html>\r\n",
	    code, err, err, msg?msg:"", SERVER_URL, get_server(server, STRLEN));
  DEBUG("HttpRequest error: %s %d %s\n", SERVER_PROTOCOL, code, msg ? msg : err);
}


/* -------------------------------------------------------------- Properties */


/**
 * Adds a response header with the given name and value. If the header
 * had already been set the new value overwrites the previous one.
 * @param res HttpResponse object
 * @param name Header key name
 * @param value Header key value
 */
void set_header(HttpResponse res, const char *name, const char *value) {
  HttpHeader h= NULL;

  ASSERT(res);
  ASSERT(name);

  NEW(h);
  h->name= Str_dup(name);
  h->value= Str_dup(value);
  if(res->headers) {
    HttpHeader n, p;
    for( n= p= res->headers; p; n= p, p= p->next) {
      if(!strcasecmp(p->name, name)) {
	FREE(p->value);
	p->value= Str_dup(value);
	destroy_entry(h);
	return;
      }
    }
    n->next= h;
  } else {
    res->headers= h;
  }
}


/**
 * Sets the status code for the response
 * @param res HttpResponse object
 * @param code A HTTP status code <100-510>
 * @param msg The status code string message 
 */
void set_status(HttpResponse res, int code) {
  res->status= code;
  res->status_msg= get_status_string(code);
}


/**
 * Set the response content-type
 * @param res HttpResponse object
 * @param mime Mime content type, e.g. text/html
 */
void set_content_type(HttpResponse res, const char *mime) {
  set_header(res, "Content-Type", mime);
}


/**
 * Returns the value of the specified header
 * @param req HttpRequest object
 * @param name Header name to lookup the value for
 * @return The value of the specified header, NULL if not found
 */
const char *get_header(HttpRequest req, const char *name) {
  HttpHeader p;

  for(p= req->headers; p; p= p->next) {
    if(!strcasecmp(p->name, name)) {
      return (p->value);
    }
  }
  return NULL;
}


/**
 * Returns the value of the specified parameter
 * @param req HttpRequest object
 * @param name The request parameter key to lookup the value for
 * @return The value of the specified parameter, or NULL if not found
 */
const char *get_parameter(HttpRequest req, const char *name) {
  HttpParameter p;

  for(p= req->params; p; p= p->next) {
    if(!strcasecmp(p->name, name)) {
      return (p->value);
    }
  }
  return NULL;
}


/**
 * Returns a string containing all (extra) headers found in the
 * response.  The headers are newline separated in the returned
 * string.
 * @param res HttpResponse object
 * @return A String containing all headers set in the Response object
 */
char *get_headers(HttpResponse res) {
  HttpHeader p;
  char buf[RES_STRLEN];
  char *b= buf;

  *buf=0;
  for(p= res->headers; (((b-buf) + STRLEN) < RES_STRLEN) && p; p= p->next) {
    b+= snprintf(b, STRLEN,"%s: %s\r\n", p->name, p->value);
  }
  return buf[0]?Str_dup(buf):NULL;
}


/**
 * Lookup the corresponding HTTP status string for the given status
 * code
 * @param status A HTTP status code
 * @return A default status message for the specified HTTP status
 * code.
 */
const char *get_status_string(int status) {
  switch (status) {
  case SC_OK:
      return "OK";
  case SC_ACCEPTED:
      return "Accepted";
  case SC_BAD_GATEWAY:
      return "Bad Gateway";
  case SC_BAD_REQUEST:
      return "Bad Request";
  case SC_CONFLICT:
      return "Conflict";
  case SC_CONTINUE:
      return "Continue";
  case SC_CREATED:
      return "Created";
  case SC_EXPECTATION_FAILED:
      return "Expectation Failed";
  case SC_FORBIDDEN:
      return "Forbidden";
  case SC_GATEWAY_TIMEOUT:
      return "Gateway Timeout";
  case SC_GONE:
      return "Gone";
  case SC_VERSION_NOT_SUPPORTED:
      return "HTTP Version Not Supported";
  case SC_INTERNAL_SERVER_ERROR:
      return "Internal Server Error";
  case SC_LENGTH_REQUIRED:
      return "Length Required";
  case SC_METHOD_NOT_ALLOWED:
      return "Method Not Allowed";
  case SC_MOVED_PERMANENTLY:
      return "Moved Permanently";
  case SC_MOVED_TEMPORARILY:
      return "Moved Temporarily";
  case SC_MULTIPLE_CHOICES:
      return "Multiple Choices";
  case SC_NO_CONTENT:
      return "No Content";
  case SC_NON_AUTHORITATIVE:
      return "Non-Authoritative Information";
  case SC_NOT_ACCEPTABLE:
      return "Not Acceptable";
  case SC_NOT_FOUND:
      return "Not Found";
  case SC_NOT_IMPLEMENTED:
      return "Not Implemented";
  case SC_NOT_MODIFIED:
      return "Not Modified";
  case SC_PARTIAL_CONTENT:
      return "Partial Content";
  case SC_PAYMENT_REQUIRED:
      return "Payment Required";
  case SC_PRECONDITION_FAILED:
      return "Precondition Failed";
  case SC_PROXY_AUTHENTICATION_REQUIRED:
      return "Proxy Authentication Required";
  case SC_REQUEST_ENTITY_TOO_LARGE:
      return "Request Entity Too Large";
  case SC_REQUEST_TIMEOUT:
      return "Request Timeout";
  case SC_REQUEST_URI_TOO_LARGE:
      return "Request URI Too Large";
  case SC_RANGE_NOT_SATISFIABLE:
      return "Requested Range Not Satisfiable";
  case SC_RESET_CONTENT:
      return "Reset Content";
  case SC_SEE_OTHER:
      return "See Other";
  case SC_SERVICE_UNAVAILABLE:
      return "Service Unavailable";
  case SC_SWITCHING_PROTOCOLS:
      return "Switching Protocols";
  case SC_UNAUTHORIZED:
      return "Unauthorized";
  case SC_UNSUPPORTED_MEDIA_TYPE:
      return "Unsupported Media Type";
  case SC_USE_PROXY:
      return "Use Proxy";
  default: {
      return "Unknown HTTP status";
    } 
  }
}


/* ----------------------------------------------------------------- Private */


/**
 * Receives standard HTTP requests from a client socket and dispatches
 * them to the doXXX methods defined in a cervlet module.
 */
static void do_service(Socket_T s) {
  volatile HttpResponse res= create_HttpResponse(s);
  volatile HttpRequest req= create_HttpRequest(s);
  
  if(res && req) {
    if(is_authenticated(req, res)) {
      if(IS(req->method, METHOD_GET)) {
	Impl.doGet(req, res);
      } else if(IS(req->method, METHOD_POST)) {
	Impl.doPost(req, res);
      } else {
	send_error(res, SC_NOT_IMPLEMENTED, "Method not implemented");
      }
    }
    send_response(res);
  }
  done(req, res);
}


/**
 * Return a (RFC1123) Date string
 */
static char *get_date(char *result, int size) {
  time_t now;
  
  time(&now);
  if(strftime(result, size, DATEFMT, gmtime(&now)) <= 0) {
    *result= 0;
  }
  return result;
}


/**
 * Return this server name + version
 */
static char *get_server(char *result, int size) {
  snprintf(result, size, "%s %s", SERVER_NAME, Run.httpdsig?SERVER_VERSION:"");
  return result;
}


/**
 * Send the response to the client. If the response has already been
 * commited, this function does nothing.
 */
static void send_response(HttpResponse res) {
  Socket_T S= res->S;

  if(!res->is_committed) {
    char date[STRLEN];
    char server[STRLEN];
    char *headers= get_headers(res);
    int length = StringBuffer_length(res->outputbuffer);

    res->is_committed= TRUE;
    get_date(date, STRLEN);
    get_server(server, STRLEN);
    socket_print(S, "%s %d %s\r\n", res->protocol, res->status,
		 res->status_msg);
    socket_print(S, "Date: %s\r\n", date);
    socket_print(S, "Server: %s\r\n", server);
    socket_print(S, "Content-Length: %d\r\n", length);
    socket_print(S, "Connection: close\r\n");
    if(headers)
	socket_print(S, "%s", headers);
    socket_print(S, "\r\n");
    if(length)
	socket_write(S, (unsigned char *)StringBuffer_toString(res->outputbuffer), length);
    FREE(headers);
  }
}


/* --------------------------------------------------------------- Factories */


/**
 * Returns a new HttpRequest object wrapping the client request
 */
static HttpRequest create_HttpRequest(Socket_T S) {
  HttpRequest req= NULL;
  char url[REQ_STRLEN];
  char line[REQ_STRLEN];
  char protocol[STRLEN]; 
  char method[REQ_STRLEN];

  if(socket_readln(S, line, REQ_STRLEN) == NULL) {
    internal_error(S, SC_BAD_REQUEST, "No request found");
    return NULL;
  }
  Str_chomp(line);
  if(sscanf(line, "%1023s %1023s HTTP/%3[1.0]", method, url, protocol) != 3) {
    internal_error(S, SC_BAD_REQUEST, "Cannot parse request");
    return NULL;
  }
  if(strlen(url) >= MAX_URL_LENGTH) {
    internal_error(S, SC_BAD_REQUEST, "[error] URL too long");
    return NULL;
  }
  NEW(req);
  req->S= S;
  Util_urlDecode(url);
  req->url= Str_dup(url);
  req->method= Str_dup(method);
  req->protocol= Str_dup(protocol); 
  create_headers(req);
  if(!create_parameters(req)) {
    destroy_HttpRequest(req);
    internal_error(S, SC_BAD_REQUEST, "Cannot parse Request parameters");
    return NULL;
  }
  return req;
}


/**
 * Returns a new HttpResponse object wrapping a default response. Use
 * the set_XXX methods to change the object.
 */
static HttpResponse create_HttpResponse(Socket_T S) {
  HttpResponse res= NULL;

  NEW(res);
  res->S= S;
  res->status= SC_OK;
  res->outputbuffer= StringBuffer_create(256);
  res->is_committed= FALSE;
  res->protocol= SERVER_PROTOCOL;
  res->status_msg= get_status_string(SC_OK);
  return res;
}


/**
 * Create HTTP headers for the given request
 */
static void create_headers(HttpRequest req) {
  Socket_T S;
  char *value;
  HttpHeader header= NULL;
  char line[REQ_STRLEN];

  S= req->S;
  while(1) {
    if(! socket_readln(S, line, sizeof(line)))
	break;
    if(!strcasecmp(line, "\r\n") || !strcasecmp(line, "\n"))
	break;
    if(NULL != (value= strchr(line, ':'))) {
      NEW(header);
      *value++= 0;
      Str_trim(line);
      Str_trim(value);
      Str_chomp(value);
      header->name= Str_dup(line);
      header->value= Str_dup(value);
      header->next= req->headers;
      req->headers= header;
    }
  }
}


/**
 * Create parameters for the given request. Returns FALSE if an error
 * occurs.
 */
static int create_parameters(HttpRequest req) {
  char query_string[REQ_STRLEN]= {0};

  if(IS(req->method, METHOD_POST) && get_header(req, "Content-Length")) {
    int n;
    int len; 
    Socket_T S = req->S;
    const char *cl = get_header(req, "Content-Length");
    if(! cl || sscanf(cl, "%d", &len) != 1) {
      return FALSE;
    }
    if(len < 0 || len >= REQ_STRLEN)
      return FALSE;
    if(len==0)
      return TRUE;
    if(((n= socket_read(S, query_string, len)) <= 0) || (n != len)) {
      return FALSE;
    }
    query_string[n]= 0;
  } else if(IS(req->method, METHOD_GET)) {
    char *p;
    if(NULL != (p= strchr(req->url, '?'))) {
      *p++= 0;
      strncpy(query_string, p, sizeof(query_string) - 1);
      query_string[sizeof(query_string) - 1] = 0;
    }
  }
  if(*query_string) {
    char *p;
    if(NULL != (p= strchr(query_string, '/'))) {
      *p++= 0;
      req->pathinfo= Str_dup(p);
    }
    req->params= parse_parameters(query_string);
  }
  return TRUE;
}


/* ----------------------------------------------------------------- Cleanup */


/**
 * Clear the response output buffer and headers
 */
static void reset_response(HttpResponse res) {
  if(res->headers) {
    destroy_entry(res->headers);
    res->headers= NULL; /* Release Pragma */
  }
  StringBuffer_clear(res->outputbuffer);
}


/**
 * Finalize the request and response object.
 */
static void done(HttpRequest req, HttpResponse res) {
  destroy_HttpRequest(req);
  destroy_HttpResponse(res);
}


/**
 * Free a HttpRequest object
 */
static void destroy_HttpRequest(HttpRequest req) {
  if(req) {
    FREE(req->method);
    FREE(req->url); 
    FREE(req->pathinfo);
    FREE(req->protocol);
    FREE(req->remote_user);
    if(req->headers)
      destroy_entry(req->headers);
    if(req->params)
      destroy_entry(req->params);
    FREE(req);
  }
}


/**
 * Free a HttpResponse object
 */
static void destroy_HttpResponse(HttpResponse res) {
  if(res) {
    StringBuffer_free(&(res->outputbuffer));
    if(res->headers) 
      destroy_entry(res->headers);
    FREE(res);
  }
}


/**
 * Free a (linked list of) http entry object(s). Both HttpHeader and
 * HttpParameter are of this type.
 */
static void destroy_entry(void *p) {
  struct entry *h= p; 
  
  if(h->next) {
    destroy_entry(h->next);
  }
  FREE(h->name);
  FREE(h->value);
  FREE(h);
}


/* ----------------------------------------------------- Checkers/Validators */


/**
 * Do Basic Authentication if this auth. style is allowed. 
 */
static int is_authenticated(HttpRequest req, HttpResponse res) {
  if(Run.credentials!=NULL) {
    if(! basic_authenticate(req)) {
      send_error(res, SC_UNAUTHORIZED,
		 "You are <b>not</b> authorized to access <i>monit</i>. "
		 "Either you supplied the wrong credentials (e.g. bad "
		 "password), or your browser doesn't understand how to supply "
		 "the credentials required");
      set_header(res, "WWW-Authenticate", "Basic realm=\"monit\"");
      return FALSE;
    }
  }
  return TRUE;
}


/**
 * Authenticate the basic-credentials (uname/password) submitted by
 * the user.
 */
static int basic_authenticate(HttpRequest req) {
  size_t n;
  char *password;
  char buf[STRLEN];
  char uname[STRLEN];
  const char *credentials= get_header(req, "Authorization");

  if(! (credentials && Str_startsWith(credentials, "Basic "))) {
    return FALSE;
  }
  strncpy(buf, &credentials[6], sizeof(buf) - 1);
  buf[sizeof(buf) - 1] = 0;
  if((n= decode_base64((unsigned char*)uname, buf))<=0) {
    return FALSE;
  }
  uname[n]= 0;
  password= strchr(uname, ':');
  if(password==NULL) {
    return FALSE;
  }
  *password++= 0;
  if(*uname==0 || *password==0) {
    return FALSE;
  }
  /* Check if user exist */
  if(NULL==Util_getUserCredentials(uname)) {
    LogError("Warning: Client '%s' supplied unknown user '%s'"
	" accessing monit httpd\n", socket_get_remote_host(req->S), uname); 
    return FALSE;
  }
  /* Check if user has supplied the right password */
  if(! Util_checkCredentials(uname,  password)) {
    LogError("Warning: Client '%s' supplied wrong password for user '%s'"
	" accessing monit httpd\n", socket_get_remote_host(req->S), uname); 
    return FALSE;
  }
  req->remote_user= Str_dup(uname);
  return TRUE;
}


/* --------------------------------------------------------------- Utilities */


/**
 * Send an error message to the client. This is a helper function,
 * used internal if the service function fails to setup the framework
 * properly; i.e. with a valid HttpRequest and a valid HttpResponse.
 */
static void internal_error(Socket_T S, int status, char *msg) {
  char date[STRLEN];
  char server[STRLEN];
  const char *status_msg= get_status_string(status);
  
  get_date(date, STRLEN);
  get_server(server, STRLEN);
  socket_print(S, 
	       "%s %d %s\r\n"
	       "Date: %s\r\n"
	       "Server: %s\r\n"
	       "Content-Type: text/html\r\n"
	       "Connection: close\r\n"
	       "\r\n"
	       "<html><head><title>%s</title></head>"
	       "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"
	       "<hr><a href='%s'><font size=-1>%s</font></a>"
	       "</body></html>\r\n",
	       SERVER_PROTOCOL, status, status_msg, date, server,
	       status_msg, status_msg, msg, SERVER_URL, server);
  DEBUG("HttpRequest error: %s %d %s\n", SERVER_PROTOCOL, status, msg ? msg : status_msg);
}


/**
 * Parse request parameters from the given query string and return a
 * linked list of HttpParameters
 */
static HttpParameter parse_parameters(char *query_string) {
#define KEY 1
#define VALUE 2
  int token;
  int cursor= 0;
  char *key= NULL;
  char *value= NULL;
  HttpParameter head= NULL;

  while((token= get_next_token(query_string, &cursor, &value))) {
    if(token==KEY)
      key= value;
    else if(token==VALUE) {
      HttpParameter p= NULL;
      if(!key) goto error;
      NEW(p);
      p->name= key;
      p->value= value;
      p->next= head;
      head= p;
      key= NULL;
    }
  }
  return head;
error:
  FREE(key);
  FREE(value);
  if ( head != NULL ) {
    destroy_entry(head);
  }
  return NULL;
}


/**
 * A mini-scanner for tokenizing a query string
 */
static int get_next_token(char *s, int *cursor, char **r) {
  int i= *cursor;

  while(s[*cursor]) {
    if(s[*cursor+1]=='=') {
      *cursor+= 1;
      *r= Str_ndup(&s[i], (*cursor-i));
      return KEY;
    } 
    if(s[*cursor]=='=') {
      while(s[*cursor] && s[*cursor]!='&') *cursor+= 1;
      if(s[*cursor]=='&') {
	*r= Str_ndup(&s[i+1], (*cursor-i)-1);
	*cursor+= 1;
      }  else
	*r= Str_ndup(&s[i+1], (*cursor-i));
      return VALUE;
    }
    *cursor+= 1;
  }
  return FALSE;
}
