[Mplayer-cvslog] CVS: main/libmpdemux cookies.c,NONE,1.1 cookies.h,NONE,1.1 Makefile,1.69,1.70 network.c,1.88,1.89

Alex Beregszaszi alex at mplayerhq.hu
Mon Dec 8 14:25:37 CET 2003


Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv2422/libmpdemux

Modified Files:
	Makefile network.c 
Added Files:
	cookies.c cookies.h 
Log Message:
Send HTTP Cookies (reading from mozilla/netscape files) support by Dave Lambley <mplayer-dev-eng at dlambley.freeserve.co.uk>. Disabled by default.

--- NEW FILE ---
/*
 * HTTP Cookies
 * Reads Netscape and Mozilla cookies.txt files
 *
 * by Dave Lambley <mplayer at davel.me.uk>
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>

#include "cookies.h"
#include "http.c"
#include "mp_msg.h"

#define MAX_COOKIES 20

char *cookies_file = NULL;

typedef struct cookie_list_type {
    char *name;
    char *value;
    char *domain;
    char *path;

    int secure;

    struct cookie_list_type *next;
} cookie_list_t;

/* Pointer to the linked list of cookies */
static struct cookie_list_type *cookie_list = NULL;


/* Like strdup, but stops at anything <31. */
static char *col_dup(const char *src)
{
    char *dst;
    int length = 0;
    char *p, *end;

    while (src[length] > 31)
	length++;

    dst = malloc(length + 1);
    strncpy(dst, src, length);
    dst[length] = 0;

    return dst;
}

static int right_hand_strcmp(const char *cookie_domain, const char *url_domain)
{
    int c_l;
    int u_l;

    c_l = strlen(cookie_domain);
    u_l = strlen(url_domain);

    if (c_l > u_l)
	return -1;
    return strcmp(cookie_domain, url_domain + u_l - c_l);
}

static int left_hand_strcmp(const char *cookie_path, const char *url_path)
{
    return strncmp(cookie_path, url_path, strlen(cookie_path));
}

/* Finds the start of all the columns */
static int parse_line(char **ptr, char *cols[6])
{
    int col;
    cols[0] = *ptr;

    for (col = 1; col < 7; col++) {
	for (; (**ptr) > 31; (*ptr)++);
	if (**ptr == 0)
	    return 0;
	(*ptr)++;
	if ((*ptr)[-1] != 9)
	    return 0;
	cols[col] = (*ptr);
    }

    return 1;
}

/* Loads a file into RAM */
static char *load_file(const char *filename, off_t * length)
{
    int fd;
    char *buffer;

    mp_msg(MSGT_NETWORK, MSGL_V, "Loading cookie file: %s\n", filename);

    fd = open(filename, O_RDONLY);
    if (fd < 0) {
	mp_msg(MSGT_NETWORK, MSGL_V, "Could not open");
	return NULL;
    }

    *length = lseek(fd, 0, SEEK_END);

    if (*length < 0) {
	mp_msg(MSGT_NETWORK, MSGL_V, "Could not find EOF");
	return NULL;
    }

    lseek(fd, SEEK_SET, 0);

    if (!(buffer = malloc(*length + 1))) {
	mp_msg(MSGT_NETWORK, MSGL_V, "Could not malloc.");
	return NULL;
    }

    if (read(fd, buffer, *length) != *length) {
	mp_msg(MSGT_NETWORK, MSGL_V, "Read is behaving funny.");
	return NULL;
    }
    close(fd);
    buffer[*length] = 0;

    return buffer;
}

/* Loads a cookies.txt file into a linked list. */
static struct cookie_list_type *load_cookies_from(const char *filename,
						  struct cookie_list_type
						  *list)
{
    char *ptr;
    off_t length;

    mp_msg(MSGT_NETWORK, MSGL_V, "Loading cookie file: %s\n", filename);

    ptr = load_file(filename, &length);
    if (!ptr)
	return list;

    while (*ptr > 0) {
	char *cols[7];
	if (parse_line(&ptr, cols)) {
	    struct cookie_list_type *new;
	    new = malloc(sizeof(cookie_list_t));
	    new->name = col_dup(cols[5]);
	    new->value = col_dup(cols[6]);
	    new->path = col_dup(cols[2]);
	    new->domain = col_dup(cols[0]);
	    new->secure = (*(cols[3]) == 't') || (*(cols[3]) == 'T');
	    new->next = list;
	    list = new;
	}
    }
    return list;
}

/* Attempt to load cookies.txt from various locations. Returns a pointer to the linked list contain the cookies. */
static struct cookie_list_type *load_cookies()
{
    DIR *dir;
    struct dirent *ent;
    struct cookie_list_type *list = NULL;
    char *buf;

    char *homedir;

    if (cookies_file)
	return load_cookies_from(cookies_file, list);

    homedir = getenv("HOME");
    if (!homedir)
	return list;


    asprintf(&buf, "%s/.mozilla/default", homedir);
    dir = opendir(buf);
    free(buf);

    if (dir) {
	while ((ent = readdir(dir)) != NULL) {
	    if ((ent->d_name)[0] != '.') {
		asprintf(&buf, "%s/.mozilla/default/%s/cookies.txt",
			 getenv("HOME"), ent->d_name);
		list = load_cookies_from(buf, list);
		free(buf);
	    }
	}
	closedir(dir);
    }

    asprintf(&buf, "%s/.netscape/cookies.txt", homedir);
    list = load_cookies_from(buf, list);
    free(buf);

    return list;
}

/* Take an HTTP_header_t, and insert the correct headers. The cookie files are read if necessary. */
void
cookies_set(HTTP_header_t * http_hdr, const char *domain, const char *url)
{
    int found_cookies = 0;
    struct cookie_list_type *cookies[MAX_COOKIES];
    struct cookie_list_type *list, *start;
    int i;
    char *path;
    char *buf;

    path = index(url, '/');
    if (!path)
	path = "";

    if (!cookie_list)
	cookie_list = load_cookies();


    list = start = cookie_list;

    /* Find which cookies we want, removing duplicates. Cookies with the longest domain, then longest path take priority */
    while (list) {
	/* Check the cookie domain and path. Also, we never send "secure" cookies. These should only be sent over HTTPS. */
	if ((right_hand_strcmp(list->domain, domain) == 0)
	    && (left_hand_strcmp(list->path, path) == 0) && !list->secure) {
	    int replacing = 0;
	    for (i = 0; i < found_cookies; i++) {
		if (strcmp(list->name, cookies[i]->name) == 0) {
		    replacing = 0;
		    if (strlen(list->domain) >
			strlen(cookies[i]->domain) == 0) {
			cookies[i] = list;
		    } else if (strlen(list->path) >
			       strlen(cookies[i]->path) == 0) {
			cookies[i] = list;
		    }
		}
	    }
	    if (found_cookies > MAX_COOKIES) {
		/* Cookie jar overflow! */
		break;
	    }
	    if (!replacing)
		cookies[found_cookies++] = list;
	}
	list = list->next;
    }


    asprintf(&buf, "Cookie:");

    for (i = 0; i < found_cookies; i++) {
	char *nbuf;

	asprintf(&nbuf, "%s %s=%s;", buf, cookies[i]->name,
		 cookies[i]->value);
	free(buf);
	buf = nbuf;
    }
    if (found_cookies)
	http_set_field(http_hdr, buf);
    else
	free(buf);
}

--- NEW FILE ---
/*
 * HTTP Cookies
 * Reads Netscape and Mozilla cookies.txt files
 * 
 * by Dave Lambley <mplayer at davel.me.uk>
 */

#ifndef __COOKIES_H
#define __COOKIES_H

#include "http.h"

extern void cookies_set(HTTP_header_t * http_hdr, const char *hostname,
			const char *url);

#endif

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/Makefile,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- Makefile	17 Aug 2003 20:56:40 -0000	1.69
+++ Makefile	8 Dec 2003 13:25:32 -0000	1.70
@@ -8,7 +8,7 @@
 SRCS += demux_xmms.c
 endif 
 ifeq ($(MPLAYER_NETWORK),yes)
-SRCS += asf_streaming.c http.c network.c asf_mmst_streaming.c pnm.c
+SRCS += asf_streaming.c http.c network.c cookies.c asf_mmst_streaming.c pnm.c
 SRCS += realrtsp/asmrp.c realrtsp/real.c realrtsp/rmff.c realrtsp/rtsp.c realrtsp/rtsp_session.c realrtsp/sdpplin.c realrtsp/xbuffer.c
 ifeq ($(STREAMING_LIVE_DOT_COM),yes)
 CPLUSPLUSSRCS = demux_rtp.cpp demux_rtp_codec.cpp

Index: network.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/network.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- network.c	23 Nov 2003 13:31:44 -0000	1.88
+++ network.c	8 Dec 2003 13:25:32 -0000	1.89
@@ -29,6 +29,7 @@
 
 #include "network.h"
 #include "http.h"
+#include "cookies.h"
 #include "url.h"
 #include "asf.h"
 #ifndef STREAMING_LIVE_DOT_COM
@@ -47,11 +48,13 @@
 int asf_streaming_start( stream_t *stream, int *demuxer_type );
 int rtsp_streaming_start( stream_t *stream );
 
-/* Variables for the command line option -user, -passwd, -bandwidth 
-   and -user-agent */
+/* Variables for the command line option -user, -passwd, -bandwidth,
+   -user-agent and -nocookies */
+
 char *network_username=NULL;
 char *network_password=NULL;
 int   network_bandwidth=0;
+int   network_cookies_enabled = 0;
 char *network_useragent=NULL;
 
 /* IPv6 options */
@@ -452,6 +455,9 @@
 	}
 	else
 	    http_set_field( http_hdr, "User-Agent: MPlayer/"VERSION);
+	    
+	if (network_cookies_enabled) cookies_set( http_hdr, server_url->hostname, server_url->url );
+	
 	http_set_field( http_hdr, "Connection: closed");
 	http_add_basic_authentication( http_hdr, url->username, url->password );
 	if( http_build_request( http_hdr )==NULL ) {



More information about the MPlayer-cvslog mailing list