Dateien verwalten mit Modul jdk.httpserver
ulrich
2024-01-22 c28d338cf5c917a867faf58204b85203d620f06e
commit | author | age
342aeb 1 /*
U 2   http-cm - File management extensions to jdk.httpserver
3   Copyright (C) 2021  Ulrich Hilger
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package de.uhilger.httpserver.cm.actor;
19
20 import com.google.gson.Gson;
21 import com.sun.net.httpserver.Headers;
22 import com.sun.net.httpserver.HttpExchange;
23 import de.uhilger.httpserver.base.HttpHelper;
24 import de.uhilger.httpserver.base.HttpResponder;
25 import de.uhilger.httpserver.base.handler.FileHandler;
26 import static de.uhilger.httpserver.base.handler.FileHandler.CONTENT_TYPE;
27 import static de.uhilger.httpserver.base.handler.FileHandler.SC_METHOD_NOT_ALLOWED;
28 import static de.uhilger.httpserver.base.handler.FileHandler.SC_OK;
29 import static de.uhilger.httpserver.base.handler.FileHandler.SC_UNPROCESSABLE_ENTITY;
30 import static de.uhilger.httpserver.cm.FileManager.OP_COPY;
31 import static de.uhilger.httpserver.cm.FileManager.OP_MOVE;
32 import static de.uhilger.httpserver.cm.FileManager.P_COPY;
33 import static de.uhilger.httpserver.cm.FileManager.P_DUPLICATE;
34 import static de.uhilger.httpserver.cm.FileManager.P_MOVE;
35 import static de.uhilger.httpserver.cm.FileManager.P_RENAME;
36 import static de.uhilger.httpserver.cm.FileManager.P_UNZIP;
37 import static de.uhilger.httpserver.cm.FileManager.P_ZIP;
38 import static de.uhilger.httpserver.cm.FileManager.STR_SLASH;
39 import static de.uhilger.httpserver.cm.FileManager.UTF8;
40 import de.uhilger.httpserver.cm.FileTransporter;
41 import java.io.BufferedReader;
42 import java.io.File;
43 import java.io.FileOutputStream;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.InputStreamReader;
47 import java.io.OutputStream;
48 import java.net.URLDecoder;
49 import java.util.Arrays;
50
51 /**
52  * Klasse mit Methoden zu schreibenden Dateioperationen
53  * 
54  * @author Ulrich Hilger, 15. Janauar 2024
55  */
56 public class Writer {
57   public void put(HttpExchange exchange, HttpHelper helper) throws IOException {
58     String query = exchange.getRequestURI().getQuery();
59     if (query != null) {
60       String[] params = query.split("=");
61       for (String param : params) {
62         //logger.fine("param: " + param);
63       }
64       switch (params[0]) {
65         case P_COPY:
66           copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_COPY);
67           break;
68         case P_MOVE:
69           copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_MOVE);
70           break;
71         case P_DUPLICATE:
72           if(Boolean.parseBoolean(params[1])) {
73             String neuerDateiName = new Mover().duplizieren(
74                     exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), 
75                     helper.getFileName(exchange));
76             //logger.fine("neuer Name: " + neuerDateiName);
77             standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
78           }
79           break;
80         case P_RENAME:
81           String neuerDateiName = new Renamer().umbenennen(exchange, helper, params[1]);
82           //logger.fine("neuer Name: " + neuerDateiName);
83           standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
84           break;
85         case P_ZIP:
86           String path = exchange.getRequestURI().toString();
87           //logger.fine(path);
88           String antwort = new Zipper().packFolder(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
89           if(antwort.equalsIgnoreCase("ok")) {
90             standardHeaderUndAntwort(exchange, SC_OK, antwort);
91           } else {
92             standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
93           }
94           break;
95         case P_UNZIP:
96           path = exchange.getRequestURI().toString();
97           //logger.fine(path);
98           antwort = new Unzipper().extractZipfile(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
99           if(antwort.equalsIgnoreCase("ok")) {
100             standardHeaderUndAntwort(exchange, SC_OK, antwort);
101           } else {
102             standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
103           }
104           break;
105       }
106     } else {
107       speichern(exchange, helper);
108     }
109   }
110   
111   private void copyOrMove(HttpExchange exchange, String quelle, String ziel, int op) throws IOException {
112     //logger.fine("quelle: " + quelle + ", ziel: " + ziel);
113     String[] dateiNamen = dateiliste(exchange);
114     new Mover().copyOrMoveFiles(quelle, ziel, dateiNamen, op, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
115     standardHeaderUndAntwort(exchange, SC_OK, "Dateien verarbeitet.");
116   }
117
118   public void loeschen(HttpExchange exchange, HttpHelper helper) throws IOException {
119     String[] dateiNamen = dateiliste(exchange);
120     String relPfad = helper.getFileName(exchange);
121     new Eraser().deleteFiles(relPfad, Arrays.asList(dateiNamen), exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
122     standardHeaderUndAntwort(exchange, SC_OK, "Dateien geloescht.");
123   }
124
125   private String[] dateiliste(HttpExchange exchange) throws IOException {
126     String body = new HttpHelper().bodyLesen(exchange);
127     //logger.fine("dateien: " + body);
128     Gson gson = new Gson();
129     return gson.fromJson(body, String[].class);
130   }
131
132   public void standardHeaderUndAntwort(HttpExchange exchange, int status, String antwort) throws IOException {
133     Headers resHeaders = exchange.getResponseHeaders();
134     resHeaders.add(CONTENT_TYPE, HttpHelper.CT_TEXT_HTML);
135     new HttpResponder().antwortSenden(exchange, status, antwort);
136   }  
137   
138   public void speichern(HttpExchange exchange, HttpHelper helper) throws IOException {
139     String fileName = helper.getFileName(exchange);
140     //logger.info("fileName: " + fileName);
141
142     // file ist die Datei, um die es geht
143     File file = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fileName);
144
145     String method = exchange.getRequestMethod();
146     if (fileName.endsWith(STR_SLASH)) {
147       //logger.info("neuer Ordner: " + file.getAbsolutePath());
148       // neuen Ordner erstellen oder ablehnen, wenn der Ordner schon existiert
149       if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
150         if (!file.exists()) {
151           file.mkdir();
152           new Writer().standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
153         } else {
154           String antwort = "Ordner existiert bereits.";
155           new Writer().standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
156         }
157       } else {
158         String antwort = "PUT fuer neuen Ordner nicht erlaubt, bitte POST verwenden.";
159         new Writer().standardHeaderUndAntwort(exchange, SC_METHOD_NOT_ALLOWED, antwort);        
160       }
161     } else {
162       //logger.info("Datei speichern: " + file.getAbsolutePath());
163       // Datei speichern
164       if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
165         if (file.exists()) {
166           FileTransporter trans = new FileTransporter();
167           file = trans.getNewFileName(file);
168         }
169       } else if (method.equalsIgnoreCase(HttpHelper.HTTP_PUT)) {
170         if (file.exists()) {
171           /*
172             muss delete() sein?
173             pruefen: ueberschreibt der FileWriter den alteen Inhalt oder 
174             entsteht eine unerwuenschte Mischung aus altem und neuem 
175             Inhalt?
176            */
177           file.delete();
178         } else {
179           file.getParentFile().mkdirs();
180         }
181       }
182       // Request Body mit dem Dateiinhalt in einen String lesen
183       StringBuilder sb = new StringBuilder();
184       InputStream is = exchange.getRequestBody();
185       BufferedReader in = new BufferedReader(new InputStreamReader(is));
186       String line = in.readLine();
187       while (line != null) {
188         sb.append(line);
189         line = in.readLine();
190       }
191
192       // dekodieren
193       String content = sb.toString();
194       //logger.fine(content);
195       String decoded = URLDecoder.decode(content, UTF8);
196       //logger.fine(decoded);
197
198       // in Datei schreiben
199       byte[] bytes = decoded.getBytes();
200       file.createNewFile();
201       OutputStream os = new FileOutputStream(file);
202       os.write(bytes);
203       os.flush();
204       os.close();
205       is.close();
206
207       // Antwort senden
208       standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
209     }
210   }  
211 }