Skip to content
http.c 60.2 KiB
Newer Older
/***************************************************************************
Daniel Stenberg's avatar
Daniel Stenberg committed
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___ 
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 * 
Daniel Stenberg's avatar
Daniel Stenberg committed
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
Daniel Stenberg's avatar
Daniel Stenberg committed
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
Daniel Stenberg's avatar
Daniel Stenberg committed
 * $Id$
 ***************************************************************************/
Daniel Stenberg's avatar
Daniel Stenberg committed

Daniel Stenberg's avatar
Daniel Stenberg committed
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <errno.h>

#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <netinet/in.h>
#endif
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <sys/time.h>
#ifdef HAVE_TIME_H
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#endif
#endif

Daniel Stenberg's avatar
Daniel Stenberg committed
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <netdb.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif


#endif

#include "urldata.h"
#include <curl/curl.h>
Daniel Stenberg's avatar
Daniel Stenberg committed
#include "sendf.h"
#include "formdata.h"
#include "progress.h"
#include "base64.h"
#include "cookie.h"
#include "strequal.h"
#include "ssluse.h"
#include "http_digest.h"
#include "http_negotiate.h"
#include "share.h"
#include "hostip.h"
Daniel Stenberg's avatar
Daniel Stenberg committed

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

/* The last #include file should be: */
#include "memdebug.h"
#endif

static CURLcode Curl_output_basic_proxy(struct connectdata *conn);

Daniel Stenberg's avatar
Daniel Stenberg committed
 * checkheaders() checks the linked list of custom HTTP headers for a
 * particular header (prefix).
 *
 * Returns a pointer to the first matching header or NULL if none matched.
 */
static char *checkheaders(struct SessionHandle *data, const char *thisheader)
{
  struct curl_slist *head;
  size_t thislen = strlen(thisheader);

  for(head = data->set.headers; head; head=head->next) {
    if(strnequal(head->data, thisheader, thislen))
      return head->data;
  }
  return NULL;
}

Daniel Stenberg's avatar
Daniel Stenberg committed
/*
 * Curl_output_basic() sets up an Authorization: header for HTTP Basic
 * authentication. It uses the conn->user, conn->passwd fields for it.
 *
 * Returns CURLcode.
 */
static CURLcode Curl_output_basic(struct connectdata *conn)
{
  char *authorization;
  struct SessionHandle *data=conn->data;

  sprintf(data->state.buffer, "%s:%s", conn->user, conn->passwd);
  if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
                        &authorization) > 0) {
    if(conn->allocptr.userpwd)
      free(conn->allocptr.userpwd);
    conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
                                      authorization);
    free(authorization);
  }
  else
    return CURLE_OUT_OF_MEMORY;
  return CURLE_OK;
}

Daniel Stenberg's avatar
Daniel Stenberg committed
/*
 * Curl_output_basic_proxy() sets up a proxy-Authorization: header for HTTP
 * Basic proxy authentication. It uses the conn->proxyuser and
 * conn->proxypasswd fields for it.
 *
 * Returns CURLcode.
 */
static CURLcode Curl_output_basic_proxy(struct connectdata *conn)
{
  char *authorization;
  struct SessionHandle *data=conn->data;

  sprintf(data->state.buffer, "%s:%s",
  if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
                        &authorization) > 0) {
    Curl_safefree(conn->allocptr.proxyuserpwd);
    conn->allocptr.proxyuserpwd =
      aprintf("Proxy-authorization: Basic %s\015\012", authorization);
    free(authorization);
  }
  else
    return CURLE_OUT_OF_MEMORY;
  return CURLE_OK;
}

/*
 * Curl_http_auth_act() checks what authentication methods that are available
 * and decides which one (if any) to use. It will set 'newurl' if an auth
 * metod was picked.
 */

void Curl_http_auth_act(struct connectdata *conn)
{
  struct SessionHandle *data = conn->data;

  if(data->state.authavail) {
    /* The order of these checks is highly relevant, as this will be the order
       of preference in case of the existance of multiple accepted types. */
    if(data->state.authavail & CURLAUTH_GSSNEGOTIATE)
      data->state.authwant = CURLAUTH_GSSNEGOTIATE;
    else if(data->state.authavail & CURLAUTH_DIGEST)
      data->state.authwant = CURLAUTH_DIGEST;
    else if(data->state.authavail & CURLAUTH_NTLM)
      data->state.authwant = CURLAUTH_NTLM;
    else if(data->state.authavail & CURLAUTH_BASIC)
      data->state.authwant = CURLAUTH_BASIC;
    else
      data->state.authwant = CURLAUTH_NONE; /* clear it */
Loading
Loading full blame…