| 276 | #define NCHRS 3 |
| 277 | |
| 278 | static int |
| 279 | soishttpconnected(struct socket *so, void *arg, int waitflag) |
| 280 | { |
| 281 | char a, b, c; |
| 282 | struct mbuf *m, *n; |
| 283 | int ccleft, copied; |
| 284 | |
| 285 | DPRINT("start"); |
| 286 | if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) != 0 || sbfull(&so->so_rcv)) |
| 287 | goto gotit; |
| 288 | |
| 289 | /* |
| 290 | * Walk the socketbuffer and copy the last NCHRS (3) into a, b, and c |
| 291 | * copied - how much we've copied so far |
| 292 | * ccleft - how many bytes remaining in the socketbuffer |
| 293 | * just loop over the mbufs subtracting from 'ccleft' until we only |
| 294 | * have NCHRS left |
| 295 | */ |
| 296 | copied = 0; |
| 297 | ccleft = sbavail(&so->so_rcv); |
| 298 | if (ccleft < NCHRS) |
| 299 | goto readmore; |
| 300 | a = b = c = '\0'; |
| 301 | for (m = so->so_rcv.sb_mb; m; m = n) { |
| 302 | n = m->m_nextpkt; |
| 303 | for (; m; m = m->m_next) { |
| 304 | ccleft -= m->m_len; |
| 305 | if (ccleft <= NCHRS) { |
| 306 | char *src; |
| 307 | int tocopy; |
| 308 | |
| 309 | tocopy = (NCHRS - ccleft) - copied; |
| 310 | src = mtod(m, char *) + (m->m_len - tocopy); |
| 311 | |
| 312 | while (tocopy--) { |
| 313 | switch (copied++) { |
| 314 | case 0: |
| 315 | a = *src++; |
| 316 | break; |
| 317 | case 1: |
| 318 | b = *src++; |
| 319 | break; |
| 320 | case 2: |
| 321 | c = *src++; |
| 322 | break; |
| 323 | } |
| 324 | } |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | if (c == '\n' && (b == '\n' || (b == '\r' && a == '\n'))) { |
| 329 | /* we have all request headers */ |
| 330 | goto gotit; |
| 331 | } |
| 332 | |
| 333 | readmore: |
| 334 | soupcall_set(so, SO_RCV, soishttpconnected, arg); |
| 335 | return (SU_OK); |
no test coverage detected