{
size_t len = curlx_dyn_len(&data->state.headerb);
char *hd = curlx_dyn_ptr(&data->state.headerb);
- if(len && (hd[len -1] == '\n'))
+ if(len && (hd[len - 1] == '\n'))
len--;
- if(len && (hd[len -1] == '\r'))
+ if(len && (hd[len - 1] == '\r'))
+ len--;
+ while(len && (ISBLANK(hd[len - 1]))) /* strip off trailing whitespace */
len--;
curlx_dyn_setlen(&data->state.headerb, len);
+ data->state.leading_unfold = TRUE;
}
/*
goto out; /* read more and try again */
}
- /* decrease the size of the remaining (supposed) header line */
+ /* the size of the remaining (supposed) header line */
consumed = (end_ptr - buf) + 1;
- result = curlx_dyn_addn(&data->state.headerb, buf, consumed);
- if(result)
- return result;
- blen -= consumed;
- buf += consumed;
- *pconsumed += consumed;
+
+ {
+ /* preserve the whole original header piece size */
+ size_t header_piece = consumed;
+
+ if(data->state.leading_unfold) {
+ /* immediately after an unfold, keep only a single whitespace */
+ const size_t iblen = blen;
+ while(consumed && ISBLANK(buf[0])) {
+ consumed--;
+ buf++;
+ blen--;
+ }
+ if(consumed) {
+ if(iblen > blen) {
+ /* take one step back */
+ consumed++;
+ buf--;
+ blen++;
+ }
+ data->state.leading_unfold = FALSE; /* done now */
+ }
+ }
+
+ if(consumed) {
+ result = curlx_dyn_addn(&data->state.headerb, buf, consumed);
+ if(result)
+ return result;
+ blen -= consumed;
+ buf += consumed;
+ }
+ *pconsumed += header_piece;
+ }
/****
* We now have a FULL header line in 'headerb'.