httpReadRequest(http_t *http,		/* I - HTTP connection */
                char   *uri,		/* I - URI buffer */
		size_t urilen)		/* I - Size of URI buffer */
{
  char	line[4096],			/* HTTP request line */
	*req_method,			/* HTTP request method */
	*req_uri,			/* HTTP request URI */
	*req_version;			/* HTTP request version number string */


 /*
  * Range check input...
  */

  DEBUG_printf(("httpReadRequest(http=%p, uri=%p, urilen=" CUPS_LLFMT ")", (void *)http, (void *)uri, CUPS_LLCAST urilen));

  if (uri)
    *uri = '\0';

  if (!http || !uri || urilen < 1)
  {
    DEBUG_puts("1httpReadRequest: Bad arguments, returning HTTP_STATE_ERROR.");
    return (HTTP_STATE_ERROR);
  }
  else if (http->state != HTTP_STATE_WAITING)
  {
    DEBUG_printf(("1httpReadRequest: Bad state %s, returning HTTP_STATE_ERROR.",
                  httpStateString(http->state)));
    return (HTTP_STATE_ERROR);
  }

 /*
  * Reset state...
  */

  httpClearFields(http);

  http->activity       = time(NULL);
  http->data_encoding  = HTTP_ENCODING_FIELDS;
  http->data_remaining = 0;
  http->keep_alive     = HTTP_KEEPALIVE_OFF;
  http->status         = HTTP_STATUS_OK;
  http->version        = HTTP_VERSION_1_1;

 /*
  * Read a line from the socket...
  */

  if (!httpGets(line, sizeof(line), http))
  {
    DEBUG_puts("1httpReadRequest: Unable to read, returning HTTP_STATE_ERROR");
    return (HTTP_STATE_ERROR);
  }

  if (!line[0])
  {
    DEBUG_puts("1httpReadRequest: Blank line, returning HTTP_STATE_WAITING");
    return (HTTP_STATE_WAITING);
  }

  DEBUG_printf(("1httpReadRequest: %s", line));

 /*
  * Parse it...
  */

  req_method = line;
  req_uri    = line;

  while (*req_uri && !isspace(*req_uri & 255))
    req_uri ++;

  if (!*req_uri)
  {
    DEBUG_puts("1httpReadRequest: No request URI.");
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No request URI."), 1);
    return (HTTP_STATE_ERROR);
  }

  *req_uri++ = '\0';

  while (*req_uri && isspace(*req_uri & 255))
    req_uri ++;

  req_version = req_uri;

  while (*req_version && !isspace(*req_version & 255))
    req_version ++;

  if (!*req_version)
  {
    DEBUG_puts("1httpReadRequest: No request protocol version.");
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No request protocol version."), 1);
    return (HTTP_STATE_ERROR);
  }

  *req_version++ = '\0';

  while (*req_version && isspace(*req_version & 255))
    req_version ++;

 /*
  * Validate...
  */

  if (!strcmp(req_method, "OPTIONS"))
    http->state = HTTP_STATE_OPTIONS;
  else if (!strcmp(req_method, "GET"))
    http->state = HTTP_STATE_GET;
  else if (!strcmp(req_method, "HEAD"))
    http->state = HTTP_STATE_HEAD;
  else if (!strcmp(req_method, "POST"))
    http->state = HTTP_STATE_POST;
  else if (!strcmp(req_method, "PUT"))
    http->state = HTTP_STATE_PUT;
  else if (!strcmp(req_method, "DELETE"))
    http->state = HTTP_STATE_DELETE;
  else if (!strcmp(req_method, "TRACE"))
    http->state = HTTP_STATE_TRACE;
  else if (!strcmp(req_method, "CONNECT"))
    http->state = HTTP_STATE_CONNECT;
  else
  {
    DEBUG_printf(("1httpReadRequest: Unknown method \"%s\".", req_method));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown request method."), 1);
    return (HTTP_STATE_UNKNOWN_METHOD);
  }

  DEBUG_printf(("1httpReadRequest: Set state to %s.",
                httpStateString(http->state)));

  if (!strcmp(req_version, "HTTP/1.0"))
  {
    http->version    = HTTP_VERSION_1_0;
    http->keep_alive = HTTP_KEEPALIVE_OFF;
  }
  else if (!strcmp(req_version, "HTTP/1.1"))
  {
    http->version    = HTTP_VERSION_1_1;
    http->keep_alive = HTTP_KEEPALIVE_ON;
  }
  else
  {
    DEBUG_printf(("1httpReadRequest: Unknown version \"%s\".", req_version));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown request version."), 1);
    return (HTTP_STATE_UNKNOWN_VERSION);
  }

  DEBUG_printf(("1httpReadRequest: URI is \"%s\".", req_uri));
  strlcpy(uri, req_uri, urilen);

  return (http->state);
}