@@ -1211,51 +1211,45 @@ int net_http_fd(struct http_t *state)
12111211static ssize_t net_http_receive_header (struct http_t * state , ssize_t len )
12121212{
12131213 struct response * response = (struct response * )& state -> response ;
1214+ char * scan ;
1215+ char * dataend ;
12141216
12151217 response -> pos += len ;
1218+ scan = response -> data ;
1219+ dataend = response -> data + response -> pos ;
12161220
12171221 while (response -> part < P_BODY )
12181222 {
1219- char * dataend = response -> data + response -> pos ;
1220- char * lineend = (char * )memchr (response -> data , '\n' , response -> pos );
1221-
1223+ ssize_t remaining = dataend - scan ;
1224+ char * lineend = (char * )memchr (scan , '\n' , remaining );
12221225 if (!lineend )
12231226 break ;
12241227
1225- * lineend = '\0' ;
1226-
1227- if (lineend != response -> data && lineend [-1 ]== '\r' )
1228+ * lineend = '\0' ;
1229+ if (lineend != scan && lineend [-1 ] == '\r' )
12281230 lineend [-1 ] = '\0' ;
12291231
12301232 if (response -> part == P_HEADER_TOP )
12311233 {
1232- if (strncmp (response -> data , "HTTP/1." , sizeof ("HTTP/1." )- 1 )!= 0 )
1234+ if ( scan [0 ] != 'H' || scan [1 ] != 'T' || scan [2 ] != 'T'
1235+ || scan [3 ] != 'P' || scan [4 ] != '/' || scan [5 ] != '1'
1236+ || scan [6 ] != '.' )
12331237 {
12341238 response -> part = P_DONE ;
12351239 state -> err = true;
12361240 return -1 ;
12371241 }
1238- response -> status = (int )strtoul (response -> data
1239- + (sizeof ("HTTP/1.1 " )- 1 ), NULL , 10 );
1240- response -> part = P_HEADER ;
1242+ {
1243+ const char * p = scan + 9 ;
1244+ response -> status = (p [0 ] - '0' ) * 100
1245+ + (p [1 ] - '0' ) * 10
1246+ + (p [2 ] - '0' );
1247+ }
1248+ response -> part = P_HEADER ;
12411249 }
12421250 else
12431251 {
1244- if (string_starts_with_case_insensitive (response -> data ,
1245- "Content-Length:" ))
1246- {
1247- char * ptr = response -> data + (sizeof ("Content-Length:" )- 1 );
1248- while (* ptr == ' ' || * ptr == '\t' || * ptr == '\r' || * ptr == '\n' )
1249- ++ ptr ;
1250-
1251- response -> bodytype = T_LEN ;
1252- response -> len = strtol (ptr , NULL , 10 );
1253- }
1254- else if (string_is_equal_case_insensitive (response -> data ,
1255- "Transfer-Encoding: chunked" ))
1256- response -> bodytype = T_CHUNK ;
1257-
1258- if (response -> data [0 ]== '\0' )
1252+ if (scan [0 ] == '\0' )
12591253 {
12601254 if (response -> status == 100 )
12611255 response -> part = P_HEADER_TOP ;
@@ -1265,17 +1259,51 @@ static ssize_t net_http_receive_header(struct http_t *state, ssize_t len)
12651259 if (response -> bodytype == T_CHUNK )
12661260 response -> part = P_BODY_CHUNKLEN ;
12671261 }
1262+ scan = lineend + 1 ;
1263+ continue ;
12681264 }
1269- else
1265+
1266+ switch (scan [0 ] | 0x20 )
1267+ {
1268+ case 'c' :
1269+ if (strncasecmp (scan , "Content-Length:" ,
1270+ sizeof ("Content-Length:" ) - 1 ) == 0 )
1271+ {
1272+ char * ptr = scan + (sizeof ("Content-Length:" ) - 1 );
1273+ ssize_t val = 0 ;
1274+ while (* ptr == ' ' || * ptr == '\t' )
1275+ ++ ptr ;
1276+ while (* ptr >= '0' && * ptr <= '9' )
1277+ val = val * 10 + (* ptr ++ - '0' );
1278+ response -> bodytype = T_LEN ;
1279+ response -> len = val ;
1280+ }
1281+ break ;
1282+ case 't' :
1283+ if (strcasecmp (scan ,
1284+ "Transfer-Encoding: chunked" ) == 0 )
1285+ response -> bodytype = T_CHUNK ;
1286+ break ;
1287+ default :
1288+ break ;
1289+ }
1290+
12701291 {
12711292 union string_list_elem_attr attr ;
12721293 attr .i = 0 ;
1273- string_list_append (response -> headers , response -> data , attr );
1294+ string_list_append (response -> headers , scan , attr );
12741295 }
12751296 }
12761297
1277- memmove (response -> data , lineend + 1 , dataend - (lineend + 1 ));
1278- response -> pos = (dataend - (lineend + 1 ));
1298+ scan = lineend + 1 ;
1299+ }
1300+
1301+ if (scan != response -> data )
1302+ {
1303+ ssize_t leftover = dataend - scan ;
1304+ if (leftover > 0 )
1305+ memmove (response -> data , scan , leftover );
1306+ response -> pos = leftover ;
12791307 }
12801308
12811309 if (response -> part >= P_BODY )
0 commit comments