⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpp.c,v

📁 版本控制CVS资源库转换成SVN库的转换程序
💻 C,V
📖 第 1 页 / 共 3 页
字号:
head	1.23;access;symbols	libshout-2_0:1.23	libshout-2_0b3:1.23	libshout-2_0b2:1.22	libshout_2_0b1:1.22	libogg2-zerocopy:1.8.0.2	start:1.1.1.1	xiph:1.1.1;locks; strict;comment	@ * @;1.23date	2003.07.07.01.49.27;	author brendan;	state Exp;branches;next	1.22;1.22date	2003.06.18.15.52.25;	author karl;	state Exp;branches;next	1.21;1.21date	2003.06.18.11.13.11;	author karl;	state Exp;branches;next	1.20;1.20date	2003.06.09.22.30.09;	author brendan;	state Exp;branches;next	1.19;1.19date	2003.06.05.17.09.12;	author brendan;	state Exp;branches;next	1.18;1.18date	2003.03.15.02.10.18;	author msmith;	state Exp;branches;next	1.17;1.17date	2003.03.09.22.56.46;	author karl;	state Exp;branches;next	1.16;1.16date	2003.03.08.16.05.38;	author karl;	state Exp;branches;next	1.15;1.15date	2003.03.08.05.27.17;	author msmith;	state Exp;branches;next	1.14;1.14date	2003.03.08.04.57.02;	author msmith;	state Exp;branches;next	1.13;1.13date	2003.03.06.01.55.20;	author brendan;	state Exp;branches;next	1.12;1.12date	2003.01.17.09.01.04;	author msmith;	state Exp;branches;next	1.11;1.11date	2003.01.16.05.48.31;	author brendan;	state Exp;branches;next	1.10;1.10date	2003.01.15.23.46.56;	author brendan;	state Exp;branches;next	1.9;1.9date	2002.12.31.06.28.39;	author msmith;	state Exp;branches;next	1.8;1.8date	2002.08.16.14.22.44;	author msmith;	state Exp;branches;next	1.7;1.7date	2002.08.05.14.48.03;	author msmith;	state Exp;branches;next	1.6;1.6date	2002.05.03.15.04.56;	author msmith;	state Exp;branches;next	1.5;1.5date	2002.04.05.09.28.25;	author msmith;	state Exp;branches;next	1.4;1.4date	2002.02.11.09.11.18;	author msmith;	state Exp;branches;next	1.3;1.3date	2001.10.20.07.40.09;	author jack;	state Exp;branches;next	1.2;1.2date	2001.10.20.04.41.54;	author jack;	state Exp;branches;next	1.1;1.1date	2001.09.10.02.28.47;	author jack;	state Exp;branches	1.1.1.1;next	;1.1.1.1date	2001.09.10.02.28.47;	author jack;	state Exp;branches;next	;desc@@1.23log@httpp goes through the rinse cycle@text@/* Httpp.c**** http parsing engine*/#ifdef HAVE_CONFIG_H #include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <avl/avl.h>#include "httpp.h"#ifdef _WIN32#define strcasecmp stricmp#endif#define MAX_HEADERS 32/* internal functions *//* misc */static char *_lowercase(char *str);/* for avl trees */static int _compare_vars(void *compare_arg, void *a, void *b);static int _free_vars(void *key);http_parser_t *httpp_create_parser(void){    return (http_parser_t *)malloc(sizeof(http_parser_t));}void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults){    http_varlist_t *list;    parser->req_type = httpp_req_none;    parser->uri = NULL;    parser->vars = avl_tree_new(_compare_vars, NULL);    parser->queryvars = avl_tree_new(_compare_vars, NULL);    /* now insert the default variables */    list = defaults;    while (list != NULL) {        httpp_setvar(parser, list->var.name, list->var.value);        list = list->next;    }}static int split_headers(char *data, unsigned long len, char **line){    /* first we count how many lines there are     ** and set up the line[] array         */    int lines = 0;    unsigned long i;    line[lines] = data;    for (i = 0; i < len && lines < MAX_HEADERS; i++) {        if (data[i] == '\r')            data[i] = '\0';        if (data[i] == '\n') {            lines++;            data[i] = '\0';            if (i + 1 < len) {                if (data[i + 1] == '\n' || data[i + 1] == '\r')                    break;                line[lines] = &data[i + 1];            }        }    }    i++;    while (data[i] == '\n') i++;    return lines;}static void parse_headers(http_parser_t *parser, char **line, int lines){    int i,l;    int whitespace, where, slen;    char *name = NULL;    char *value = NULL;    /* parse the name: value lines. */    for (l = 1; l < lines; l++) {        where = 0;        whitespace = 0;        name = line[l];        value = NULL;        slen = strlen(line[l]);        for (i = 0; i < slen; i++) {            if (line[l][i] == ':') {                whitespace = 1;                line[l][i] = '\0';            } else {                if (whitespace) {                    whitespace = 0;                    while (i < slen && line[l][i] == ' ')                        i++;                    if (i < slen)                        value = &line[l][i];                                        break;                }            }        }                if (name != NULL && value != NULL) {            httpp_setvar(parser, _lowercase(name), value);            name = NULL;             value = NULL;        }    }}int httpp_parse_response(http_parser_t *parser, char *http_data, unsigned long len, char *uri){    char *data;    char *line[MAX_HEADERS];    int lines, slen,i, whitespace=0, where=0,code;    char *version=NULL, *resp_code=NULL, *message=NULL;        if(http_data == NULL)        return 0;    /* make a local copy of the data, including 0 terminator */    data = (char *)malloc(len+1);    if (data == NULL) return 0;    memcpy(data, http_data, len);    data[len] = 0;    lines = split_headers(data, len, line);    /* In this case, the first line contains:     * VERSION RESPONSE_CODE MESSAGE, such as HTTP/1.0 200 OK     */    slen = strlen(line[0]);    version = line[0];    for(i=0; i < slen; i++) {        if(line[0][i] == ' ') {            line[0][i] = 0;            whitespace = 1;        } else if(whitespace) {            whitespace = 0;            where++;            if(where == 1)                resp_code = &line[0][i];            else {                message = &line[0][i];                break;            }        }    }    if(version == NULL || resp_code == NULL || message == NULL) {        free(data);        return 0;    }    httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code);    code = atoi(resp_code);    if(code < 200 || code >= 300) {        httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message);    }    httpp_setvar(parser, HTTPP_VAR_URI, uri);    httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "NONE");    parse_headers(parser, line, lines);    free(data);    return 1;}static int hex(char c){    if(c >= '0' && c <= '9')        return c - '0';    else if(c >= 'A' && c <= 'F')        return c - 'A' + 10;    else if(c >= 'a' && c <= 'f')        return c - 'a' + 10;    else        return -1;}static char *url_escape(char *src){    int len = strlen(src);    unsigned char *decoded;    int i;    char *dst;    int done = 0;    decoded = calloc(1, len + 1);    dst = decoded;    for(i=0; i < len; i++) {        switch(src[i]) {        case '%':            if(i+2 >= len) {                free(decoded);                return NULL;            }            if(hex(src[i+1]) == -1 || hex(src[i+2]) == -1 ) {                free(decoded);                return NULL;            }            *dst++ = hex(src[i+1]) * 16  + hex(src[i+2]);            i+= 2;            break;        case '#':            done = 1;            break;        case 0:            free(decoded);            return NULL;            break;        default:            *dst++ = src[i];            break;        }        if(done)            break;    }    *dst = 0; /* null terminator */    return decoded;}/** TODO: This is almost certainly buggy in some cases */static void parse_query(http_parser_t *parser, char *query){    int len;    int i=0;    char *key = query;    char *val=NULL;    if(!query || !*query)        return;    len = strlen(query);    while(i<len) {        switch(query[i]) {        case '&':            query[i] = 0;            if(val && key)                httpp_set_query_param(parser, key, val);            key = query+i+1;            break;        case '=':            query[i] = 0;            val = query+i+1;            break;        }        i++;    }    if(val && key) {        httpp_set_query_param(parser, key, val);    }}/* The old shoutcast procotol. Don't look at this, it's really nasty */int httpp_parse_icy(http_parser_t *parser, char *http_data, unsigned long len){    char *data;    char *line[MAX_HEADERS];    int lines;    if(http_data == NULL)        return 0;    data = malloc(len + 1);    memcpy(data, http_data, len);    data[len] = 0;    lines = split_headers(data, len, line);    /* Now, this protocol looks like:     * sourcepassword\n     * headers: as normal\n"     * \n     */    parser->req_type = httpp_req_source;    httpp_setvar(parser, HTTPP_VAR_URI, "/");    httpp_setvar(parser, HTTPP_VAR_ICYPASSWORD, line[0]);    httpp_setvar(parser, HTTPP_VAR_PROTOCOL, "ICY");    httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE");    /* This protocol is evil */    httpp_setvar(parser, HTTPP_VAR_VERSION, "666");    parse_headers(parser, line, lines);    free(data);        return 1;}int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len){    char *data, *tmp;    char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */    int i;    int lines;    char *req_type = NULL;    char *uri = NULL;    char *version = NULL;    int whitespace, where, slen;    if (http_data == NULL)        return 0;    /* make a local copy of the data, including 0 terminator */    data = (char *)malloc(len+1);    if (data == NULL) return 0;    memcpy(data, http_data, len);    data[len] = 0;    lines = split_headers(data, len, line);    /* parse the first line special    ** the format is:    ** REQ_TYPE URI VERSION    ** eg:    ** GET /index.html HTTP/1.0    */    where = 0;    whitespace = 0;    slen = strlen(line[0]);    req_type = line[0];    for (i = 0; i < slen; i++) {        if (line[0][i] == ' ') {            whitespace = 1;            line[0][i] = '\0';        } else {            /* we're just past the whitespace boundry */            if (whitespace) {                whitespace = 0;                where++;                switch (where) {                case 1:                    uri = &line[0][i];                    break;                case 2:                    version = &line[0][i];                    break;                }            }        }    }    if (strcasecmp("GET", req_type) == 0) {        parser->req_type = httpp_req_get;    } else if (strcasecmp("POST", req_type) == 0) {        parser->req_type = httpp_req_post;    } else if (strcasecmp("HEAD", req_type) == 0) {        parser->req_type = httpp_req_head;    } else if (strcasecmp("SOURCE", req_type) == 0) {        parser->req_type = httpp_req_source;    } else if (strcasecmp("PLAY", req_type) == 0) {        parser->req_type = httpp_req_play;    } else if (strcasecmp("STATS", req_type) == 0) {        parser->req_type = httpp_req_stats;    } else {        parser->req_type = httpp_req_unknown;    }    if (uri != NULL && strlen(uri) > 0) {        char *query;        if((query = strchr(uri, '?')) != NULL) {            *query = 0;            query++;            parse_query(parser, query);        }        parser->uri = strdup(uri);    } else {        free(data);        return 0;    }    if ((version != NULL) && ((tmp = strchr(version, '/')) != NULL)) {        tmp[0] = '\0';        if ((strlen(version) > 0) && (strlen(&tmp[1]) > 0)) {            httpp_setvar(parser, HTTPP_VAR_PROTOCOL, version);            httpp_setvar(parser, HTTPP_VAR_VERSION, &tmp[1]);        } else {            free(data);            return 0;        }    } else {        free(data);        return 0;    }    if (parser->req_type != httpp_req_none && parser->req_type != httpp_req_unknown) {        switch (parser->req_type) {        case httpp_req_get:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "GET");            break;        case httpp_req_post:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "POST");            break;        case httpp_req_head:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "HEAD");            break;        case httpp_req_source:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE");            break;        case httpp_req_play:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PLAY");            break;        case httpp_req_stats:            httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "STATS");            break;        default:            break;        }    } else {        free(data);        return 0;    }    if (parser->uri != NULL) {        httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);    } else {        free(data);        return 0;    }    parse_headers(parser, line, lines);    free(data);    return 1;}void httpp_setvar(http_parser_t *parser, char *name, char *value){    http_var_t *var;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -