From a8155e7bccfef9df2344c7aa575773efcb155ba9 Mon Sep 17 00:00:00 2001
From: hniksic <devnull@localhost>
Date: Fri, 5 Dec 2003 18:32:57 -0800
Subject: [PATCH] [svn] Correctly calculate bandwidth as total data read
 divided with download time.

---
 src/ChangeLog | 10 ++++++++++
 src/ftp.c     |  9 +++++----
 src/http.c    | 11 +++++++----
 src/retr.c    | 44 ++++++++++++++++++++++++++------------------
 src/retr.h    |  3 ++-
 5 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index e580c25c..24b86060 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2003-12-06  Hrvoje Niksic  <hniksic@xemacs.org>
+
+	* ftp.c (getftp): Ditto.
+
+	* http.c (gethttp): Correctly calculate bandwidth as total data
+	read divided with download time.
+
+	* retr.c (fd_read_body): Separate the return values for data
+	written and read.
+
 2003-12-05  Hrvoje Niksic  <hniksic@xemacs.org>
 
 	* http.c (H_REDIRECTED): Respect the HTTP/1.1 "303 See Other"
diff --git a/src/ftp.c b/src/ftp.c
index 436a8f52..da5be896 100644
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -246,6 +246,7 @@ getftp (struct url *u, long *len, long restval, ccon *con)
   long expected_bytes = 0L;
   int rest_failed = 0;
   int flags;
+  long rd_size;
 
   assert (con != NULL);
   assert (con->target != NULL);
@@ -1000,13 +1001,14 @@ Error in server response, closing control connection.\n"));
   flags = 0;
   if (restval && rest_failed)
     flags |= rb_skip_startpos;
+  *len = restval;
+  rd_size = 0;
   res = fd_read_body (dtsock, fp,
 		      expected_bytes ? expected_bytes - restval : 0,
-		      restval, len, &con->dltime, flags);
-  *len += restval;
+		      restval, &rd_size, len, &con->dltime, flags);
 
   tms = time_str (NULL);
-  tmrate = retr_rate (*len - restval, con->dltime, 0);
+  tmrate = retr_rate (rd_size, con->dltime, 0);
   /* Close data connection socket.  */
   fd_close (dtsock);
   fd_close (local_sock);
@@ -1247,7 +1249,6 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
 	  /* Not as great.  */
 	  abort ();
 	}
-      /* Time?  */
       tms = time_str (NULL);
       if (!opt.spider)
         tmrate = retr_rate (len - restval, con->dltime, 0);
diff --git a/src/http.c b/src/http.c
index 609e5fab..e3889bb0 100644
--- a/src/http.c
+++ b/src/http.c
@@ -982,7 +982,8 @@ struct http_stat
   char *remote_time;		/* remote time-stamp string */
   char *error;			/* textual HTTP error */
   int statcode;			/* status code */
-  double dltime;		/* time of the download in msecs */
+  long rd_size;			/* amount of data read from socket */
+  double dltime;		/* time it took to download the data */
   const char *referer;		/* value of the referer header. */
   char **local_file;		/* local file. */
 };
@@ -1718,9 +1719,11 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
     flags |= rb_read_exactly;
   if (hs->restval > 0 && contrange == 0)
     flags |= rb_skip_startpos;
+  hs->len = hs->restval;
+  hs->rd_size = 0;
   hs->res = fd_read_body (sock, fp, contlen != -1 ? contlen : 0,
-			  hs->restval, &hs->len, &hs->dltime, flags);
-  hs->len += hs->restval;
+			  hs->restval, &hs->rd_size, &hs->len, &hs->dltime,
+			  flags);
 
   if (hs->res >= 0)
     CLOSE_FINISH (sock);
@@ -2122,7 +2125,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
 	  return RETROK;
 	}
 
-      tmrate = retr_rate (hstat.len - hstat.restval, hstat.dltime, 0);
+      tmrate = retr_rate (hstat.rd_size, hstat.dltime, 0);
 
       if (hstat.len == hstat.contlen)
 	{
diff --git a/src/retr.c b/src/retr.c
index 73425cba..308289ac 100644
--- a/src/retr.c
+++ b/src/retr.c
@@ -143,7 +143,7 @@ limit_bandwidth (long bytes, struct wget_timer *timer)
 
 static int
 write_data (FILE *out, const char *buf, int bufsize, long *skip,
-	    long *transferred)
+	    long *written)
 {
   if (!out)
     return 1;
@@ -160,8 +160,9 @@ write_data (FILE *out, const char *buf, int bufsize, long *skip,
       if (bufsize == 0)
 	return 1;
     }
-  *transferred += bufsize;
+
   fwrite (buf, 1, bufsize, out);
+  *written += bufsize;
 
   /* Immediately flush the downloaded data.  This should not hinder
      performance: fast downloads will arrive in large 16K chunks
@@ -180,9 +181,11 @@ write_data (FILE *out, const char *buf, int bufsize, long *skip,
    by the progress gauge.
 
    STARTPOS is the position from which the download starts, used by
-   the progress gauge.  The amount of data read gets stored to
-   *TRANSFERRED.  The time it took to download the data (in
-   milliseconds) is stored to *ELAPSED.
+   the progress gauge.  If QTYREAD is non-NULL, the value it points to
+   is incremented by the amount of data read from the network.  If
+   QTYWRITTEN is non-NULL, the value it points to is incremented by
+   the amount of data written to disk.  The time it took to download
+   the data (in milliseconds) is stored to ELAPSED.
 
    The function exits and returns the amount of data read.  In case of
    error while reading data, -1 is returned.  In case of error while
@@ -190,7 +193,7 @@ write_data (FILE *out, const char *buf, int bufsize, long *skip,
 
 int
 fd_read_body (int fd, FILE *out, long toread, long startpos,
-	      long *transferred, double *elapsed, int flags)
+	      long *qtyread, long *qtywritten, double *elapsed, int flags)
 {
   int ret = 0;
 
@@ -212,11 +215,10 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
   int exact = flags & rb_read_exactly;
   long skip = 0;
 
-  /* How much data we've read.  This is used internally and is
-     unaffected by skipping STARTPOS.  */
-  long total_read = 0;
+  /* How much data we've read/written.  */
+  long sum_read = 0;
+  long sum_written = 0;
 
-  *transferred = 0;
   if (flags & rb_skip_startpos)
     skip = startpos;
 
@@ -251,9 +253,9 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
      means that it is unknown how much data is to arrive.  However, if
      EXACT is set, then toread==0 means what it says: that no data
      should be read.  */
-  while (!exact || (total_read < toread))
+  while (!exact || (sum_read < toread))
     {
-      int rdsize = exact ? MIN (toread - total_read, dlbufsize) : dlbufsize;
+      int rdsize = exact ? MIN (toread - sum_read, dlbufsize) : dlbufsize;
       double tmout = opt.read_timeout;
       if (progress_interactive)
 	{
@@ -265,7 +267,7 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
 	  waittm = (wtimer_read (timer) - last_successful_read_tm) / 1000;
 	  if (waittm + tmout > opt.read_timeout)
 	    {
-	      /* Don't allow waiting time to exceed read timeout. */
+	      /* Don't let total idle time exceed read timeout. */
 	      tmout = opt.read_timeout - waittm;
 	      if (tmout < 0)
 		{
@@ -278,9 +280,9 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
       ret = fd_read (fd, dlbuf, rdsize, tmout);
 
       if (ret == 0 || (ret < 0 && errno != ETIMEDOUT))
-	break;
+	break;			/* read error */
       else if (ret < 0)
-	ret = 0;		/* timeout */
+	ret = 0;		/* read timeout */
 
       if (progress || opt.limit_rate)
 	{
@@ -291,8 +293,8 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
 
       if (ret > 0)
 	{
-	  total_read += ret;
-	  if (!write_data (out, dlbuf, ret, &skip, transferred))
+	  sum_read += ret;
+	  if (!write_data (out, dlbuf, ret, &skip, &sum_written))
 	    {
 	      ret = -2;
 	      goto out;
@@ -307,7 +309,7 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
 #ifdef WINDOWS
       if (toread > 0)
 	ws_percenttitle (100.0 *
-			 (startpos + total_read) / (startpos + toread));
+			 (startpos + sum_read) / (startpos + toread));
 #endif
     }
   if (ret < -1)
@@ -316,11 +318,17 @@ fd_read_body (int fd, FILE *out, long toread, long startpos,
  out:
   if (progress)
     progress_finish (progress, wtimer_read (timer));
+
   if (elapsed)
     *elapsed = wtimer_read (timer);
   if (timer)
     wtimer_delete (timer);
 
+  if (qtyread)
+    *qtyread += sum_read;
+  if (qtywritten)
+    *qtywritten += sum_written;
+
   return ret;
 }
 
diff --git a/src/retr.h b/src/retr.h
index da93734d..9f9a3026 100644
--- a/src/retr.h
+++ b/src/retr.h
@@ -36,7 +36,8 @@ enum {
   rb_skip_startpos = 2
 };
 
-int fd_read_body PARAMS ((int, FILE *, long, long, long *, double *, int));
+int fd_read_body PARAMS ((int, FILE *, long, long, long *, long *, double *,
+                          int));
 
 typedef const char *(*hunk_terminator_t) PARAMS ((const char *, int, int));