/* GStreamer
 * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
 *               <2006> Lutz Mueller <lutz at topfrose dot de>
 *               <2015> Tim-Philipp Müller <tim@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/*
 * Unless otherwise indicated, Source Code is licensed under MIT license.
 * See further explanation attached in License Statement (distributed in the file
 * LICENSE).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * SECTION:gstrtspmessage
 * @title: GstRTSPMessage
 * @short_description: RTSP messages
 * @see_also: gstrtspconnection
 *
 * Provides methods for creating and parsing request, response and data messages.
 */

#include <string.h>

#include <gst/gstutils.h>
#include "gstrtspmessage.h"

typedef struct _RTSPKeyValue
{
  GstRTSPHeaderField field;
  gchar *value;
  gchar *custom_key;            /* custom header string (field is INVALID then) */
} RTSPKeyValue;

static void
key_value_foreach (GArray * array, GFunc func, gpointer user_data)
{
  guint i;

  g_return_if_fail (array != NULL);

  for (i = 0; i < array->len; i++) {
    (*func) (&g_array_index (array, RTSPKeyValue, i), user_data);
  }
}

static void
key_value_append (const RTSPKeyValue * kv, GArray * array)
{
  RTSPKeyValue kvcopy;
  g_return_if_fail (kv != NULL);
  g_return_if_fail (array != NULL);

  kvcopy.field = kv->field;
  kvcopy.value = g_strdup (kv->value);
  kvcopy.custom_key = g_strdup (kv->custom_key);

  g_array_append_val (array, kvcopy);
}

static GstRTSPMessage *
gst_rtsp_message_boxed_copy (GstRTSPMessage * orig)
{
  GstRTSPMessage *copy;

  if (gst_rtsp_message_copy (orig, &copy) == GST_RTSP_OK)
    return copy;

  return NULL;
}

static void
gst_rtsp_message_boxed_free (GstRTSPMessage * msg)
{
  gst_rtsp_message_free (msg);
}

G_DEFINE_BOXED_TYPE (GstRTSPMessage, gst_rtsp_msg, gst_rtsp_message_boxed_copy,
    gst_rtsp_message_boxed_free);

/**
 * gst_rtsp_message_new:
 * @msg: (out) (transfer full): a location for the new #GstRTSPMessage
 *
 * Create a new initialized #GstRTSPMessage. Free with gst_rtsp_message_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_new (GstRTSPMessage ** msg)
{
  GstRTSPMessage *newmsg;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  newmsg = g_new0 (GstRTSPMessage, 1);

  *msg = newmsg;

  return gst_rtsp_message_init (newmsg);
}

/**
 * gst_rtsp_message_init:
 * @msg: a #GstRTSPMessage
 *
 * Initialize @msg. This function is mostly used when @msg is allocated on the
 * stack. The reverse operation of this is gst_rtsp_message_unset().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_init (GstRTSPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  gst_rtsp_message_unset (msg);

  msg->type = GST_RTSP_MESSAGE_INVALID;
  msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_get_type:
 * @msg: a #GstRTSPMessage
 *
 * Get the message type of @msg.
 *
 * Returns: the message type.
 */
GstRTSPMsgType
gst_rtsp_message_get_type (GstRTSPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_MESSAGE_INVALID);

  return msg->type;
}

/**
 * gst_rtsp_message_new_request:
 * @msg: (out) (transfer full): a location for the new #GstRTSPMessage
 * @method: the request method to use
 * @uri: (transfer none): the uri of the request
 *
 * Create a new #GstRTSPMessage with @method and @uri and store the result
 * request message in @msg. Free with gst_rtsp_message_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method,
    const gchar * uri)
{
  GstRTSPMessage *newmsg;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (uri != NULL, GST_RTSP_EINVAL);

  newmsg = g_new0 (GstRTSPMessage, 1);

  *msg = newmsg;

  return gst_rtsp_message_init_request (newmsg, method, uri);
}

/**
 * gst_rtsp_message_init_request:
 * @msg: a #GstRTSPMessage
 * @method: the request method to use
 * @uri: (transfer none): the uri of the request
 *
 * Initialize @msg as a request message with @method and @uri. To clear @msg
 * again, use gst_rtsp_message_unset().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_init_request (GstRTSPMessage * msg, GstRTSPMethod method,
    const gchar * uri)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (uri != NULL, GST_RTSP_EINVAL);

  gst_rtsp_message_unset (msg);

  msg->type = GST_RTSP_MESSAGE_REQUEST;
  msg->type_data.request.method = method;
  msg->type_data.request.uri = g_strdup (uri);
  msg->type_data.request.version = GST_RTSP_VERSION_1_0;
  msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_parse_request:
 * @msg: a #GstRTSPMessage
 * @method: (out) (allow-none): location to hold the method
 * @uri: (out) (allow-none) (transfer none): location to hold the uri
 * @version: (out) (allow-none) (transfer none): location to hold the version
 *
 * Parse the request message @msg and store the values @method, @uri and
 * @version. The result locations can be %NULL if one is not interested in its
 * value.
 *
 * @uri remains valid for as long as @msg is valid and unchanged.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_parse_request (GstRTSPMessage * msg,
    GstRTSPMethod * method, const gchar ** uri, GstRTSPVersion * version)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_REQUEST ||
      msg->type == GST_RTSP_MESSAGE_HTTP_REQUEST, GST_RTSP_EINVAL);

  if (method)
    *method = msg->type_data.request.method;
  if (uri)
    *uri = msg->type_data.request.uri;
  if (version)
    *version = msg->type_data.request.version;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_new_response:
 * @msg: (out) (transfer full): a location for the new #GstRTSPMessage
 * @code: the status code
 * @reason: (transfer none) (allow-none): the status reason or %NULL
 * @request: (transfer none) (allow-none): the request that triggered the response or %NULL
 *
 * Create a new response #GstRTSPMessage with @code and @reason and store the
 * result message in @msg. Free with gst_rtsp_message_free().
 *
 * When @reason is %NULL, the default reason for @code will be used.
 *
 * When @request is not %NULL, the relevant headers will be copied to the new
 * response message.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code,
    const gchar * reason, const GstRTSPMessage * request)
{
  GstRTSPMessage *newmsg;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  newmsg = g_new0 (GstRTSPMessage, 1);

  *msg = newmsg;

  return gst_rtsp_message_init_response (newmsg, code, reason, request);
}

/**
 * gst_rtsp_message_init_response:
 * @msg: a #GstRTSPMessage
 * @code: the status code
 * @reason: (transfer none) (allow-none): the status reason or %NULL
 * @request: (transfer none) (allow-none): the request that triggered the response or %NULL
 *
 * Initialize @msg with @code and @reason.
 *
 * When @reason is %NULL, the default reason for @code will be used.
 *
 * When @request is not %NULL, the relevant headers will be copied to the new
 * response message.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_init_response (GstRTSPMessage * msg, GstRTSPStatusCode code,
    const gchar * reason, const GstRTSPMessage * request)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  gst_rtsp_message_unset (msg);

  if (reason == NULL)
    reason = gst_rtsp_status_as_text (code);

  msg->type = GST_RTSP_MESSAGE_RESPONSE;
  msg->type_data.response.code = code;
  msg->type_data.response.reason = g_strdup (reason);
  msg->type_data.response.version = GST_RTSP_VERSION_1_0;
  msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));

  if (request) {
    if (request->type == GST_RTSP_MESSAGE_HTTP_REQUEST) {
      msg->type = GST_RTSP_MESSAGE_HTTP_RESPONSE;
      if (request->type_data.request.version != GST_RTSP_VERSION_INVALID)
        msg->type_data.response.version = request->type_data.request.version;
      else
        msg->type_data.response.version = GST_RTSP_VERSION_1_1;
    } else {
      gchar *header;

      /* copy CSEQ */
      if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_CSEQ, &header,
              0) == GST_RTSP_OK) {
        gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CSEQ, header);
      }

      /* copy session id */
      if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &header,
              0) == GST_RTSP_OK) {
        char *pos;

        header = g_strdup (header);
        if ((pos = strchr (header, ';'))) {
          *pos = '\0';
        }
        g_strchomp (header);
        gst_rtsp_message_take_header (msg, GST_RTSP_HDR_SESSION, header);
      }

      /* FIXME copy more headers? */
    }
  }

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_parse_response:
 * @msg: a #GstRTSPMessage
 * @code: (out) (allow-none): location to hold the status code
 * @reason: (out) (allow-none) (transfer none): location to hold the status reason
 * @version: (out) (allow-none) (transfer none): location to hold the version
 *
 * Parse the response message @msg and store the values @code, @reason and
 * @version. The result locations can be %NULL if one is not interested in its
 * value.
 *
 * @reason remains valid for as long as @msg is valid and unchanged.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_parse_response (GstRTSPMessage * msg,
    GstRTSPStatusCode * code, const gchar ** reason, GstRTSPVersion * version)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_RESPONSE ||
      msg->type == GST_RTSP_MESSAGE_HTTP_RESPONSE, GST_RTSP_EINVAL);

  if (code)
    *code = msg->type_data.response.code;
  if (reason)
    *reason = msg->type_data.response.reason;
  if (version)
    *version = msg->type_data.response.version;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_new_data:
 * @msg: (out) (transfer full): a location for the new #GstRTSPMessage
 * @channel: the channel
 *
 * Create a new data #GstRTSPMessage with @channel and store the
 * result message in @msg. Free with gst_rtsp_message_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_new_data (GstRTSPMessage ** msg, guint8 channel)
{
  GstRTSPMessage *newmsg;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  newmsg = g_new0 (GstRTSPMessage, 1);

  *msg = newmsg;

  return gst_rtsp_message_init_data (newmsg, channel);
}

/**
 * gst_rtsp_message_init_data:
 * @msg: a #GstRTSPMessage
 * @channel: a channel
 *
 * Initialize a new data #GstRTSPMessage for @channel.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_init_data (GstRTSPMessage * msg, guint8 channel)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  gst_rtsp_message_unset (msg);

  msg->type = GST_RTSP_MESSAGE_DATA;
  msg->type_data.data.channel = channel;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_parse_data:
 * @msg: a #GstRTSPMessage
 * @channel: (out): location to hold the channel
 *
 * Parse the data message @msg and store the channel in @channel.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_parse_data (GstRTSPMessage * msg, guint8 * channel)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_DATA, GST_RTSP_EINVAL);

  if (channel)
    *channel = msg->type_data.data.channel;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_unset:
 * @msg: a #GstRTSPMessage
 *
 * Unset the contents of @msg so that it becomes an uninitialized
 * #GstRTSPMessage again. This function is mostly used in combination with
 * gst_rtsp_message_init_request(), gst_rtsp_message_init_response() and
 * gst_rtsp_message_init_data() on stack allocated #GstRTSPMessage structures.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_unset (GstRTSPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  switch (msg->type) {
    case GST_RTSP_MESSAGE_INVALID:
      break;
    case GST_RTSP_MESSAGE_REQUEST:
    case GST_RTSP_MESSAGE_HTTP_REQUEST:
      g_free (msg->type_data.request.uri);
      break;
    case GST_RTSP_MESSAGE_RESPONSE:
    case GST_RTSP_MESSAGE_HTTP_RESPONSE:
      g_free (msg->type_data.response.reason);
      break;
    case GST_RTSP_MESSAGE_DATA:
      break;
    default:
      g_return_val_if_reached (GST_RTSP_EINVAL);
  }

  if (msg->hdr_fields != NULL) {
    guint i;

    for (i = 0; i < msg->hdr_fields->len; i++) {
      RTSPKeyValue *keyval = &g_array_index (msg->hdr_fields, RTSPKeyValue, i);

      g_free (keyval->value);
      g_free (keyval->custom_key);
    }
    g_array_free (msg->hdr_fields, TRUE);
  }
  g_free (msg->body);

  memset (msg, 0, sizeof (GstRTSPMessage));

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_free:
 * @msg: a #GstRTSPMessage
 *
 * Free the memory used by @msg.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_free (GstRTSPMessage * msg)
{
  GstRTSPResult res;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  res = gst_rtsp_message_unset (msg);
  if (res == GST_RTSP_OK)
    g_free (msg);

  return res;
}

/**
 * gst_rtsp_message_copy:
 * @msg: a #GstRTSPMessage
 * @copy: (out) (transfer full): pointer to new #GstRTSPMessage
 *
 * Allocate a new copy of @msg and store the result in @copy. The value in
 * @copy should be release with gst_rtsp_message_free function.
 *
 * Returns: a #GstRTSPResult
 *
 * Since: 1.14
 */
GstRTSPResult
gst_rtsp_message_copy (const GstRTSPMessage * msg, GstRTSPMessage ** copy)
{
  GstRTSPResult ret;
  GstRTSPMessage *cp;

  if (msg == NULL)
    return GST_RTSP_EINVAL;

  ret = gst_rtsp_message_new (copy);
  if (ret != GST_RTSP_OK)
    return ret;

  cp = *copy;

  cp->type = msg->type;
  switch (cp->type) {
    case GST_RTSP_MESSAGE_INVALID:
      break;
    case GST_RTSP_MESSAGE_REQUEST:
    case GST_RTSP_MESSAGE_HTTP_REQUEST:
      cp->type_data.request.method = msg->type_data.request.method;
      cp->type_data.request.uri = g_strdup (msg->type_data.request.uri);
      cp->type_data.request.version = msg->type_data.request.version;
      break;
    case GST_RTSP_MESSAGE_RESPONSE:
    case GST_RTSP_MESSAGE_HTTP_RESPONSE:
      cp->type_data.response.code = msg->type_data.response.code;
      cp->type_data.response.reason = g_strdup (msg->type_data.response.reason);
      cp->type_data.response.version = msg->type_data.response.version;
      break;
    case GST_RTSP_MESSAGE_DATA:
      cp->type_data.data.channel = msg->type_data.data.channel;
      break;
    default:
      return GST_RTSP_EINVAL;
  }

  key_value_foreach (msg->hdr_fields, (GFunc) key_value_append, cp->hdr_fields);
  gst_rtsp_message_set_body (cp, msg->body, msg->body_size);

  return GST_RTSP_OK;
}


/**
 * gst_rtsp_message_take_header:
 * @msg: a #GstRTSPMessage
 * @field: a #GstRTSPHeaderField
 * @value: (transfer full): the value of the header
 *
 * Add a header with key @field and @value to @msg. This function takes
 * ownership of @value.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_take_header (GstRTSPMessage * msg, GstRTSPHeaderField field,
    gchar * value)
{
  RTSPKeyValue key_value;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL);

  key_value.field = field;
  key_value.value = value;
  key_value.custom_key = NULL;

  g_array_append_val (msg->hdr_fields, key_value);

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_add_header:
 * @msg: a #GstRTSPMessage
 * @field: a #GstRTSPHeaderField
 * @value: (transfer none): the value of the header
 *
 * Add a header with key @field and @value to @msg. This function takes a copy
 * of @value.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field,
    const gchar * value)
{
  return gst_rtsp_message_take_header (msg, field, g_strdup (value));
}

/**
 * gst_rtsp_message_remove_header:
 * @msg: a #GstRTSPMessage
 * @field: a #GstRTSPHeaderField
 * @indx: the index of the header
 *
 * Remove the @indx header with key @field from @msg. If @indx equals -1, all
 * headers will be removed.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_message_remove_header (GstRTSPMessage * msg, GstRTSPHeaderField field,
    gint indx)
{
  GstRTSPResult res = GST_RTSP_ENOTIMPL;
  guint i = 0;
  gint cnt = 0;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  while (i < msg->hdr_fields->len) {
    RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i);

    if (key_value->field == field && (indx == -1 || cnt++ == indx)) {
      g_free (key_value->value);
      g_array_remove_index (msg->hdr_fields, i);
      res = GST_RTSP_OK;
      if (indx != -1)
        break;
    } else {
      i++;
    }
  }
  return res;
}

/**
 * gst_rtsp_message_get_header:
 * @msg: a #GstRTSPMessage
 * @field: a #GstRTSPHeaderField
 * @value: (out) (transfer none): pointer to hold the result
 * @indx: the index of the header
 *
 * Get the @indx header value with key @field from @msg. The result in @value
 * stays valid as long as it remains present in @msg.
 *
 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key
 * was not found.
 */
GstRTSPResult
gst_rtsp_message_get_header (const GstRTSPMessage * msg,
    GstRTSPHeaderField field, gchar ** value, gint indx)
{
  guint i;
  gint cnt = 0;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  /* no header initialized, there are no headers */
  if (msg->hdr_fields == NULL)
    return GST_RTSP_ENOTIMPL;

  for (i = 0; i < msg->hdr_fields->len; i++) {
    RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i);

    if (key_value->field == field && cnt++ == indx) {
      if (value)
        *value = key_value->value;
      return GST_RTSP_OK;
    }
  }

  return GST_RTSP_ENOTIMPL;
}

/**
 * gst_rtsp_message_add_header_by_name:
 * @msg: a #GstRTSPMessage
 * @header: (transfer none): header string
 * @value: (transfer none): the value of the header
 *
 * Add a header with key @header and @value to @msg. This function takes a copy
 * of @value.
 *
 * Returns: a #GstRTSPResult.
 *
 * Since: 1.6
 */
GstRTSPResult
gst_rtsp_message_add_header_by_name (GstRTSPMessage * msg,
    const gchar * header, const gchar * value)
{
  GstRTSPHeaderField field;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (header != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL);

  field = gst_rtsp_find_header_field (header);
  if (field != GST_RTSP_HDR_INVALID)
    return gst_rtsp_message_take_header (msg, field, g_strdup (value));

  return gst_rtsp_message_take_header_by_name (msg, header, g_strdup (value));
}

/**
 * gst_rtsp_message_take_header_by_name:
 * @msg: a #GstRTSPMessage
 * @header: (transfer none): a header string
 * @value: (transfer full): the value of the header
 *
 * Add a header with key @header and @value to @msg. This function takes
 * ownership of @value, but not of @header.
 *
 * Returns: a #GstRTSPResult.
 *
 * Since: 1.6
 */
GstRTSPResult
gst_rtsp_message_take_header_by_name (GstRTSPMessage * msg,
    const gchar * header, gchar * value)
{
  RTSPKeyValue key_value;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (header != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL);

  key_value.field = GST_RTSP_HDR_INVALID;
  key_value.value = value;
  key_value.custom_key = g_strdup (header);

  g_array_append_val (msg->hdr_fields, key_value);

  return GST_RTSP_OK;
}

/* returns -1 if not found, otherwise index position within msg->hdr_fields */
static gint
gst_rtsp_message_find_header_by_name (GstRTSPMessage * msg,
    const gchar * header, gint index)
{
  GstRTSPHeaderField field;
  gint cnt = 0;
  guint i;

  /* no header initialized, there are no headers */
  if (msg->hdr_fields == NULL)
    return -1;

  field = gst_rtsp_find_header_field (header);
  for (i = 0; i < msg->hdr_fields->len; i++) {
    RTSPKeyValue *key_val;

    key_val = &g_array_index (msg->hdr_fields, RTSPKeyValue, i);

    if (key_val->field != field)
      continue;

    if (key_val->custom_key != NULL &&
        g_ascii_strcasecmp (key_val->custom_key, header) != 0)
      continue;

    if (index < 0 || cnt++ == index)
      return i;
  }

  return -1;
}

/**
 * gst_rtsp_message_remove_header_by_name:
 * @msg: a #GstRTSPMessage
 * @header: the header string
 * @index: the index of the header
 *
 * Remove the @index header with key @header from @msg. If @index equals -1,
 * all matching headers will be removed.
 *
 * Returns: a #GstRTSPResult
 *
 * Since: 1.6
 */
GstRTSPResult
gst_rtsp_message_remove_header_by_name (GstRTSPMessage * msg,
    const gchar * header, gint index)
{
  GstRTSPResult res = GST_RTSP_ENOTIMPL;
  RTSPKeyValue *kv;
  gint pos;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (header != NULL, GST_RTSP_EINVAL);

  do {
    pos = gst_rtsp_message_find_header_by_name (msg, header, index);

    if (pos < 0)
      break;

    kv = &g_array_index (msg->hdr_fields, RTSPKeyValue, pos);
    g_free (kv->value);
    g_free (kv->custom_key);
    g_array_remove_index (msg->hdr_fields, pos);
    res = GST_RTSP_OK;
  } while (index < 0);

  return res;
}

/**
 * gst_rtsp_message_get_header_by_name:
 * @msg: a #GstRTSPMessage
 * @header: a #GstRTSPHeaderField
 * @value: (out) (transfer none): pointer to hold the result
 * @index: the index of the header
 *
 * Get the @index header value with key @header from @msg. The result in @value
 * stays valid as long as it remains present in @msg.
 *
 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key
 * was not found.
 *
 * Since: 1.6
 */
GstRTSPResult
gst_rtsp_message_get_header_by_name (GstRTSPMessage * msg,
    const gchar * header, gchar ** value, gint index)
{
  RTSPKeyValue *key_val;
  gint pos;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (header != NULL, GST_RTSP_EINVAL);

  pos = gst_rtsp_message_find_header_by_name (msg, header, index);

  if (pos < 0)
    return GST_RTSP_ENOTIMPL;

  key_val = &g_array_index (msg->hdr_fields, RTSPKeyValue, pos);

  if (value)
    *value = key_val->value;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_append_headers:
 * @msg: a #GstRTSPMessage
 * @str: (transfer none): a string
 *
 * Append the currently configured headers in @msg to the #GString @str suitable
 * for transmission.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_append_headers (const GstRTSPMessage * msg, GString * str)
{
  guint i;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL);

  for (i = 0; i < msg->hdr_fields->len; i++) {
    RTSPKeyValue *key_value;
    const gchar *keystr;

    key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i);

    if (key_value->custom_key != NULL)
      keystr = key_value->custom_key;
    else
      keystr = gst_rtsp_header_as_text (key_value->field);

    g_string_append_printf (str, "%s: %s\r\n", keystr, key_value->value);
  }
  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_set_body:
 * @msg: a #GstRTSPMessage
 * @data: (array length=size) (transfer none): the data
 * @size: the size of @data
 *
 * Set the body of @msg to a copy of @data.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_set_body (GstRTSPMessage * msg, const guint8 * data,
    guint size)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  return gst_rtsp_message_take_body (msg, g_memdup (data, size), size);
}

/**
 * gst_rtsp_message_take_body:
 * @msg: a #GstRTSPMessage
 * @data: (array length=size) (transfer full): the data
 * @size: the size of @data
 *
 * Set the body of @msg to @data and @size. This method takes ownership of
 * @data.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_take_body (GstRTSPMessage * msg, guint8 * data, guint size)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (data != NULL || size == 0, GST_RTSP_EINVAL);

  g_free (msg->body);

  msg->body = data;
  msg->body_size = size;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_get_body:
 * @msg: a #GstRTSPMessage
 * @data: (out) (transfer none) (array length=size): location for the data
 * @size: (out): location for the size of @data
 *
 * Get the body of @msg. @data remains valid for as long as @msg is valid and
 * unchanged.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_get_body (const GstRTSPMessage * msg, guint8 ** data,
    guint * size)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);

  *data = msg->body;
  *size = msg->body_size;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_message_steal_body:
 * @msg: a #GstRTSPMessage
 * @data: (out) (transfer full) (array length=size): location for the data
 * @size: (out): location for the size of @data
 *
 * Take the body of @msg and store it in @data and @size. After this method,
 * the body and size of @msg will be set to %NULL and 0 respectively.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_steal_body (GstRTSPMessage * msg, guint8 ** data, guint * size)
{
  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);

  *data = msg->body;
  *size = msg->body_size;

  msg->body = NULL;
  msg->body_size = 0;

  return GST_RTSP_OK;
}

static void
dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED)
{
  RTSPKeyValue *key_value = (RTSPKeyValue *) data;
  const gchar *key_string;

  if (key_value->custom_key != NULL)
    key_string = key_value->custom_key;
  else
    key_string = gst_rtsp_header_as_text (key_value->field);

  g_print ("   key: '%s', value: '%s'\n", key_string, key_value->value);
}

/**
 * gst_rtsp_message_dump:
 * @msg: a #GstRTSPMessage
 *
 * Dump the contents of @msg to stdout.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_message_dump (GstRTSPMessage * msg)
{
  guint8 *data;
  guint size;

  g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);

  switch (msg->type) {
    case GST_RTSP_MESSAGE_REQUEST:
      g_print ("RTSP request message %p\n", msg);
      g_print (" request line:\n");
      g_print ("   method: '%s'\n",
          gst_rtsp_method_as_text (msg->type_data.request.method));
      g_print ("   uri:    '%s'\n", msg->type_data.request.uri);
      g_print ("   version: '%s'\n",
          gst_rtsp_version_as_text (msg->type_data.request.version));
      g_print (" headers:\n");
      key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
      g_print (" body:\n");
      gst_rtsp_message_get_body (msg, &data, &size);
      gst_util_dump_mem (data, size);
      break;
    case GST_RTSP_MESSAGE_RESPONSE:
      g_print ("RTSP response message %p\n", msg);
      g_print (" status line:\n");
      g_print ("   code:   '%d'\n", msg->type_data.response.code);
      g_print ("   reason: '%s'\n", msg->type_data.response.reason);
      g_print ("   version: '%s'\n",
          gst_rtsp_version_as_text (msg->type_data.response.version));
      g_print (" headers:\n");
      key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
      gst_rtsp_message_get_body (msg, &data, &size);
      g_print (" body: length %d\n", size);
      gst_util_dump_mem (data, size);
      break;
    case GST_RTSP_MESSAGE_HTTP_REQUEST:
      g_print ("HTTP request message %p\n", msg);
      g_print (" request line:\n");
      g_print ("   method:  '%s'\n",
          gst_rtsp_method_as_text (msg->type_data.request.method));
      g_print ("   uri:     '%s'\n", msg->type_data.request.uri);
      g_print ("   version: '%s'\n",
          gst_rtsp_version_as_text (msg->type_data.request.version));
      g_print (" headers:\n");
      key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
      g_print (" body:\n");
      gst_rtsp_message_get_body (msg, &data, &size);
      gst_util_dump_mem (data, size);
      break;
    case GST_RTSP_MESSAGE_HTTP_RESPONSE:
      g_print ("HTTP response message %p\n", msg);
      g_print (" status line:\n");
      g_print ("   code:    '%d'\n", msg->type_data.response.code);
      g_print ("   reason:  '%s'\n", msg->type_data.response.reason);
      g_print ("   version: '%s'\n",
          gst_rtsp_version_as_text (msg->type_data.response.version));
      g_print (" headers:\n");
      key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
      gst_rtsp_message_get_body (msg, &data, &size);
      g_print (" body: length %d\n", size);
      gst_util_dump_mem (data, size);
      break;
    case GST_RTSP_MESSAGE_DATA:
      g_print ("RTSP data message %p\n", msg);
      g_print (" channel: '%d'\n", msg->type_data.data.channel);
      g_print (" size:    '%d'\n", msg->body_size);
      gst_rtsp_message_get_body (msg, &data, &size);
      gst_util_dump_mem (data, size);
      break;
    default:
      g_print ("unsupported message type %d\n", msg->type);
      return GST_RTSP_EINVAL;
  }
  return GST_RTSP_OK;
}


static const gchar *
skip_lws (const gchar * s)
{
  while (g_ascii_isspace (*s))
    s++;
  return s;
}

static const gchar *
skip_commas (const gchar * s)
{
  /* The grammar allows for multiple commas */
  while (g_ascii_isspace (*s) || *s == ',')
    s++;
  return s;
}

static const gchar *
skip_scheme (const gchar * s)
{
  while (*s && !g_ascii_isspace (*s))
    s++;
  return s;
}

static const gchar *
skip_item (const gchar * s)
{
  gboolean quoted = FALSE;

  /* A list item ends at the last non-whitespace character
   * before a comma which is not inside a quoted-string. Or at
   * the end of the string.
   */
  while (*s) {
    if (*s == '"') {
      quoted = !quoted;
    } else if (quoted) {
      if (*s == '\\' && *(s + 1))
        s++;
    } else {
      if (*s == ',' || g_ascii_isspace (*s))
        break;
    }
    s++;
  }

  return s;
}

static void
decode_quoted_string (gchar * quoted_string)
{
  gchar *src, *dst;

  src = quoted_string + 1;
  dst = quoted_string;
  while (*src && *src != '"') {
    if (*src == '\\' && *(src + 1))
      src++;
    *dst++ = *src++;
  }
  *dst = '\0';
}

static void
parse_auth_credentials (GPtrArray * auth_credentials, const gchar * header,
    GstRTSPHeaderField field)
{
  while (header[0] != '\0') {
    const gchar *end;
    GstRTSPAuthCredential *auth_credential;

    /* Skip whitespace at the start of the string */
    header = skip_lws (header);
    if (header[0] == '\0')
      break;

    /* Skip until end of string or whitespace: end of scheme */
    end = skip_scheme (header);

    auth_credential = g_new0 (GstRTSPAuthCredential, 1);

    if (g_ascii_strncasecmp (header, "basic", 5) == 0) {
      auth_credential->scheme = GST_RTSP_AUTH_BASIC;
    } else if (g_ascii_strncasecmp (header, "digest", 6) == 0) {
      auth_credential->scheme = GST_RTSP_AUTH_DIGEST;
    } else {
      /* Not supported, skip */
      g_free (auth_credential);
      header = end;
      continue;
    }

    /* Basic Authorization request has only an unformated blurb following, all
     * other variants have comma-separated name=value pairs */
    if (end[0] != '\0' && field == GST_RTSP_HDR_AUTHORIZATION
        && auth_credential->scheme == GST_RTSP_AUTH_BASIC) {
      auth_credential->authorization = g_strdup (end + 1);
      header = end;
    } else if (end[0] != '\0') {
      GPtrArray *params;

      params = g_ptr_array_new ();

      /* Space or start of param */
      header = end;

      /* Parse a header whose content is described by RFC2616 as
       * "#something", where "something" does not itself contain commas,
       * except as part of quoted-strings, into a list of allocated strings.
       */
      while (*header) {
        const gchar *item_end;
        const gchar *eq;

        header = skip_commas (header);
        item_end = skip_item (header);

        for (eq = header; *eq != '\0' && *eq != '=' && eq < item_end; eq++);
        if (eq[0] == '=') {
          GstRTSPAuthParam *auth_param = g_new0 (GstRTSPAuthParam, 1);
          const gchar *value;

          /* have an actual param */
          auth_param->name = g_strndup (header, eq - header);

          value = eq + 1;
          value = skip_lws (value);
          auth_param->value = g_strndup (value, item_end - value);
          if (value[0] == '"')
            decode_quoted_string (auth_param->value);

          g_ptr_array_add (params, auth_param);
          header = item_end;
        } else {
          /* at next scheme, header at start of it */
          break;
        }
      }
      if (params->len)
        g_ptr_array_add (params, NULL);
      auth_credential->params =
          (GstRTSPAuthParam **) g_ptr_array_free (params, FALSE);
    } else {
      header = end;
    }
    g_ptr_array_add (auth_credentials, auth_credential);

    /* WWW-Authenticate allows multiple, Authorization allows one */
    if (field == GST_RTSP_HDR_AUTHORIZATION)
      break;
  }
}

/**
 * gst_rtsp_message_parse_auth_credentials:
 * @msg: a #GstRTSPMessage
 * @field: a #GstRTSPHeaderField
 *
 * Parses the credentials given in a WWW-Authenticate or Authorization header.
 *
 * Returns: (array zero-terminated=1):
 *     %NULL-terminated array of GstRTSPAuthCredential or %NULL.
 *
 * Since: 1.12
 */
GstRTSPAuthCredential **
gst_rtsp_message_parse_auth_credentials (GstRTSPMessage * msg,
    GstRTSPHeaderField field)
{
  gchar *header;
  GPtrArray *auth_credentials;
  gint i;

  g_return_val_if_fail (msg != NULL, NULL);

  auth_credentials = g_ptr_array_new ();

  i = 0;
  while (gst_rtsp_message_get_header (msg, field, &header, i) == GST_RTSP_OK) {
    parse_auth_credentials (auth_credentials, header, field);
    i++;
  }

  if (auth_credentials->len)
    g_ptr_array_add (auth_credentials, NULL);

  return (GstRTSPAuthCredential **) g_ptr_array_free (auth_credentials, FALSE);
}

GstRTSPAuthParam *
gst_rtsp_auth_param_copy (GstRTSPAuthParam * param)
{
  GstRTSPAuthParam *copy;

  if (param == NULL)
    return NULL;

  copy = g_new0 (GstRTSPAuthParam, 1);
  copy->name = g_strdup (param->name);
  copy->value = g_strdup (param->value);

  return copy;
}

void
gst_rtsp_auth_param_free (GstRTSPAuthParam * param)
{
  if (param != NULL) {
    g_free (param->name);
    g_free (param->value);
    g_free (param);
  }
}

G_DEFINE_BOXED_TYPE (GstRTSPAuthParam, gst_rtsp_auth_param,
    (GBoxedCopyFunc) gst_rtsp_auth_param_copy,
    (GBoxedFreeFunc) gst_rtsp_auth_param_free);

static void
gst_rtsp_auth_credential_free (GstRTSPAuthCredential * credential)
{
  GstRTSPAuthParam **p;

  if (credential == NULL)
    return;

  for (p = credential->params; p != NULL && *p != NULL; ++p)
    gst_rtsp_auth_param_free (*p);

  g_free (credential->params);
  g_free (credential->authorization);
  g_free (credential);
}

static GstRTSPAuthCredential *
gst_rtsp_auth_credential_copy (GstRTSPAuthCredential * cred)
{
  GstRTSPAuthCredential *copy;

  if (cred == NULL)
    return NULL;

  copy = g_new0 (GstRTSPAuthCredential, 1);
  copy->scheme = cred->scheme;
  if (cred->params) {
    guint i, n_params = g_strv_length ((gchar **) cred->params);

    copy->params = g_new0 (GstRTSPAuthParam *, n_params + 1);
    for (i = 0; i < n_params; ++i)
      copy->params[i] = gst_rtsp_auth_param_copy (cred->params[i]);
  }
  copy->authorization = g_strdup (cred->authorization);
  return copy;
}

/**
 * gst_rtsp_auth_credentials_free:
 * @credentials: a %NULL-terminated array of #GstRTSPAuthCredential
 *
 * Free a %NULL-terminated array of credentials returned from
 * gst_rtsp_message_parse_auth_credentials().
 *
 * Since: 1.12
 */
void
gst_rtsp_auth_credentials_free (GstRTSPAuthCredential ** credentials)
{
  GstRTSPAuthCredential **p;

  if (!credentials)
    return;

  for (p = credentials; p != NULL && *p != NULL; ++p)
    gst_rtsp_auth_credential_free (*p);

  g_free (credentials);
}

G_DEFINE_BOXED_TYPE (GstRTSPAuthCredential, gst_rtsp_auth_credential,
    (GBoxedCopyFunc) gst_rtsp_auth_credential_copy,
    (GBoxedFreeFunc) gst_rtsp_auth_credential_free);
