/*
 * Copyright (c) 1999 Caucho Technology.  All rights reserved.
 *
 * Caucho Technology permits redistribution, modification and use
 * of this file in source and binary form ("the Software") under the
 * Caucho Public License ("the License").  In particular, the following
 * conditions must be met:
 *
 * 1. Each copy or derived work of the Software must preserve the copyright
 *    notice and this notice unmodified.
 *
 * 2. Redistributions of the Software in source or binary form must include 
 *    an unmodified copy of the License, normally in a plain ASCII text
 *
 * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and
 *    may not be used to endorse products derived from this software.
 *    "Resin" or "Caucho" may not appear in the names of products derived
 *    from this software.
 *
 * 4. Caucho Technology requests that attribution be given to Resin
 *    in any manner possible.  We suggest using the "Resin Powered"
 *    button or creating a "powered by Resin(tm)" link to
 *    http://www.caucho.com for each page served by Resin.
 *
 * This Software is provided "AS IS," without a warranty of any kind. 
 * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.

 * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR
 * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE
 * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
 * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGES.
 *
 * @author Scott Ferguson
 *
 * $Id: request.c,v 1.1 1999/12/30 23:31:31 ferg Exp $
 */

#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include "rws.h"

int
rws_scan_request(stream_t *stream, request_t *request)
{
  int ch;
  int i;

  while (isspace(ch = rws_read_byte(stream))) {
  }

  i = 0;
  request->method = rws_pin_alloc(request->pool, SMALL_LENGTH);
  for (;
       ch > 0 && ! isspace(ch) && i < SMALL_LENGTH;
       ch = rws_read_byte(stream)) {
    request->method[i++] = ch;
  }
  request->method[i] = 0;
  rws_free_pin(request->pool, i + 1);

  for (; isspace(ch); ch = rws_read_byte(stream)) {
  }

  i = 0;
  request->uri = rws_pin_alloc(request->pool, SMALL_LENGTH);
  for (;
       ch > 0 && ! isspace(ch) && i < SMALL_LENGTH;
       ch = rws_read_byte(stream)) {
    if (ch != '?' || request->query)
      request->uri[i++] = ch;
    else {
      request->uri[i++] = 0;
      request->query = &request->uri[i];
    }
  }
  request->uri[i] = 0;
  rws_free_pin(request->pool, i + 1);

  for (; ch == ' ' || ch == '\t'; ch = rws_read_byte(stream)) {
  }

  i = 0;
  request->protocol = rws_pin_alloc(request->pool, SMALL_LENGTH);
  for (;
       ch > 0 && ! isspace(ch) && i < SMALL_LENGTH;
       ch = rws_read_byte(stream)) {
    request->protocol[i++] = ch;
  }
  request->protocol[i] = 0;
  rws_free_pin(request->pool, i + 1);
  
  for (; ch > 0 && ch != '\n'; ch = rws_read_byte(stream)) {
  }

  return 1;
}  

int
rws_scan_headers(stream_t *stream, request_t *request)
{
  pool_t *pool = request->pool;
  int ch;
  int i;

  while ((ch = rws_read_byte(stream)) >= 0) {
    header_t *header;
    char *key;
    char *value;
      
    if (ch == '\n') {
      return 1;
    }
    else if (ch == '\r') {
      /* should be '\n' */
      ch = rws_read_byte(stream);
      return 1; 
    }

    key = rws_pin_alloc(pool, SMALL_LENGTH);
    i = 0;
    for (;
	 ch >= 0 && ! isspace(ch) && ch != ':';  
	 ch = rws_read_byte(stream)) {
      key[i++] = ch;
    }
    key[i++] = 0;
    rws_free_pin(pool, i);
    
    if (ch != ':')
      return 0;

    while ((ch = rws_read_byte(stream)) >= 0 && (ch == ' ' || ch == '\t')) {
    }
        
    value = rws_pin_alloc(pool, SMALL_LENGTH);
    i = 0;
    for (;
	 ch >= 0 && ch != '\n';
	 ch = rws_read_byte(stream)) {
      value[i++] = ch;
    }
    if (value[i] == '\r')
      value[i] = 0;
    else
      value[i++] = 0;
    
    rws_free_pin(pool, i);

    header = rws_malloc(pool, sizeof(header_t));
    header->next = request->headers;    
    request->headers = header;
    header->key = key;
    header->value = value;

    return 1;
  }
}
