Dateien verwalten mit Modul jdk.httpserver
ulrich
2024-01-15 020a97355fdd8133da6cfd490b7b1e9618a1eb06
src/de/uhilger/httpserver/cm/FileManager.java
@@ -31,7 +31,6 @@
import de.uhilger.httpserver.oauth.BearerAuthenticator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -43,15 +42,9 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
 * <p>Der FileManager verknuepft einen HTTP-Endpunkt mit einem Ordner des lokalen
@@ -208,7 +201,7 @@
        case P_ZIP:
          String path = exchange.getRequestURI().toString();
          //logger.fine(path);
          String antwort = packFolder(helper.getFileName(exchange), path, exchange);
          String antwort = new Zipper().packFolder(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
          if(antwort.equalsIgnoreCase("ok")) {
            standardHeaderUndAntwort(exchange, SC_OK, antwort);
          } else {
@@ -218,7 +211,7 @@
        case P_UNZIP:
          path = exchange.getRequestURI().toString();
          //logger.fine(path);
          antwort = extractZipfile(helper.getFileName(exchange), path, exchange);
          antwort = new Unzipper().extractZipfile(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
          if(antwort.equalsIgnoreCase("ok")) {
            standardHeaderUndAntwort(exchange, SC_OK, antwort);
          } else {
@@ -665,184 +658,6 @@
    Headers resHeaders = exchange.getResponseHeaders();
    resHeaders.add(CONTENT_TYPE, HttpHelper.CT_TEXT_HTML);
    new HttpResponder().antwortSenden(exchange, status, antwort);
  }
  /* --------- ZIP entpacken ---------------- */
  public String extractZipfile(String fName, String relPath, HttpExchange e) {
    //logger.fine("fName: " + fName + ", relPath: " + relPath);
    String result = null;
    if (!relPath.startsWith(".")) {
      try {
        //File targetDir = new File(fileBase, relPath);
        //File targetDir = getTargetDir(relPath);
        File archive = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
        if(extract(archive)) {
          result = "ok";
        } else {
          result = "error while extracting";
        }
      } catch(Exception ex) {
        result = ex.getLocalizedMessage();
        //logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
      }
    } else {
      result = "Falsche relative Pfadangabe.";
    }
    return result;
  }
  /**
    * extract a given ZIP archive to the folder respective archive resides in
    * @param archive  the archive to extract
    * @throws Exception
    */
   private boolean extract(File archive) throws Exception {
      ZipFile zipfile = new ZipFile(archive);
      Enumeration en = zipfile.entries();
      while(en.hasMoreElements()) {
         ZipEntry zipentry = (ZipEntry) en.nextElement();
         unzip(zipfile, zipentry, archive.getParent());
      }
      zipfile.close();
      return true;
   }
   /**
    * unzip a given entry of a given zip file to a given location
    * @param zipfile  the zip file to read an entry from
    * @param zipentry  the zip entry to read
    * @param destPath  the path to the destination location for the extracted content
    * @throws IOException
    */
   private void unzip(ZipFile zipfile, ZipEntry zipentry, String destPath) throws IOException {
      byte buf[] = new byte[1024];
      InputStream is = zipfile.getInputStream(zipentry);
      String outFileName = destPath + File.separator + zipentry.getName();
      File file = new File(outFileName);
      if(!zipentry.isDirectory()) {
         file.getParentFile().mkdirs();
         if(!file.exists())
            file.createNewFile();
         FileOutputStream fos = new FileOutputStream(file);
         int i = is.read(buf, 0, 1024);
         while(i > -1) {
            fos.write(buf, 0, i);
            i = is.read(buf, 0, 1024);
         }
         fos.close();
         is.close();
      } else {
         file.mkdirs();
      }
   }
  /* --------------- Ordner packen ----------------- */
  /**
   * Einen Ordner packen.
   *
   * Als Ziel wird eine neue Datei mit Dateiendung '.zip' erzeugt, die so
   * heisst wie der Ordner, der gapckt werden soll. Die Datei mit
   * dem gepackten Ordnerinhalt wird in dem Ordner angelegt, der den zu
   * packenden Ordner enthaelt.
   *
   * @param fName  Name des zu packenden Ordners
   * @param relPath  relativer Pfad zum Ordner, der gepackt werden soll
   * @return die Meldung mit dem Ergebnis. Wenn die Meldung nicht "ok" lautet
   * wurde die ZIP-Datei nicht erzeugt und die Meldung nennt den Grund.
   */
  public String packFolder(String fName, String relPath, HttpExchange e) {
    if (!relPath.startsWith(".")) {
      try {
        //String fName = getFileName(e);
        //logger.fine("fName: " + fName);
        if (fName.endsWith(STR_SLASH)) {
          File dir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
          if(dir.isDirectory()) {
            //logger.fine("absPath: " + dir.getAbsolutePath());
            File parentDir = dir.getParentFile();
            StringBuilder fname = new StringBuilder();
            fname.append(dir.getName());
            fname.append(".zip");
            File archiveFile = new File(parentDir, fname.toString());
            pack(dir.getAbsolutePath(), archiveFile.getAbsolutePath());
            return "ok";
          } else {
            return "kein Ordner";
          }
        } else {
          return "kein Ordner";
        }
      } catch(Exception ex) {
        String result = ex.getLocalizedMessage();
        //logger.log(Level.SEVERE, result, ex);
        return result;
      }
    } else {
      return "Falsche relative Pfadangabe";
    }
  }
   /**
    * pack the contents of a given folder into a new ZIP compressed archive
    * @param folder  absolute path and name of the folder to pack
    * @param archive  absolute path and name of the archive to create from the given files
    * @throws Exception
    */
   private boolean pack(String folder, String archive) throws Exception {
      File file = new File(archive);
      FileOutputStream fos = new FileOutputStream(file);
      CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());
      ZipOutputStream zos = new ZipOutputStream(checksum);
      pack(zos, folder, "");
      zos.flush();
      zos.finish();
      zos.close();
      fos.flush();
      fos.close();
      return true;
   }
   /**
    * go through the given file structure recursively
    * @param zipFile  the ZIP file to write to
    * @param srcDir  the directory to pack during this cycle
    * @param subDir  the subdirectory to append to names of file entries inside the archive
    * @throws IOException
    */
   private void pack(ZipOutputStream zipFile, String srcDir, String subDir) throws IOException {
      File[] files = new File(srcDir).listFiles();
      for(int i = 0; i < files.length; i++) {
         if(files[i].isDirectory()) {
            pack(zipFile, files[i].getAbsolutePath(), subDir + File.separator + files[i].getName());
         }
         else {
            packFile(zipFile, subDir, files[i]);
         }
      }
   }
   /**
    * pack a given file
    * @param zipFile  the ZIP archive to pack to
    * @param dir  the directory name to append to name of file entry inside archive
    * @param file  the file to pack
    * @throws IOException
    */
   private void packFile(ZipOutputStream zipFile, String dir, File file) throws IOException
   {
      FileInputStream fileinputstream = new FileInputStream(file);
      byte buf[] = new byte[fileinputstream.available()];
      fileinputstream.read(buf);
      String dirWithSlashes = dir.replace('\\', '/');
      //System.out.println("zipping " + dirWithSlashes + "/" + file.getName());
      ZipEntry ze = new ZipEntry(dirWithSlashes + "/" + file.getName());
      ze.setMethod(ZipEntry.DEFLATED);
      zipFile.putNextEntry(ze);
      zipFile.write(buf, 0, buf.length);
      zipFile.closeEntry();
      fileinputstream.close();
   }