diff --git a/include/curl/curl.h b/include/curl/curl.h index fdca815c49971c127ac134c7ad4a3f9b8feafadc..0e0c1b100f97463733505ea06599aea06ab82d8d 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -616,6 +616,9 @@ typedef enum { /* Set pointer to private data */ CINIT(PRIVATE, OBJECTPOINT, 103), + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff --git a/lib/transfer.c b/lib/transfer.c index eca2cad7becafe35af1c9de5d03add2d51ea374a..5ba6cd59cbfcc4a5d4b1202974fae2f3cf2f2b87 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -162,6 +162,28 @@ static int fillbuffer(struct connectdata *conn, return nread; } +/* + * checkhttpprefix() + * + * Returns TRUE if member of the list matches prefix of string + */ +static bool +checkhttpprefix(struct SessionHandle *data, + const char *s) +{ + struct curl_slist *head = data->set.http200aliases; + + while (head) { + if (checkprefix(head->data, s)) + return TRUE; + head = head->next; + } + + if(checkprefix("HTTP/", s)) + return TRUE; + + return FALSE; +} CURLcode Curl_readwrite(struct connectdata *conn, bool *done) @@ -287,7 +309,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, k->hbuflen += nread; if (!k->headerline && (k->hbuflen>5)) { /* make a first check that this looks like a HTTP header */ - if(!checkprefix("HTTP/", data->state.headerbuff)) { + if(!checkhttpprefix(data, data->state.headerbuff)) { /* this is not the beginning of a HTTP first header line */ k->header = FALSE; k->badheader = HEADER_ALLBAD; @@ -341,7 +363,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(!k->headerline) { /* the first read header */ if((k->hbuflen>5) && - !checkprefix("HTTP/", data->state.headerbuff)) { + !checkhttpprefix(data, data->state.headerbuff)) { /* this is not the beginning of a HTTP first header line */ k->header = FALSE; k->badheader = HEADER_PARTHEADER; @@ -468,6 +490,18 @@ CURLcode Curl_readwrite(struct connectdata *conn, */ nc=sscanf (k->p, " HTTP %3d", &k->httpcode); k->httpversion = 10; + + /* If user has set option HTTP200ALIASES, + compare header line against list of aliases + */ + if (!nc) { + if (checkhttpprefix(data, k->p)) { + nc = 1; + k->httpcode = 200; + k->httpversion = + (data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11; + } + } } if (nc) { diff --git a/lib/url.c b/lib/url.c index a639ebaa1e19df09fc12ea50f66fa511b1bac4b8..7f2aae8a5d86157b3defb785f28aae9cf6afd8f0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1095,6 +1095,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.private = va_arg(param, char *); break; + case CURLOPT_HTTP200ALIASES: + /* + * Set a list of aliases for HTTP 200 in response header + */ + data->set.http200aliases = va_arg(param, struct curl_slist *); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ diff --git a/lib/urldata.h b/lib/urldata.h index 334b0e63368dd9fd845997f4e5114188fb82e3a1..cb6cbee1bd0a5b8dff03e3d0a2e6a6e86210e4b1 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -715,6 +715,8 @@ struct UserDefined { long buffer_size; /* size of receive buffer to use */ char *private; /* Private data */ + + struct curl_slist *http200aliases; /* linked list of aliases for http200 */ /* Here follows boolean settings that define how to behave during this session. They are STATIC, set by libcurl users or at least initially