8 libogg2-zerocopy:1.8.0.2
16 date 2003.07.07.01.49.27; author brendan; state Exp;
21 date 2003.06.18.15.52.25; author karl; state Exp;
26 date 2003.06.18.11.13.11; author karl; state Exp;
31 date 2003.06.09.22.30.09; author brendan; state Exp;
36 date 2003.06.05.17.09.12; author brendan; state Exp;
41 date 2003.03.15.02.10.18; author msmith; state Exp;
46 date 2003.03.09.22.56.46; author karl; state Exp;
51 date 2003.03.08.16.05.38; author karl; state Exp;
56 date 2003.03.08.05.27.17; author msmith; state Exp;
61 date 2003.03.08.04.57.02; author msmith; state Exp;
66 date 2003.03.06.01.55.20; author brendan; state Exp;
71 date 2003.01.17.09.01.04; author msmith; state Exp;
76 date 2003.01.16.05.48.31; author brendan; state Exp;
81 date 2003.01.15.23.46.56; author brendan; state Exp;
86 date 2002.12.31.06.28.39; author msmith; state Exp;
91 date 2002.08.16.14.22.44; author msmith; state Exp;
96 date 2002.08.05.14.48.03; author msmith; state Exp;
101 date 2002.05.03.15.04.56; author msmith; state Exp;
106 date 2002.04.05.09.28.25; author msmith; state Exp;
111 date 2002.02.11.09.11.18; author msmith; state Exp;
116 date 2001.10.20.07.40.09; author jack; state Exp;
121 date 2001.10.20.04.41.54; author jack; state Exp;
126 date 2001.09.10.02.28.47; author jack; state Exp;
132 date 2001.09.10.02.28.47; author jack; state Exp;
143 @httpp goes through the rinse cycle
148 ** http parsing engine
160 #ifdef HAVE_STRINGS_H
168 #define strcasecmp stricmp
171 #define MAX_HEADERS 32
173 /* internal functions */
176 static char *_lowercase(char *str);
179 static int _compare_vars(void *compare_arg, void *a, void *b);
180 static int _free_vars(void *key);
182 http_parser_t *httpp_create_parser(void)
184 return (http_parser_t *)malloc(sizeof(http_parser_t));
187 void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults)
189 http_varlist_t *list;
191 parser->req_type = httpp_req_none;
193 parser->vars = avl_tree_new(_compare_vars, NULL);
194 parser->queryvars = avl_tree_new(_compare_vars, NULL);
196 /* now insert the default variables */
198 while (list != NULL) {
199 httpp_setvar(parser, list->var.name, list->var.value);
204 static int split_headers(char *data, unsigned long len, char **line)
206 /* first we count how many lines there are
207 ** and set up the line[] array
212 for (i = 0; i < len && lines < MAX_HEADERS; i++) {
215 if (data[i] == '\n') {
219 if (data[i + 1] == '\n' || data[i + 1] == '\r')
221 line[lines] = &data[i + 1];
227 while (data[i] == '\n') i++;
232 static void parse_headers(http_parser_t *parser, char **line, int lines)
235 int whitespace, where, slen;
239 /* parse the name: value lines. */
240 for (l = 1; l < lines; l++) {
245 slen = strlen(line[l]);
246 for (i = 0; i < slen; i++) {
247 if (line[l][i] == ':') {
253 while (i < slen && line[l][i] == ' ')
264 if (name != NULL && value != NULL) {
265 httpp_setvar(parser, _lowercase(name), value);
272 int httpp_parse_response(http_parser_t *parser, char *http_data, unsigned long len, char *uri)
275 char *line[MAX_HEADERS];
276 int lines, slen,i, whitespace=0, where=0,code;
277 char *version=NULL, *resp_code=NULL, *message=NULL;
279 if(http_data == NULL)
282 /* make a local copy of the data, including 0 terminator */
283 data = (char *)malloc(len+1);
284 if (data == NULL) return 0;
285 memcpy(data, http_data, len);
288 lines = split_headers(data, len, line);
290 /* In this case, the first line contains:
291 * VERSION RESPONSE_CODE MESSAGE, such as HTTP/1.0 200 OK
293 slen = strlen(line[0]);
295 for(i=0; i < slen; i++) {
296 if(line[0][i] == ' ') {
299 } else if(whitespace) {
303 resp_code = &line[0][i];
305 message = &line[0][i];
311 if(version == NULL || resp_code == NULL || message == NULL) {
316 httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code);
317 code = atoi(resp_code);
318 if(code < 200 || code >= 300) {
319 httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message);
322 httpp_setvar(parser, HTTPP_VAR_URI, uri);
323 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "NONE");
325 parse_headers(parser, line, lines);
332 static int hex(char c)
334 if(c >= '0' && c <= '9')
336 else if(c >= 'A' && c <= 'F')
338 else if(c >= 'a' && c <= 'f')
344 static char *url_escape(char *src)
346 int len = strlen(src);
347 unsigned char *decoded;
352 decoded = calloc(1, len + 1);
356 for(i=0; i < len; i++) {
363 if(hex(src[i+1]) == -1 || hex(src[i+2]) == -1 ) {
368 *dst++ = hex(src[i+1]) * 16 + hex(src[i+2]);
386 *dst = 0; /* null terminator */
391 /** TODO: This is almost certainly buggy in some cases */
392 static void parse_query(http_parser_t *parser, char *query)
399 if(!query || !*query)
409 httpp_set_query_param(parser, key, val);
421 httpp_set_query_param(parser, key, val);
425 /* The old shoutcast procotol. Don't look at this, it's really nasty */
426 int httpp_parse_icy(http_parser_t *parser, char *http_data, unsigned long len)
429 char *line[MAX_HEADERS];
432 if(http_data == NULL)
435 data = malloc(len + 1);
436 memcpy(data, http_data, len);
439 lines = split_headers(data, len, line);
441 /* Now, this protocol looks like:
443 * headers: as normal\n"
447 parser->req_type = httpp_req_source;
448 httpp_setvar(parser, HTTPP_VAR_URI, "/");
449 httpp_setvar(parser, HTTPP_VAR_ICYPASSWORD, line[0]);
450 httpp_setvar(parser, HTTPP_VAR_PROTOCOL, "ICY");
451 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE");
452 /* This protocol is evil */
453 httpp_setvar(parser, HTTPP_VAR_VERSION, "666");
455 parse_headers(parser, line, lines);
462 int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
465 char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
468 char *req_type = NULL;
470 char *version = NULL;
471 int whitespace, where, slen;
473 if (http_data == NULL)
476 /* make a local copy of the data, including 0 terminator */
477 data = (char *)malloc(len+1);
478 if (data == NULL) return 0;
479 memcpy(data, http_data, len);
482 lines = split_headers(data, len, line);
484 /* parse the first line special
486 ** REQ_TYPE URI VERSION
488 ** GET /index.html HTTP/1.0
492 slen = strlen(line[0]);
494 for (i = 0; i < slen; i++) {
495 if (line[0][i] == ' ') {
499 /* we're just past the whitespace boundry */
508 version = &line[0][i];
515 if (strcasecmp("GET", req_type) == 0) {
516 parser->req_type = httpp_req_get;
517 } else if (strcasecmp("POST", req_type) == 0) {
518 parser->req_type = httpp_req_post;
519 } else if (strcasecmp("HEAD", req_type) == 0) {
520 parser->req_type = httpp_req_head;
521 } else if (strcasecmp("SOURCE", req_type) == 0) {
522 parser->req_type = httpp_req_source;
523 } else if (strcasecmp("PLAY", req_type) == 0) {
524 parser->req_type = httpp_req_play;
525 } else if (strcasecmp("STATS", req_type) == 0) {
526 parser->req_type = httpp_req_stats;
528 parser->req_type = httpp_req_unknown;
531 if (uri != NULL && strlen(uri) > 0) {
533 if((query = strchr(uri, '?')) != NULL) {
536 parse_query(parser, query);
539 parser->uri = strdup(uri);
545 if ((version != NULL) && ((tmp = strchr(version, '/')) != NULL)) {
547 if ((strlen(version) > 0) && (strlen(&tmp[1]) > 0)) {
548 httpp_setvar(parser, HTTPP_VAR_PROTOCOL, version);
549 httpp_setvar(parser, HTTPP_VAR_VERSION, &tmp[1]);
559 if (parser->req_type != httpp_req_none && parser->req_type != httpp_req_unknown) {
560 switch (parser->req_type) {
562 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "GET");
565 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "POST");
568 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "HEAD");
570 case httpp_req_source:
571 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE");
574 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PLAY");
576 case httpp_req_stats:
577 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "STATS");
587 if (parser->uri != NULL) {
588 httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);
594 parse_headers(parser, line, lines);
601 void httpp_setvar(http_parser_t *parser, char *name, char *value)
605 if (name == NULL || value == NULL)
608 var = (http_var_t *)malloc(sizeof(http_var_t));
609 if (var == NULL) return;
611 var->name = strdup(name);
612 var->value = strdup(value);
614 if (httpp_getvar(parser, name) == NULL) {
615 avl_insert(parser->vars, (void *)var);
617 avl_delete(parser->vars, (void *)var, _free_vars);
618 avl_insert(parser->vars, (void *)var);
622 char *httpp_getvar(http_parser_t *parser, char *name)
632 if (avl_get_by_key(parser->vars, &var, fp) == 0)
638 void httpp_set_query_param(http_parser_t *parser, char *name, char *value)
642 if (name == NULL || value == NULL)
645 var = (http_var_t *)malloc(sizeof(http_var_t));
646 if (var == NULL) return;
648 var->name = strdup(name);
649 var->value = url_escape(value);
651 if (httpp_get_query_param(parser, name) == NULL) {
652 avl_insert(parser->queryvars, (void *)var);
654 avl_delete(parser->queryvars, (void *)var, _free_vars);
655 avl_insert(parser->queryvars, (void *)var);
659 char *httpp_get_query_param(http_parser_t *parser, char *name)
669 if (avl_get_by_key(parser->queryvars, (void *)&var, fp) == 0)
675 void httpp_clear(http_parser_t *parser)
677 parser->req_type = httpp_req_none;
681 avl_tree_free(parser->vars, _free_vars);
682 avl_tree_free(parser->queryvars, _free_vars);
686 void httpp_destroy(http_parser_t *parser)
692 static char *_lowercase(char *str)
695 for (; *p != '\0'; p++)
701 static int _compare_vars(void *compare_arg, void *a, void *b)
703 http_var_t *vara, *varb;
705 vara = (http_var_t *)a;
706 varb = (http_var_t *)b;
708 return strcmp(vara->name, varb->name);
711 static int _free_vars(void *key)
715 var = (http_var_t *)key;
731 @ermmm, let's use the right operator.
736 int _compare_vars(void *compare_arg, void *a, void *b);
737 int _free_vars(void *key);
740 int _compare_vars(void *compare_arg, void *a, void *b)
743 int _free_vars(void *key)
749 @minor cleanup, removes compiler warning, makes it static, and doesn't
750 re-evaluate string length each time.
755 for (; *p |= '\0'; p++)
761 @gcc 3.3 warns: dereferencing type-punned pointer will break strict-aliasing rules
766 char *_lowercase(char *str);
769 char *_lowercase(char *str)
773 for (i = 0; i < strlen(str); i++)
774 str[i] = tolower(str[i]);
780 @Karl's patch for freebsd, minus the sys/select.h test which breaks on OS X.
781 Also enables IPV6 in libshout!
788 if (avl_get_by_key(parser->vars, (void *)&var, (void **)&found) == 0)
793 if (avl_get_by_key(parser->queryvars, (void *)&var, (void **)&found) == 0)
799 @Brendan was getting pissed off about inconsistent indentation styles.
800 Convert all tabs to 4 spaces. All code must now use 4 space indents.
809 @reduce include file namespace clutter for libshout and the associated
815 return (http_parser_t *)malloc(sizeof(http_parser_t));
818 http_varlist_t *list;
821 parser->req_type = httpp_req_none;
823 parser->vars = avl_tree_new(_compare_vars, NULL);
824 parser->queryvars = avl_tree_new(_compare_vars, NULL);
826 /* now insert the default variables */
828 while (list != NULL) {
829 httpp_setvar(parser, list->var.name, list->var.value);
834 /* first we count how many lines there are
835 ** and set up the line[] array
841 for (i = 0; i < len && lines < MAX_HEADERS; i++) {
844 if (data[i] == '\n') {
848 if (data[i + 1] == '\n' || data[i + 1] == '\r')
850 line[lines] = &data[i + 1];
858 while (data[i] == '\n') i++;
861 int whitespace, where, slen;
865 /* parse the name: value lines. */
866 for (l = 1; l < lines; l++) {
871 slen = strlen(line[l]);
872 for (i = 0; i < slen; i++) {
873 if (line[l][i] == ':') {
879 while (i < slen && line[l][i] == ' ')
890 if (name != NULL && value != NULL) {
891 httpp_setvar(parser, _lowercase(name), value);
899 char *line[MAX_HEADERS];
900 int lines, slen,i, whitespace=0, where=0,code;
901 char *version=NULL, *resp_code=NULL, *message=NULL;
904 if(http_data == NULL)
908 /* make a local copy of the data, including 0 terminator */
909 data = (char *)malloc(len+1);
910 if (data == NULL) return 0;
911 memcpy(data, http_data, len);
914 lines = split_headers(data, len, line);
916 /* In this case, the first line contains:
917 * VERSION RESPONSE_CODE MESSAGE, such as HTTP/1.0 200 OK
919 slen = strlen(line[0]);
921 for(i=0; i < slen; i++) {
922 if(line[0][i] == ' ') {
925 } else if(whitespace) {
929 resp_code = &line[0][i];
931 message = &line[0][i];
937 if(version == NULL || resp_code == NULL || message == NULL) {
942 httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code);
943 code = atoi(resp_code);
944 if(code < 200 || code >= 300) {
945 httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message);
949 httpp_setvar(parser, HTTPP_VAR_URI, uri);
950 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "NONE");
953 parse_headers(parser, line, lines);
962 if(c >= '0' && c <= '9')
964 else if(c >= 'A' && c <= 'F')
966 else if(c >= 'a' && c <= 'f')
972 int len = strlen(src);
973 unsigned char *decoded;
978 decoded = calloc(1, len + 1);
982 for(i=0; i < len; i++) {
989 if(hex(src[i+1]) == -1 || hex(src[i+2]) == -1 ) {
994 *dst++ = hex(src[i+1]) * 16 + hex(src[i+2]);
1013 *dst = 0; /* null terminator */
1024 if(!query || !*query)
1027 len = strlen(query);
1034 httpp_set_query_param(parser, key, val);
1046 httpp_set_query_param(parser, key, val);
1050 lines = split_headers(data, len, line);
1054 char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
1057 char *req_type = NULL;
1059 char *version = NULL;
1060 int whitespace, where, slen;
1062 if (http_data == NULL)
1065 /* make a local copy of the data, including 0 terminator */
1066 data = (char *)malloc(len+1);
1067 if (data == NULL) return 0;
1068 memcpy(data, http_data, len);
1071 lines = split_headers(data, len, line);
1073 /* parse the first line special
1075 ** REQ_TYPE URI VERSION
1077 ** GET /index.html HTTP/1.0
1081 slen = strlen(line[0]);
1083 for (i = 0; i < slen; i++) {
1084 if (line[0][i] == ' ') {
1088 /* we're just past the whitespace boundry */
1097 version = &line[0][i];
1104 if (strcasecmp("GET", req_type) == 0) {
1105 parser->req_type = httpp_req_get;
1106 } else if (strcasecmp("POST", req_type) == 0) {
1107 parser->req_type = httpp_req_post;
1108 } else if (strcasecmp("HEAD", req_type) == 0) {
1109 parser->req_type = httpp_req_head;
1110 } else if (strcasecmp("SOURCE", req_type) == 0) {
1111 parser->req_type = httpp_req_source;
1112 } else if (strcasecmp("PLAY", req_type) == 0) {
1113 parser->req_type = httpp_req_play;
1114 } else if (strcasecmp("STATS", req_type) == 0) {
1115 parser->req_type = httpp_req_stats;
1117 parser->req_type = httpp_req_unknown;
1120 if (uri != NULL && strlen(uri) > 0) {
1122 if((query = strchr(uri, '?')) != NULL) {
1125 parse_query(parser, query);
1129 parser->uri = strdup(uri);
1133 if ((version != NULL) && ((tmp = strchr(version, '/')) != NULL)) {
1135 if ((strlen(version) > 0) && (strlen(&tmp[1]) > 0)) {
1136 httpp_setvar(parser, HTTPP_VAR_PROTOCOL, version);
1137 httpp_setvar(parser, HTTPP_VAR_VERSION, &tmp[1]);
1147 if (parser->req_type != httpp_req_none && parser->req_type != httpp_req_unknown) {
1148 switch (parser->req_type) {
1150 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "GET");
1152 case httpp_req_post:
1153 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "POST");
1155 case httpp_req_head:
1156 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "HEAD");
1158 case httpp_req_source:
1159 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE");
1161 case httpp_req_play:
1162 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PLAY");
1164 case httpp_req_stats:
1165 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "STATS");
1175 if (parser->uri != NULL) {
1176 httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);
1183 parse_headers(parser, line, lines);
1195 if (name == NULL || value == NULL)
1199 var = (http_var_t *)malloc(sizeof(http_var_t));
1200 if (var == NULL) return;
1203 var->name = strdup(name);
1204 var->value = strdup(value);
1206 if (httpp_getvar(parser, name) == NULL) {
1207 avl_insert(parser->vars, (void *)var);
1209 avl_delete(parser->vars, (void *)var, _free_vars);
1210 avl_insert(parser->vars, (void *)var);
1222 if (avl_get_by_key(parser->vars, (void *)&var, (void **)&found) == 0)
1223 return found->value;
1231 if (name == NULL || value == NULL)
1235 var = (http_var_t *)malloc(sizeof(http_var_t));
1236 if (var == NULL) return;
1239 var->name = strdup(name);
1240 var->value = url_escape(value);
1242 if (httpp_get_query_param(parser, name) == NULL) {
1243 avl_insert(parser->queryvars, (void *)var);
1245 avl_delete(parser->queryvars, (void *)var, _free_vars);
1246 avl_insert(parser->queryvars, (void *)var);
1258 if (avl_get_by_key(parser->queryvars, (void *)&var, (void **)&found) == 0)
1259 return found->value;
1264 parser->req_type = httpp_req_none;
1268 avl_tree_free(parser->vars, _free_vars);
1269 avl_tree_free(parser->queryvars, _free_vars);
1270 parser->vars = NULL;
1273 httpp_clear(parser);
1278 for (i = 0; i < strlen(str); i++)
1279 str[i] = tolower(str[i]);
1285 http_var_t *vara, *varb;
1288 vara = (http_var_t *)a;
1289 varb = (http_var_t *)b;
1292 return strcmp(vara->name, varb->name);
1298 var = (http_var_t *)key;
1314 @include the automake config.h file if the application defines one
1325 @Set another parameter in the icy protocol parse that logging expects
1334 @Added support for shoutcast login protocol (ewww...)
1343 @Use gnu archive ACX_PTHREAD macro to figure out how to compile thread support.
1344 Also make it possible to build libshout without threads, albeit without locking
1345 in the resolver or avl trees.
1346 New option --disable-pthread too.
1359 @Fix some warnings, fix cflags.
1369 @Indentation again, don't mind me
1380 @Make indentation consistent before doing other work
1391 @mp3 metadata complete. Still untested.
1396 parser->queryvars = avl_tree_new(_compare_vars, NULL);
1400 char *line[MAX_HEADERS];
1401 int lines, slen,i, whitespace=0, where=0,code;
1402 char *version=NULL, *resp_code=NULL, *message=NULL;
1405 if(http_data == NULL)
1412 lines = split_headers(data, len, line);
1415 /* In this case, the first line contains:
1416 * VERSION RESPONSE_CODE MESSAGE, such as
1419 slen = strlen(line[0]);
1421 for(i=0; i < slen; i++) {
1422 if(line[0][i] == ' ') {
1426 else if(whitespace) {
1430 resp_code = &line[0][i];
1432 message = &line[0][i];
1439 if(version == NULL || resp_code == NULL || message == NULL) {
1444 httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code);
1445 code = atoi(resp_code);
1446 if(code < 200 || code >= 300) {
1447 httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message);
1451 httpp_setvar(parser, HTTPP_VAR_URI, uri);
1454 parse_headers(parser, line, lines);
1457 if(c >= '0' && c <= '9')
1459 else if(c >= 'A' && c <= 'F')
1460 return c - 'A' + 10;
1461 else if(c >= 'a' && c <= 'f')
1462 return c - 'a' + 10;
1467 int len = strlen(src);
1468 unsigned char *decoded;
1473 decoded = calloc(1, len + 1);
1477 for(i=0; i < len; i++) {
1484 if(hex(src[i+1]) == -1 || hex(src[i+2]) == -1 ) {
1489 *dst++ = hex(src[i+1]) * 16 + hex(src[i+2]);
1508 *dst = 0; /* null terminator */
1519 if(!query || !*query)
1522 len = strlen(query);
1529 httpp_set_query_param(parser, key, val);
1542 httpp_set_query_param(parser, key, val);
1546 int whitespace, where, slen;
1552 lines = split_headers(data, len, line);
1555 if (uri != NULL && strlen(uri) > 0)
1558 if((query = strchr(uri, '?')) != NULL) {
1561 parse_query(parser, query);
1569 if (parser->uri != NULL) {
1572 parse_headers(parser, line, lines);
1578 httpp_clear(parser);
1585 @bugfixes for httpp_parse_response
1592 if (uri != NULL && strlen(uri) > 0)
1604 @Cleaned up version of Ciaran Anscomb's relaying patch.
1613 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "RELAY");
1619 @Memory leaks. Lots of little ones.
1624 int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
1627 char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
1630 char *req_type = NULL;
1632 char *version = NULL;
1635 int whitespace, where;
1638 if (http_data == NULL)
1641 /* make a local copy of the data, including 0 terminator */
1642 data = (char *)malloc(len+1);
1643 if (data == NULL) return 0;
1644 memcpy(data, http_data, len);
1655 if (parser->uri != NULL) {
1658 /* parse the name: value lines. */
1659 for (l = 1; l < lines; l++) {
1664 slen = strlen(line[l]);
1665 for (i = 0; i < slen; i++) {
1666 if (line[l][i] == ':') {
1672 while (i < slen && line[l][i] == ' ')
1676 value = &line[l][i];
1683 if (name != NULL && value != NULL) {
1684 httpp_setvar(parser, _lowercase(name), value);
1699 Requires a change to the format plugin interface - jack: if you want this
1700 done differently, feel free to change it (or ask me to).
1705 void httpp_destroy(http_parser_t *parser)
1714 - connections are now matched to format plugins based on content-type headers,
1715 and are rejected if there isn't a format handler for that content-type, or
1716 there is no content-type at all.
1717 - format_vorbis now handles pages with granulepos of -1 in the headers
1718 correctly (this happens if the headers are fairly large, because of
1719 many comments, for example).
1720 - various #include fixes.
1721 - buffer overflow in httpp.c fixed.
1728 char *line[32]; /* limited to 32 lines, should be more than enough */
1731 for (i = 0; i < len; i++) {
1737 @Thanks to Akos Maroy <darkeye@@tyrell.hu> for this. These variables need to
1738 be uppercase always in order to comply with the HTTP specification.
1739 While not a problem internal to icecast, they were slipping into the log
1740 files and breaking some less-than-robust parsers.
1745 /* make a local copy of the data */
1746 data = (char *)malloc(len);
1751 if (data[i + 1] == '\n' || data[i + 1] == '\r') {
1763 @Win32 compatibility courtesy of Oddsock.
1768 httpp_setvar(parser, HTTPP_VAR_PROTOCOL, _lowercase(version));
1771 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "get");
1774 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "post");
1777 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "head");
1780 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "source");
1783 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "play");
1786 httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "stats");