httpread.c (3250B)
1 #include "crossroads.h" 2 3 void http_read (int sock, int isclient, unsigned char **bufp, int *buflen) { 4 char buf[10241]; 5 struct timeval tv, *tvp, start_tv; 6 fd_set readset; 7 int nfd, nread; 8 unsigned long long microsec; 9 10 msg ("Reading HTTP message from socket %d", sock); 11 12 /* Reset initial return buffer */ 13 *bufp = 0; 14 *buflen = 0; 15 16 /* Promote the verbosity of the backend */ 17 flag_verbose = activeservice->backend[current_backend].verbosity; 18 19 /* Get starting time */ 20 gettimeofday (&start_tv, 0); 21 lock_reporter(); 22 servicereport->nclients++; 23 servicereport->backendstate[current_backend].nclients++; 24 unlock_reporter(); 25 26 while (1) { 27 FD_ZERO (&readset); 28 FD_SET (sock, &readset); 29 if (activeservice->connectiontimeout) { 30 tv.tv_sec = activeservice->connectiontimeout; 31 tv.tv_usec = 0; 32 tvp = &tv; 33 } else 34 tvp = 0; 35 36 /* Wait for input */ 37 nfd = select (FD_SETSIZE, &readset, 0, 0, tvp); 38 39 /* Update the intermediate activity as far as the elapsed time 40 * is concerned. */ 41 gettimeofday (&tv, 0); 42 microsec = ( (tv.tv_sec * 1000000 + tv.tv_usec) - 43 (start_tv.tv_sec * 1000000 + start_tv.tv_usec) ); 44 gettimeofday (&start_tv, 0); 45 mark_activity (0, microsec / 1000000, st_intermediate); 46 // msg ("Spent another %g microsecs in this connection.", microsec); 47 48 if (nfd < 1) { 49 /* Done, with error */ 50 lock_reporter(); 51 servicereport->nclients--; 52 servicereport->backendstate[current_backend].nclients--; 53 unlock_reporter(); 54 if (nfd < 0) 55 error ("Failed to wait for HTTP input: %s", strerror(errno)); 56 else 57 error ("HTTP wait on socket %d interrupted", sock); 58 } 59 60 /* Got a live socket. */ 61 nread = read (sock, buf, sizeof(buf) - 1); 62 if (nread < 1) { 63 lock_reporter(); 64 servicereport->nclients--; 65 servicereport->backendstate[current_backend].nclients--; 66 unlock_reporter(); 67 mark_activity (0, 0, st_available); 68 if (nread < 0) 69 warning ("Failed to read HTTP input: %s", strerror(errno)); 70 else 71 warning ("Premature end of HTTP message, no bytes received"); 72 73 /* If we have a buffer so far, let the caller have it. 74 * Otherwise we're done. */ 75 if (*buflen) 76 return; 77 exit (0); 78 } 79 80 /* Got a good buffer from the network. 81 * We ASCII-Z terminate the buffer. That's only for display 82 * purposes in logging; internally not relevant. */ 83 buf[nread] = 0; 84 85 /* Update the intermediate activity as far as the read bytes 86 * are concerned. Update traffic / thruput logs. */ 87 // msg ("Read %d bytes from socket %d", nread, sock); 88 mark_activity (nread, 0, st_intermediate); 89 trafficlog ( (unsigned char *) buf, nread, isclient); 90 thruputlog ( (unsigned char *) buf, nread, isclient); 91 92 93 /* Got a succesful read. Add to buffer, update stats. */ 94 *bufp = xrealloc (*bufp, *buflen + nread + 1); 95 memcpy (*bufp + *buflen, buf, nread + 1); 96 *buflen += nread; 97 98 if (http_complete (*bufp, *buflen)) { 99 lock_reporter(); 100 servicereport->nclients--; 101 servicereport->backendstate[current_backend].nclients--; 102 unlock_reporter(); 103 mark_activity (0, 0, st_available); 104 msg ("HTTP read: complete message (%d bytes) '%s'", 105 *buflen, *bufp); 106 return; 107 } 108 } 109 }