diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /http11 | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'http11')
| -rw-r--r-- | http11/.gitignore | 1 | ||||
| -rw-r--r-- | http11/Makefile.am | 8 | ||||
| -rw-r--r-- | http11/configure.in | 43 | ||||
| -rw-r--r-- | http11/contentlanguage.c | 292 | ||||
| -rw-r--r-- | http11/http11.h.in | 68 |
5 files changed, 412 insertions, 0 deletions
diff --git a/http11/.gitignore b/http11/.gitignore new file mode 100644 index 0000000..a5e7a3d --- /dev/null +++ b/http11/.gitignore @@ -0,0 +1 @@ +/http11.h diff --git a/http11/Makefile.am b/http11/Makefile.am new file mode 100644 index 0000000..d8b9be4 --- /dev/null +++ b/http11/Makefile.am @@ -0,0 +1,8 @@ +# +# Copyright 1998 - 2005 Double Precision, Inc. See COPYING for +# distribution information. + + +noinst_LTLIBRARIES=libhttp11.la + +libhttp11_la_SOURCES=contentlanguage.c http11.h diff --git a/http11/configure.in b/http11/configure.in new file mode 100644 index 0000000..3492799 --- /dev/null +++ b/http11/configure.in @@ -0,0 +1,43 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl Copyright 1998 - 2005 Double Precision, Inc. See COPYING for +dnl distribution information. + +AC_INIT(http11, 0.10, [courier-users@lists.sourceforge.net]) + +>confdefs.h # Kill PACKAGE_ macros + +AC_CONFIG_SRCDIR(http11.h.in) +AC_CONFIG_AUX_DIR(../..) +AM_INIT_AUTOMAKE([foreign no-define]) + + +dnl Checks for programs. +AC_USE_SYSTEM_EXTENSIONS +AC_PROG_CC +AC_PROG_LIBTOOL + +if test "$GCC" = yes ; then + CXXFLAGS="$CXXFLAGS -Wall" + CFLAGS="$CFLAGS -Wall" +fi + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_SYS_LARGEFILE + +dnl Checks for library functions. + +AC_ARG_WITH(defaultlang, + [ --with-defaultlang=lang Default Content-Language:], + DEFAULTLANG="$withval", DEFAULTLANG="en") +AC_SUBST(DEFAULTLANG) + +AC_OUTPUT(Makefile http11.h) diff --git a/http11/contentlanguage.c b/http11/contentlanguage.c new file mode 100644 index 0000000..3ce8f41 --- /dev/null +++ b/http11/contentlanguage.c @@ -0,0 +1,292 @@ +/* +** Copyright 1998 - 2002 Double Precision, Inc. +** See COPYING for distribution information. +*/ + + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include "http11.h" +#include "../rfc2045/rfc2045charset.h" + +#if HAVE_DIRENT_H +#include <dirent.h> +#define NAMLEN(dirent) strlen(dirent->d_name) +#else +#define dirent direct +#define NAMLEN(dirent) ((dirent)->d_namlen) +#if HAVE_SYS_NDIR_H +#include <sys/ndir.h> +#endif +#if HAVE_SYS_DIR_H +#include <sys/dir.h> +#endif +#if HAVE_NDIR_H +#include <ndir.h> +#endif +#endif + +extern void error(const char *); + +static void enomem() +{ + error("Out of memory."); +} + +static const char defaultlang[] = HTTP11_DEFAULTLANG; + +/* +** Based upon Accept-Language: header, figure out which directory in +** HTMLLIBDIR matches it. +*/ + +FILE *http11_open_langfile(const char *libdir, const char *subdir, + const char *file) +{ +char *p=malloc(strlen(libdir)+strlen(subdir)+strlen(file)+3); +FILE *fp; + + if (!p) return (0); + strcat(strcat(strcat(strcat(strcpy(p, libdir), "/"), subdir), "/"), + file); + + fp=fopen(p, "r"); + free(p); + return (fp); +} + +/**************************************************************************/ + +/* Parse Accept-Language: header */ + +static size_t parse_accept_string(const char *acc_lang, char **languages, + double *weights) +{ +char *p=strdup(acc_lang ? acc_lang:""); +size_t cnt=0; +char *q, *r; +int has_weights=0; +double *save_weights=weights; + + if (!p) enomem(); + for (q=p; (q=strtok(q, ", ")) != 0; q=0) + { + if (languages) + { + q=strdup(q); + if (!q) enomem(); + *languages++=q; + } + if (weights) *weights=1; /* Until further notice */ + for (r=q; *r; r++) + *r=tolower(*r); + if ((r=strchr(q, ';')) != 0) + { + *r++=0; + if (*r == 'q' && r[1] == '=') + { + double weight=atof(r+2); + + if (weights) *weights=weight; + has_weights=1; + } + } + if (weights) ++weights; + ++cnt; + } + free(p); + if (!has_weights && weights) + { + size_t i; + double weight=1; + + /* + ** Broken HTTP/1.1 clients do not specify quality factors, and expect + ** the server to pick the first one on the list + */ + for (i=cnt; i; ) + { + --i; + save_weights[i]=weight; + weight = weight + 1; + } + } + + return (cnt); +} + +char *http11_best_content_language(const char *libdir, const char *acc_lang) +{ +size_t naccept=parse_accept_string(acc_lang, 0, 0); +char **languages=malloc(naccept ? sizeof(char *)*naccept:1); +double *weights=malloc(naccept ? sizeof(double)*naccept:1); +DIR *p; +struct dirent *de; +size_t i; +#if 0 +double missweight=1; +#endif +char *bestlang=0; +double bestweight=0; +int found_nondefault_match=0; + + if (!languages || !weights) + { + if (languages) free(languages); + if (weights) free(weights); + enomem(); + } + (void)parse_accept_string(acc_lang, languages, weights); +#if 0 + for (i=0; i<naccept; i++) + if (strcmp(languages[i], "*") == 0) missweight=weights[i]; + /* Default weight */ +#endif + p=opendir(libdir); + while (p && (de=readdir(p)) != 0) + { + FILE *fp; + + if (*de->d_name == '.') continue; + + if ((fp=http11_open_langfile(libdir, de->d_name, "LOCALE")) + != 0) + { +#if 0 + double myweight=missweight; +#else + double myweight=0; +#endif + + fclose(fp); + for (i=0; i<naccept; i++) + if (strcmp(languages[i], de->d_name) == 0) + { + myweight=weights[i]; + break; + } + if (!bestlang || myweight > bestweight) + { + if (bestlang) free(bestlang); + bestlang=strdup(de->d_name); + if (!bestlang) enomem(); + bestweight=myweight; + if (i < naccept) + found_nondefault_match=1; + } + } + } + if (p) closedir(p); + if (!bestlang || !found_nondefault_match) + { + if (bestlang) free(bestlang); + if ((bestlang=malloc(sizeof(defaultlang))) == 0) enomem(); + strcpy(bestlang, defaultlang); + } + for (i=0; i<naccept; i++) + free(languages[i]); + free(languages); + free(weights); + return (bestlang); +} + +static const char *get_http11(const char *libdir, const char *subdir, + char *buf, + const char *file, const char *def) +{ +FILE *fp=http11_open_langfile(libdir, subdir, file); + + if (fp != 0) + { + size_t n=fread(buf, 1, 79, fp); + + if (n <= 0) n=0; + buf[n]=0; + fclose(fp); + return (strtok(buf, "\r\n")); + } + return (def); +} + +const char *http11_content_language(const char *libdir, const char *acc_lang) +{ +static char buf[80]; + + return (get_http11(libdir, acc_lang, buf, "LANGUAGE", defaultlang)); +} + +const char *http11_content_locale(const char *libdir, const char *acc_lang) +{ +static char buf[80]; +const char *p=get_http11(libdir, acc_lang, buf, "LOCALE", "C"); + + return (p); +} + +const char *http11_content_ispelldict(const char *libdir, const char *acc_lang) +{ +static char buf[80]; + + return (get_http11(libdir, acc_lang, buf, "ISPELLDICT", defaultlang)); +} + +const char *http11_content_charset(const char *libdir, const char *acc_lang) +{ + char buf[80]; + static char buf2[80]; + size_t naccept; + char **charsets; + double *weights; + const char *p; + size_t i; + + strcpy(buf2, get_http11(libdir, acc_lang, buf, "CHARSET", + RFC2045CHARSET)); + + p=getenv("HTTP_ACCEPT_CHARSET"); + + if (!p) p=""; + + naccept=parse_accept_string(p, 0, 0); + charsets=malloc(naccept ? sizeof(char *)*naccept:1); + weights=malloc(naccept ? sizeof(double)*naccept:1); + + if (!charsets || !weights) + { + if (charsets) free(charsets); + if (weights) free(weights); + enomem(); + } + + (void)parse_accept_string(p, charsets, weights); + strcpy(buf, buf2); + + for (p=strtok(buf, ", \t\r\n"); p != NULL; p=strtok(NULL, ", \t\r\n")) + { + for (i=0; i<naccept; i++) + if (strcmp(charsets[i], p) == 0) + { + strcpy(buf2, charsets[i]); + for (i=0; i<naccept; i++) + free(charsets[i]); + free(charsets); + free(weights); + return buf2; + } + } + + p=strtok(buf2, ", \t\r\n"); + if (!p) + p=RFC2045CHARSET; + for (i=0; i<naccept; i++) + free(charsets[i]); + free(charsets); + free(weights); + return p; +} diff --git a/http11/http11.h.in b/http11/http11.h.in new file mode 100644 index 0000000..d40ae08 --- /dev/null +++ b/http11/http11.h.in @@ -0,0 +1,68 @@ +#ifndef http11_h +#define http11_h + +/* +** Copyright 1998 - 2003 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if HAVE_LIBFCGI +#include <stdlib.h> +#include "fcgi_stdio.h" +#endif + + +/* HTTP 1.1 library */ + +/* Implement Accept-Language: and Content-Language: headers as follows. +** +** libdir contains one subdirectory for each support content language. +** +** softlinks are used to provide default variations of each content. +** (example: en -> en-us ) +** +** subdirectory/LANGUAGE is a file with one line, containing the name of +** the directory. So, we can open en/LANGUAGE, read en-us, and send that +** back as the Content-Language: +** +** subdirectory/LOCALE is a file with one line - the corresponding locale. +** en-us/LOCALE will contain en_US, for example. +** +*/ + +char *http11_best_content_language(const char *libdir, const char *acc_lang); + /* acc_lang is our Accept-Language: header. Figure out the best + ** content language we can use. + ** + ** Note - return pointer must be free()d. + */ + +const char *http11_content_language(const char *libdir, const char *cont_lang); + /* Return the real content language by reading LANGUAGE */ + +const char *http11_content_locale(const char *libdir, const char *cont_lang); + /* Return the LOCALE */ + +const char *http11_content_ispelldict(const char *libdir, const char *cont_lang); + /* Return the ISPELL dictionary */ + +const char *http11_content_charset(const char *libdir, const char *acc_lang); + /* Return the CHARSET */ + +FILE *http11_open_langfile(const char *libdir, const char *acc_lang, + const char *file); + /* Open arbitrary file */ + +#define HTTP11_DEFAULTLANG "@DEFAULTLANG@" +#ifdef __cplusplus +} +#endif +#endif |
