Back to index

avfs  1.0.1
http_utils.c
Go to the documentation of this file.
00001 /* 
00002    HTTP utility functions
00003    Copyright (C) 1999-2001, Joe Orton <joe@light.plus.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018    MA 02111-1307, USA
00019 
00020 */
00021 
00022 #include "config.h"
00023 
00024 #include <sys/types.h>
00025 
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 
00030 #include <ctype.h> /* isdigit() for http_parse_statusline */
00031 
00032 #include "dates.h"
00033 
00034 #include "http_utils.h"
00035 
00036 #ifdef ENABLE_SSL
00037 #include <openssl/opensslv.h>
00038 #endif
00039 
00040 int neon_debug_mask = 0;
00041 FILE *neon_debug_stream;
00042 
00043 void neon_debug_init(FILE *stream, int mask)
00044 {
00045     neon_debug_stream = stream;
00046     neon_debug_mask = mask;
00047 }
00048 
00049 void neon_debug(int ch, const char *template, ...) 
00050 {
00051     va_list params;
00052     if ((ch&neon_debug_mask) != ch) return;
00053     fflush(stdout);
00054     va_start(params, template);
00055     vfprintf(neon_debug_stream, template, params);
00056     va_end(params);
00057     if ((ch&DEBUG_FLUSH) == DEBUG_FLUSH) {
00058        fflush(neon_debug_stream);
00059     }
00060 }
00061 
00062 static const char *version_string = "neon " NEON_VERSION ": " 
00063 #ifdef NEON_IS_LIBRARY
00064   "Library build"
00065 #else
00066   "Bundled build"
00067 #endif
00068 #ifdef HAVE_EXPAT
00069   ", Expat"
00070 #else
00071 #ifdef HAVE_LIBXML
00072   ", libxml"
00073 #endif
00074 #endif
00075 #ifdef ENABLE_SSL
00076    ", SSL support using "
00077 #ifdef OPENSSL_VERSION_TEXT
00078     OPENSSL_VERSION_TEXT
00079 #else
00080    "unknown SSL library"
00081 #endif /* OPENSSL_VERSION_TEXT */
00082 #else /* !ENABLE_SSL */
00083    ", no OpenSSL support"
00084 #endif /* ENABLE_SSL */
00085 ;
00086 
00087 const char *neon_version_string(void)
00088 {
00089     return version_string;
00090 }
00091 
00092 int neon_version_minimum(int major, int minor)
00093 {
00094     return 
00095        (NEON_VERSION_MAJOR < major) || 
00096        (NEON_VERSION_MINOR < minor);
00097 }
00098 
00099 /* HTTP-date parser */
00100 time_t http_dateparse(const char *date) {
00101     time_t tmp;
00102     tmp = rfc1123_parse(date);
00103     if (tmp == -1) {
00104         tmp = rfc1036_parse(date);
00105        if (tmp == -1)
00106            tmp = asctime_parse(date);
00107     }
00108     return tmp;
00109 }
00110 
00111 int http_parse_statusline(const char *status_line, http_status *st) {
00112     const char *part;
00113     int major, minor, status_code, klass;
00114     /* Check they're speaking the right language */
00115     if (strncmp(status_line, "HTTP/", 5) != 0) {
00116        return -1;
00117     }
00118     /* And find out which dialect of this peculiar language
00119      * they can talk... */
00120     major = 0;
00121     minor = 0; 
00122     /* Note, we're good children, and accept leading zero's on the
00123      * version numbers */
00124     for (part = status_line + 5; *part != '\0' && isdigit(*part); part++) {
00125        major = major*10 + (*part-'0');
00126     }
00127     if (*part != '.') { 
00128        return -1;
00129     }
00130     for (part++ ; *part != '\0' && isdigit(*part); part++) {
00131        minor = minor*10 + (*part-'0');
00132     }
00133     if (*part != ' ') {
00134        return -1;
00135     }
00136     /* Skip any spaces */
00137     for (; *part == ' ' ; part++) /* noop */;
00138     /* Now for the Status-Code. part now points at the first Y in
00139      * "HTTP/x.x YYY". We want value of YYY... could use atoi, but
00140      * probably quicker this way. */
00141     if (!isdigit(part[0]) || !isdigit(part[1]) || !isdigit(part[2])) {
00142        return -1;
00143     }
00144     status_code = 100*(part[0]-'0') + 10*(part[1]-'0') + (part[2]-'0');
00145     klass = part[0]-'0';
00146     /* Skip whitespace between status-code and reason-phrase */
00147     for (part+=3; *part == ' ' || *part == '\t'; part++) /* noop */;
00148     if (*part == '\0') {
00149        return -1;
00150     }
00151     /* Fill in the results */
00152     st->major_version = major;
00153     st->minor_version = minor;
00154     st->reason_phrase = part;
00155     st->code = status_code;
00156     st->klass = klass;
00157     return 0;
00158 }