for(p = buf->b; (p - buf->b < buf->d) && isspace(*p); p++);
memmove(buf->b, p, buf->d -= (p - buf->b));
- for(p = buf->b + buf->d - 1; (p > buf->b) && isspace(*p); p--, buf->d--);
+ if(buf->d > 0)
+ for(p = buf->b + buf->d - 1; (p > buf->b) && isspace(*p); p--, buf->d--);
}
int parseheaders(struct hthead *head, FILE *in)
head->headers[i][1] = sstrdup(val);
}
+void headrmheader(struct hthead *head, const char *name)
+{
+ int i;
+
+ for(i = 0; i < head->noheaders; i++) {
+ if(!strcasecmp(head->headers[i][0], name)) {
+ free(head->headers[i][0]);
+ free(head->headers[i][1]);
+ free(head->headers[i]);
+ memmove(head->headers + i, head->headers + i + 1, sizeof(head->headers) * (--head->noheaders - i));
+ return;
+ }
+ }
+}
+
int writeresp(FILE *out, struct hthead *resp)
{
int i;
errno = EPROTO;
return(-1);
}
+
+char *unquoteurl(char *in)
+{
+ struct charbuf buf;
+ char *p;
+ int c;
+
+ bufinit(buf);
+ p = in;
+ while(*p) {
+ if(*p == '%') {
+ if(!p[1] || !p[2])
+ goto fail;
+ c = 0;
+ if((p[1] >= '0') && (p[1] <= '9')) c |= (p[1] - '0') << 4;
+ else if((p[1] >= 'a') && (p[1] <= 'f')) c |= (p[1] - 'a' + 10) << 4;
+ else if((p[1] >= 'A') && (p[1] <= 'F')) c |= (p[1] - 'A' + 10) << 4;
+ else goto fail;
+ if((p[2] >= '0') && (p[2] <= '9')) c |= (p[2] - '0');
+ else if((p[2] >= 'a') && (p[2] <= 'f')) c |= (p[2] - 'a' + 10);
+ else if((p[2] >= 'A') && (p[2] <= 'F')) c |= (p[2] - 'A' + 10);
+ else goto fail;
+ bufadd(buf, c);
+ p += 3;
+ } else {
+ bufadd(buf, *(p++));
+ }
+ }
+ bufadd(buf, 0);
+ return(buf.b);
+fail:
+ buffree(buf);
+ return(NULL);
+}