crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

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 }