[BACK]Return to fetch.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ftp

Diff for /src/usr.bin/ftp/fetch.c between version 1.177 and 1.178

version 1.177, 2019/11/04 15:36:36 version 1.178, 2019/11/14 23:48:37
Line 69 
Line 69 
 #include "cmds.h"  #include "cmds.h"
   
 static int      url_get(const char *, const char *, const char *, int);  static int      url_get(const char *, const char *, const char *, int);
   static int      save_chunked(FILE *, struct tls *, int , char *, size_t);
 static void     aborthttp(int);  static void     aborthttp(int);
 static void     abortfile(int);  static void     abortfile(int);
 static char     hextochar(const char *);  static char     hextochar(const char *);
Line 213 
Line 214 
         int status;          int status;
         int save_errno;          int save_errno;
         const size_t buflen = 128 * 1024;          const size_t buflen = 128 * 1024;
           int chunked = 0;
   
         direction = "received";          direction = "received";
   
Line 687 
Line 689 
                  * the original URI (path).                   * the original URI (path).
                  */                   */
                 if (credentials)                  if (credentials)
                         fprintf(fin, "GET %s HTTP/1.0\r\n"                          fprintf(fin, "GET %s HTTP/1.1\r\n"
                               "Connection: close\r\n"
                             "Proxy-Authorization: Basic %s\r\n"                              "Proxy-Authorization: Basic %s\r\n"
                             "Host: %s\r\n%s%s\r\n\r\n",                              "Host: %s\r\n%s%s\r\n\r\n",
                             epath, credentials,                              epath, credentials,
                             proxyhost, buf ? buf : "", httpuseragent);                              proxyhost, buf ? buf : "", httpuseragent);
                 else                  else
                         fprintf(fin, "GET %s HTTP/1.0\r\n"                          fprintf(fin, "GET %s HTTP/1.1\r\n"
                               "Connection: close\r\n"
                             "Host: %s\r\n%s%s\r\n\r\n",                              "Host: %s\r\n%s%s\r\n\r\n",
                             epath, proxyhost, buf ? buf : "", httpuseragent);                              epath, proxyhost, buf ? buf : "", httpuseragent);
         } else {          } else {
Line 712 
Line 716 
 #ifndef NOSSL  #ifndef NOSSL
                 if (credentials) {                  if (credentials) {
                         fprintf(fin,                          fprintf(fin,
                             "GET /%s %s\r\nAuthorization: Basic %s\r\nHost: ",                              "GET /%s HTTP/1.1\r\n"
                             epath, restart_point ?                              "Connection: close\r\n"
                             "HTTP/1.1\r\nConnection: close" : "HTTP/1.0",                              "Authorization: Basic %s\r\n"
                             credentials);                              "Host: ", epath, credentials);
                         free(credentials);                          free(credentials);
                         credentials = NULL;                          credentials = NULL;
                 } else                  } else
 #endif  /* NOSSL */  #endif  /* NOSSL */
                         fprintf(fin, "GET /%s %s\r\nHost: ", epath,                          fprintf(fin,
 #ifndef SMALL                              "GET /%s HTTP/1.1\r\n"
                             restart_point ? "HTTP/1.1\r\nConnection: close" :                              "Connection: close\r\n"
 #endif /* !SMALL */                              "Host: ", epath);
                             "HTTP/1.0");  
                 if (proxyhost) {                  if (proxyhost) {
                         fprintf(fin, "%s", proxyhost);                          fprintf(fin, "%s", proxyhost);
                         port = NULL;                          port = NULL;
Line 942 
Line 945 
                         retryafter = strtonum(cp, 0, 0, &errstr);                          retryafter = strtonum(cp, 0, 0, &errstr);
                         if (errstr != NULL)                          if (errstr != NULL)
                                 retryafter = -1;                                  retryafter = -1;
   #define TRANSFER_ENCODING "Transfer-Encoding: "
                   } else if (strncasecmp(cp, TRANSFER_ENCODING,
                               sizeof(TRANSFER_ENCODING) - 1) == 0) {
                           cp += sizeof(TRANSFER_ENCODING) - 1;
                           cp[strcspn(cp, " \t")] = '\0';
                           if (strcasecmp(cp, "chunked") == 0)
                                   chunked = 1;
                 }                  }
                 free(buf);                  free(buf);
         }          }
   
           /* Content-Length should be ignored for Transfer-Encoding: chunked */
           if (chunked)
                   filesize = -1;
   
         if (isunavail) {          if (isunavail) {
                 if (retried || retryafter != 0)                  if (retried || retryafter != 0)
                         warnx("Error retrieving %s: 503 Service Unavailable",                          warnx("Error retrieving %s: 503 Service Unavailable",
Line 1005 
Line 1019 
         /* Finally, suck down the file. */          /* Finally, suck down the file. */
         if ((buf = malloc(buflen)) == NULL)          if ((buf = malloc(buflen)) == NULL)
                 errx(1, "Can't allocate memory for transfer buffer");                  errx(1, "Can't allocate memory for transfer buffer");
         i = 0;  
         len = 1;  
         oldinti = signal(SIGINFO, psummary);          oldinti = signal(SIGINFO, psummary);
         while (len > 0) {          if (chunked) {
                 len = fread(buf, 1, buflen, fin);                  if (save_chunked(fin, tls, out, buf, buflen) == -1) {
                 bytes += len;                          signal(SIGINFO, oldinti);
                 for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {                          goto cleanup_url_get;
                         if ((i = write(out, cp, wlen)) == -1) {                  }
                                 warn("Writing %s", savefile);          } else {
                                 signal(SIGINFO, oldinti);                  i = 0;
                                 goto cleanup_url_get;                  len = 1;
                   while (len > 0) {
                           len = fread(buf, 1, buflen, fin);
                           bytes += len;
                           for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {
                                   if ((i = write(out, cp, wlen)) == -1) {
                                           warn("Writing %s", savefile);
                                           signal(SIGINFO, oldinti);
                                           goto cleanup_url_get;
                                   }
                                   else if (i == 0)
                                           break;
                         }                          }
                         else if (i == 0)                          if (hash && !progress) {
                                 break;                                  while (bytes >= hashbytes) {
                                           (void)putc('#', ttyout);
                                           hashbytes += mark;
                                   }
                                   (void)fflush(ttyout);
                           }
                 }                  }
                 if (hash && !progress) {                  signal(SIGINFO, oldinti);
                         while (bytes >= hashbytes) {                  if (hash && !progress && bytes > 0) {
                           if (bytes < mark)
                                 (void)putc('#', ttyout);                                  (void)putc('#', ttyout);
                                 hashbytes += mark;                          (void)putc('\n', ttyout);
                         }  
                         (void)fflush(ttyout);                          (void)fflush(ttyout);
                 }                  }
                   if (len != 0) {
                           warnx("Reading from socket: %s", sockerror(tls));
                           goto cleanup_url_get;
                   }
         }          }
         signal(SIGINFO, oldinti);  
         if (hash && !progress && bytes > 0) {  
                 if (bytes < mark)  
                         (void)putc('#', ttyout);  
                 (void)putc('\n', ttyout);  
                 (void)fflush(ttyout);  
         }  
         if (len != 0) {  
                 warnx("Reading from socket: %s", sockerror(tls));  
                 goto cleanup_url_get;  
         }  
         progressmeter(1, NULL);          progressmeter(1, NULL);
         if (          if (
 #ifndef SMALL  #ifndef SMALL
Line 1079 
Line 1100 
         free(newline);          free(newline);
         free(credentials);          free(credentials);
         return (rval);          return (rval);
   }
   
   static int
   save_chunked(FILE *fin, struct tls *tls, int out, char *buf, size_t buflen)
   {
   
           char                    *header, *end, *cp;
           unsigned long           chunksize;
           size_t                  hlen, rlen, wlen;
           ssize_t                 written;
           char                    cr, lf;
   
           for (;;) {
                   header = ftp_readline(fin, &hlen);
                   if (header == NULL)
                           break;
                   /* strip CRLF and any optional chunk extension */
                   header[strcspn(header, ";\r\n")] = '\0';
                   errno = 0;
                   chunksize = strtoul(header, &end, 16);
                   if (errno || header[0] == '\0' || *end != '\0' ||
                       chunksize > INT_MAX) {
                           warnx("Invalid chunk size '%s'", header);
                           free(header);
                           return -1;
                   }
                   free(header);
   
                   if (chunksize == 0) {
                           /* We're done.  Ignore optional trailer. */
                           return 0;
                   }
   
                   for (written = 0; chunksize != 0; chunksize -= rlen) {
                           rlen = (chunksize < buflen) ? chunksize : buflen;
                           rlen = fread(buf, 1, rlen, fin);
                           if (rlen == 0)
                                   break;
                           bytes += rlen;
                           for (cp = buf, wlen = rlen; wlen > 0;
                                wlen -= written, cp += written) {
                                   if ((written = write(out, cp, wlen)) == -1) {
                                           warn("Writing output file");
                                           return -1;
                                   }
                           }
                   }
   
                   if (rlen == 0 ||
                       fread(&cr, 1, 1, fin) != 1 ||
                       fread(&lf, 1, 1, fin) != 1)
                           break;
   
                   if (cr != '\r' || lf != '\n') {
                           warnx("Invalid chunked encoding");
                           return -1;
                   }
           }
   
           if (ferror(fin))
                   warnx("Error while reading from socket: %s", sockerror(tls));
           else
                   warnx("Invalid chunked encoding: short read");
   
           return -1;
 }  }
   
 /*  /*

Legend:
Removed from v.1.177  
changed lines
  Added in v.1.178