/*
     This file is part of libmicrohttpd
     Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library 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
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/
/**
 * @file requests.c
 * @brief  Methods for managing HTTP requests
 * @author Daniel Pittman
 * @author Christian Grothoff
 * @author Karlson2k (Evgeny Grin)
 */
#include "internal.h"


/**
 * Get all of the headers from the request.
 *
 * @param request request to get values from
 * @param kind types of values to iterate over, can be a bitmask
 * @param iterator callback to call on each header;
 *        maybe NULL (then just count headers)
 * @param iterator_cls extra argument to @a iterator
 * @return number of entries iterated over
 * @ingroup request
 */
unsigned int
MHD_request_get_values (struct MHD_Request *request,
                        enum MHD_ValueKind kind,
                        MHD_KeyValueIterator iterator,
                        void *iterator_cls)
{
  int ret;
  struct MHD_HTTP_Header *pos;

  ret = 0;
  for (pos = request->headers_received;
       NULL != pos;
       pos = pos->next)
  {
    if (0 != (pos->kind & kind))
    {
      ret++;
      if ( (NULL != iterator) &&
           (MHD_YES != iterator (iterator_cls,
                                 pos->kind,
                                 pos->header,
                                 pos->value)) )
        return ret;
    }
  }
  return ret;
}


/**
 * This function can be used to add an entry to the HTTP headers of a
 * request (so that the #MHD_request_get_values function will
 * return them -- and the `struct MHD_PostProcessor` will also see
 * them).  This maybe required in certain situations (see Mantis
 * #1399) where (broken) HTTP implementations fail to supply values
 * needed by the post processor (or other parts of the application).
 *
 * This function MUST only be called from within the
 * request callbacks (otherwise, access maybe improperly
 * synchronized).  Furthermore, the client must guarantee that the key
 * and value arguments are 0-terminated strings that are NOT freed
 * until the connection is closed.  (The easiest way to do this is by
 * passing only arguments to permanently allocated strings.).
 *
 * @param request the request for which a
 *  value should be set
 * @param kind kind of the value
 * @param key key for the value
 * @param value the value itself
 * @return #MHD_NO if the operation could not be
 *         performed due to insufficient memory;
 *         #MHD_YES on success
 * @ingroup request
 */
enum MHD_Bool
MHD_request_set_value (struct MHD_Request *request,
                       enum MHD_ValueKind kind,
                       const char *key,
                       const char *value)
{
  struct MHD_HTTP_Header *pos;

  pos = MHD_pool_allocate (request->connection->pool,
                           sizeof (struct MHD_HTTP_Header),
                           MHD_YES);
  if (NULL == pos)
    return MHD_NO;
  pos->header = (char *) key;
  pos->value = (char *) value;
  pos->kind = kind;
  pos->next = NULL;
  /* append 'pos' to the linked list of headers */
  if (NULL == request->headers_received_tail)
  {
    request->headers_received = pos;
    request->headers_received_tail = pos;
  }
  else
  {
    request->headers_received_tail->next = pos;
    request->headers_received_tail = pos;
  }
  return MHD_YES;
}


/**
 * Get a particular header value.  If multiple
 * values match the kind, return any one of them.
 *
 * @param request request to get values from
 * @param kind what kind of value are we looking for
 * @param key the header to look for, NULL to lookup 'trailing' value without a key
 * @return NULL if no such item was found
 * @ingroup request
 */
const char *
MHD_request_lookup_value (struct MHD_Request *request,
                          enum MHD_ValueKind kind,
                          const char *key)
{
  struct MHD_HTTP_Header *pos;

  for (pos = request->headers_received;
       NULL != pos;
       pos = pos->next)
  {
    if ((0 != (pos->kind & kind)) &&
        ( (key == pos->header) ||
          ( (NULL != pos->header) &&
            (NULL != key) &&
            (MHD_str_equal_caseless_ (key,
                                      pos->header)))))
      return pos->value;
  }
  return NULL;
}


/* end of request.c */
