Neon [1] ist ein ultrakompakter, modular aufgebauter HTTP-Server auf der Grundlage des Java-Moduls jdk.httpserver zum Einbetten in Apps und Microservices. In diesem Dokument sind Module zur Erweiterung von Neon beschrieben.

Module

Die folgenden Module sind in diesem Dokument beschrieben.

neon-image

Das Modul neon-image erzeugt verkleinerte Fassungen eines Originalbildes 'on demand'. Hierzu wird in der Serverbeschreibung [2] die Klasse ImageFilter einem HttpContext hinzugefügt. Neben neon-image.jar ist die Klassenbibliothek Thumbnailator [4] im Classpath erforderlich.

in der Serverbeschreibung den ImageFilter einem HttpContext hinzufügen
  "server": [
    {
      "name": "Mein Server",
      "port":7001,
      "contexts": [
        {
          "className": "de.uhilger.neon.Handler",
          "sharedHandler": "true",
          "contextPath": "/meine-app/dateien",
          "filter": [
            "de.uhilger.neon.image.ImageFilter"
          ],
          "attributes": {
            "contextName": "fsrv",
            "fileBase": "/home/fred/www-daten",
            "imageFilterPattern": ".+\.jpg|.+\.jpeg|.+\.png|.+\.bmp"
          }
        }
      ]
    }
  ]

Der im Beispiel gezeigte Eintrag filter im Element contexts der Serverbeschreibung fügt dem betreffenden HTTP-Kontext ein Objekt der Klasse ImageFilter hinzu. Die Annahme ist, dass der ImageFilter üblicherweise gemeinsam mit einem FileServer [5] eingesetzt wird. Der FileServer erfordert im Attribut fileBase die Angabe eines Ablageortes für Dateien. Die Verwendung des FileServer ist nicht zwingend für den Einsatz eines ImageFilter, die Angabe fileBase wird aber so auch vom ImageFilter benötigt.

Mit dem Attribut imageFilterPattern wird dem ImageFilter in Form einer Regular Expression signalisiert, welche Dateien verarbeitet werden sollen. Eine Angabe von .+\.bmp würde zum Beispiel alle Dateien betreffen, die mit .bmp enden. Standardmäßig werden vom ImageFilter alle Dateien verarbeitet, die mit .jpg, .jpeg oder .png enden, was einer Angabe von .+\.jpg|.+\.jpeg|.+\.png entspricht. Wenn diese Gruppe von Dateien verarbeitet werden soll, kann daher die Angabe des Attributs imageFilterPattern entfallen. Das Muster wird vom ImageFilter ohne Berücksichtigung von Groß- und Kleinschreibung angewendet.

Mit Hinzufügen eines ImageFilter zu einem HTTP-Kontext wird automatisch für alle Dateien, deren Name zum angegebenen Muster passt, der ImageFilter aktiv. Liegt unter /home/fred/www-daten beispielsweise die Bilddatei mein-bild.jpg, wird mit Aufruf von http://localhost:7001/meine-app/dateien/mein-bild_tn.jpg eine verkleinerte Fassung mit 120 Bildpunkten erzeugt. Die folgenden Bildgrößen werden dabei verarbeitet

Table 1. Vom ImageFilter erzeugte Bildgrößen
Bildpunkte Dateiname

120

_tn

240

_kl

500

_sm

700

_mt

1200

_gr

Desweiteren bewirkt der Zusatz _b64 die Erzeugung einer Base64-kodierten Fassung, die für Grafiken mit Data-URI [6] dienen kann. Der Zusatz _b64 wird mit den obigen Namenszusätzen kombiniert indem er ihnen angehängt wird. Der Dateiname mein-bild_tn_b64.jpg erzeugt eine Base64-kodierte und auf 120 Bildpunkte verkleinerte Fassung des Originalbildes namens mein-bild.jpg.

neon-adoc

Mit neon-adoc wird Neon um die Möglichkeit erweitert, Dokumente im AsciiDoc-Format [7] nach HTML oder PDF zu transformieren. Neben der Datei neon-adoc.jar sind die Java-Archive aus dem Paket AsciidoctorJ [8] erforderlich. Die Umwandlung geschieht 'on-demand', es muss kein besonderer Build-Prozess hergestellt werden. Zur Umwandlung von Text im AsciiDoc-Format wird lediglich der AdocFilter aktiviert wie nachfolgend beschrieben.

in der Serverbeschreibung den AdocFilter einem HttpContext hinzufügen
  "server": [
    {
      "name": "Mein Server",
      "port":7001,
      "contexts": [
        {
          "className": "de.uhilger.neon.Handler",
          "sharedHandler": "false",
          "contextPath": "/meine-app",
          "filter": [
            "de.uhilger.neon.adoc.AdocFilter"
          ],
          "attributes": {
            "contextName": "fsrv",
            "fileBase": "/home/fred/www-daten"
          }
        }
      ]
    }
  ]

Der im Beispiel gezeigte Eintrag filter im Element contexts der Serverbeschreibung fügt dem betreffenden HTTP-Kontext ein Objekt der Klasse AdocFilter hinzu. Die Annahme ist, dass der AdocFilter gemeinsam mit einem FileServer [5] eingesetzt wird. Der FileServer erfordert im Attribut fileBase die Angabe eines Ablageortes für Dateien. Die Verwendung des FileServer ist nicht zwingend für den Einsatz eines AdocFilter, die Angabe fileBase wird aber so auch vom AdocFilter benötigt.

Der AdocFilter prüft für jede HTTP-Anfrage, ob eine Datei mit Endung .adoc angefragt ist. In diesem Fall wird geprüft, ob eine aktuelle HTML-Version dieser Datei am angefragten Ort besteht. Wenn nicht, wird die HTML-Version erzeugt. Als Variante kann in der Anfrage der Zusatz ?pdf=true hinzugefügt werden. Damit wird zusätzlich eine PDF-Version aus der AsciiDoc-Quelldatei erzeugt.

Die Auslieferung von AsciiDoc-Inhalten in Form von HTML oder PDF muss dann die Anwendung übernehmen. Hierfür kann ein Actor wie folgt erstellt werden.

ein Beispiel für einen Actor zur Auslieferung von AsciiDoc-Inhalten
@Actor(name = "fileServer")
public class FileActor {

  @Action(handler = {"fsrv"}, route = "/", type = Action.Type.GET, handlesResponse = true)
  public void run(HttpExchange exchange) throws IOException {
    URI uri = exchange.getRequestURI();
    String path = uri.getPath();
    if (path.toLowerCase().endsWith(".adoc")) {
      String fileBase = (String) exchange.getHttpContext().getAttributes()
          .getOrDefault(FileServer.ATTR_FILE_BASE, FileServer.STR_EMPTY);
      String query = uri.getQuery();
      new HttpResponder().serveFile(exchange, getDocFile(fileBase, path, query));
    } else {
      new FileServer().serveFile(exchange);
    }
  }

  private File getDocFile(String fileBase, String path, String query) throws IOException {
    String ext = "html";
    if(query.toLowerCase().contains("pdf=true")) {
      ext = "pdf";
    }
    String dot = ".";
    String noExt = path.substring(0, path.lastIndexOf(dot));
    return new File(fileBase, noExt + dot + ext);
  }
}

Im obigen Beispiel wird ein Actor an den HTTP-Kontext fsrv gebunden, der laut Serverbeschreibung wiederum an den Kontext-Pfad /meine-app gebunden ist. Der Actor verarbeitet mit dem Attribut route = "/" alle Routen, die an diesen HTTP-Kontext gerichtet sind. Eine Anfrage wie beispielsweise die unten gezeigte gelangt so an den oben dargestellten Actor.

http://localhost:7001/meine-app/pfad/zum/dokument.adoc

Für Anfragen, deren Pfad mit .adoc endet, wird anstelle der angefragten .adoc-Datei die gleichnamige HTML- oder PDF-Datei ausgegeben. Hierbei wird angenommen, dass zuvor der AdocFilter die angefragte AsciiDoc-Datei nach HTML oder PDF transformiert hat.

Andere Dateien werden an eine Instanz des FileServer von Neon [5] weitergereicht. Auf diese Weise werden alle angefragten Inhalte von diesem Actor ausgegeben, aber Anfragen nach AsciiDoc-Inhalten in ihrer nach HTML oder PDF transformierten Fassung.

neon-up

Das Modul neon-up stellt die Klasse MultipartStream aus dem Projekt Apache Commons mit geringfügigen Anpassungen bereit, mit denen die Klasse ohne weitere Abhängigkeiten eingesetzt werden kann. Das folgende Code-Beispiel zeigt, wie die Klasse auf der Server-Seite in einem Neon Actor verwendet werden kann, um zum Server heraufgeladene Dateien entgegenzunehmen.

Beispiel für den Einsatz der Klasse MultipartStream in einem Neon Actor
@Actor(name = "uploader")
public class UploadActor {

 public static final String ATTR_FILENAME = "filename=";
 public static final String TEMP_FILE_NAME = "temp.up";

 private String fileBase = "/some/path/to/storage";

 @Action(handler = {"up"}, route = "/upload", type = Action.Type.PUT, handlesResponse = false)
 public void run(HttpExchange exchange) throws IOException {
    Headers headers = exchange.getRequestHeaders();
    String ct = headers.getFirst(HttpHelper.CONTENT_TYPE);
    String[] parts = ct.split("=");
    String boundary = parts[1];
    InputStream is = exchange.getRequestBody();
    MultipartStream multipartStream = new MultipartStream(is, boundary.getBytes(), 4096, null);
    File file = new File(fileBase, TEMP_FILE_NAME);
    try {
      String value = "";
      boolean nextPart = multipartStream.skipPreamble();
      while (nextPart) {
        String header = multipartStream.readHeaders();
        if(header.contains(ATTR_FILENAME)) {
          // process file content
          // perhaps insert some file name processing here too
          // so that more than one uploaded files do not overwrite
          // each other
          OutputStream os = new FileOutputStream(file);
          multipartStream.readBodyData(os);
        } else {
          // read value
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          multipartStream.readBodyData(os);
          value = os.toString().substring(fileContext.length());
        }
        nextPart = multipartStream.readBoundary();
      }
    } catch (MultipartStream.MalformedStreamException e) {
      // the stream failed to follow required syntax
    } catch (IOException e) {
      // a read or write error occurred
    }

    // processing of files 'temp.up', 'temp-2.up', 'temp-3.up' etc.
    // is required here, e.g. rename, move ..
 }
}

Die Methode run im obigen Beispiel liest mit Hilfe der Klasse MultipartStream eine HTTP-Anfrage mit Content-Type multipart/form-data, wie sie bei HTTP-Uploads an den Server gesendet wird. Dabei ist der Einfachheit halber im Beispiel der Ablageort für die hogeladene Datei hart kodiert auf den Ort /some/path/to/storage.

Eine hochgeladene Datei erhält ebenfalls im Beispiel hart kodiert den Namen temp.up. Mit Abschluss des Uploads liegt also eine Datei /some/path/to/storage/temp.up vor, die von dort weiterverarbeitet, also z.B. von dort umbenannt und verschoben werden kann.

Diese Logik zur weiteren Verarbeitung einer oder mehrerer so hochgeladenen Dateien ist nicht im Beispiel enthalten und nur im Kommentar // processing of files symbolisiert. Die im Beispiel hart kodierten Variablen können in einer Anwendung zum Beispiel über die Serverbeschreibung von Neon [2] als Attribute eines HTTP-Kontext übergeben werden, wie es in vorangegangenen Kapiteln dieses Dokuments verschiedentlich zu sehen ist.

neon-template

Das Modul neon-template erweitert Neon um die Verarbeitung von Vorlagen (Templates) auf der Grundlage von Mustache [11]. Neben neon-template.jar ist die Klassenbibliothek compiler.jar von Mustache im Classpath erforderlich.

Die Klasse TemplateWorker des Moduls neon-template wird zur Mischung von Daten mit einer Vorlage verwendet. Ihre Methode render fügt dem HTML aus einer Mustache-Vorlage die Daten hinzu, die ihr als HashMap übergeben werden.

Beispiel eines Actors, der eine Mustache-Vorlage rendert (Auszug)
public void run(HttpExchange exchange) throws IOException {
  // die gewuenschte Datei bestimmen
  String fileBase = (String) exchange.getHttpContext().getAttributes()
                 .getOrDefault(FileServer.ATTR_FILE_BASE, FileServer.STR_EMPTY);
  String fileName = new HttpHelper().getFileName(exchange);
  File file = new File(fileBase, fileName);
  // die Daten fuer die Vorlage bereitstellen
  Map data = new HashMap();
  data.put("title", file.getName());
  data.put("content", getFileContent(file));
  // die Daten in die Vorlage eintragen
  String html =
    new TemplateWorker().render(exchange, data, "vorlage.mustache");
  // die Antwort ausgeben
  new HttpResponder().antwortSenden(exchange, HttpResponder.SC_OK, html);
}

public String getFileContent(File file) {
  BufferedReader reader = new BufferedReader(new FileReader(file));
  StringWriter writer = new StringWriter();
  String line = reader.readLine();
  while (line != null) {
    writer.write(line);
    writer.write("\r\n");
    line = reader.readLine();
  }
  reader.close();
  return writer.toString();
}

Die Angabe der Vorlage erfolgt als einfacher Dateiname in Form eines String. Der TemplateWorker versucht, diese vom Ablageort zu lesen, der im Attribut FileServer.ATTR_FILE_BASE für den HTTP-Context angegeben wurde. Gelingt dies nicht, wird versucht, die Vorlage aus dem Classpath zu lesen. Ist das Lesen der Vorlage erfolgreich, werden die Daten aus der HashMap data in die Vorlage eingebaut und das Ergebnis ausgegeben. Die HashMap data wird dazu mit den Angaben beladen, die in der Vorlage als Platzhalter eingetragen sind.

Beispiel einer Mustache-Vorlage für eine HTML-Datei
<!DOCTYPE html>
<html>
  <head>
    <title>{{title}}</title>
  </head>
  <body>
    <div class="inhalt">
      {{content}}
    </div>
  </body>
</html>

Die Logik zur Bestimmung der Vorlage zum jeweiligen Inhalt ist in der Klasse TemplateWorker bewußt einfach gehalten. Sie lässt sich mit einer eigenen Implementierung der Klasse beliebig abwandeln. Zudem beinhaltet die Klassenbibliothek compiler.jar, die die Java-Implementierung für Mustache bereitstellt, umfangreiche zusätzliche Möglichkeiten der Nutzung von Mustache. Die hier vorgestellte Implementierung stellt nur ein Beispiel und mithin den Ausgangspunkt dar, wie Mustache-Vorlagen aus Neon heraus verwendbar sind.

neon-fm

Das Modul neon-fm etabliert Verwaltungsfunktionen für den Inhalt eines Ordners im Dateisystem. Es erfordert neben der Datei neon-fm.jar die Datei fm.jar [12]. Die Funktionen zur Dateiverwaltung von neon-fm werden mit einem Aktor nach folgendem Beispiel eingebunden.

ein Aktor zur Einbindung der Funktionen von neon-fm
@Actor(name = "fileManager")
public class FileManager {

  private static final String CTX = "cms";

  @Action(handler={CTX}, route="/", type=Action.Type.GET, handlesResponse=true)
  public void list(HttpExchange exchange) {
    new FileCatalog().list(exchange);
  }

  @Action(handler = {CTX}, route = "/", type = Action.Type.POST, handlesResponse = true)
  public void create(HttpExchange exchange) {
    new FileCreator().create(exchange);
  }

  @Action(handler={CTX}, route="/", type=Action.Type.DELETE, handlesResponse=true)
  public void del(HttpExchange exchange) {
    new FileEraser().delete(exchange);
  }

  @Action(handler={CTX}, route="/", type=Action.Type.PUT, handlesResponse=true)
  public void chg(HttpExchange exchange) {
    new FileManipulator().change(exchange);
  }
}

Die Annotationen der Klasse FileManager verweisen auf einen HTTP-Kontext namens cms. Ein so annotierter Aktor wird von Neon selbsttätig mit dem passenden HTTP-Handler verbunden, sofern in der Serverbeschreibung von Neon eine Eintrag wie folgt enthalten ist.

Beispiel für einen Kontext zum Einbinden des FileManager
{
  "className": "de.uhilger.neon.Handler",
  "sharedHandler": "false",
  "contextPath": "/daten",
  "filter": [
    "eventuelle Filter hier angeben"
  ],
  "attributes": {
    "contextName": "cms",
    "fileBase": "/home/fred/www-daten",
    "weitereAttribute": "..hier angeben .."
  }
}

Damit werden alle Inhalte des Ordners /home/fred/www-daten für die Dateiverwaltung über den Indikator /daten/ zur Bearbeitung zugänglich. Nachfolgend sind die Funktionen der Dateiverwaltung aufgelistet und im Detail beschrieben.

Für die weitere Beschreibung wird angenommen, dass der FileManager als Teil einer App gestartet wurde, die über den URL http://localhost:9292/ zugänglich ist.

Dateiinhalt lesen

Das Lesen von Dateiinhalten ist vergleichbar mit dem Aufruf eines URL im Webbrowser.

Beispiel

Aufruf via HTTP GET an http://localhost:9292/daten/texte/test.txt

Für einen URL, der nicht mit einem Schrägstrich endet ist die Annahme, dass eine Datei gemeint ist und der Inhalt der betreffenden Datei wird ausgeliefert. Der Inhalt der Datei /home/fred/www-daten/texte/test.txt wird in der Antwort zurückgegeben.

Dateien auflisten

Für den Aufruf eines URL, der einen Ordner bezeichnet, wird der Ordnerinhalt aufgelistet.

Beispiel

Aufruf via HTTP GET an http://localhost:9292/daten/pg/neon/

Wenn der URL mit einem Schrägstrich endet, wird der Inhalt des betreffenden Ordners als Dateiliste im JSON-Format geliefert. Mit obigem Aufruf wird der Inhalt des Ordners /home/fred/www-daten/pg/neon/ ausgegeben.

Die Liste eines Ordnerinhalts im JSON-Format
{
  "pfad": "/pg/neon/",
  "dateien": [{
      "name": "anleitung.adoc",
      "typ": "datei",
      "typKlasse": "icon-doc-inv",
      "bild": false
    }, {
      "name": "anleitung.html",
      "typ": "datei",
      "typKlasse": "icon-doc-inv",
      "bild": false
    }, {
      "name": "index.htmi",
      "typ": "datei",
      "typKlasse": "icon-doc-inv",
      "bild": false
    }, {
      "name": "module",
      "typ": "ordner",
      "typKlasse": "icon-folder",
      "bild": false
    }]
}

Bilder

Für Dateien mit den Endungen jpg, jpeg oder png erscheinen nur die Originaldateien in der Dateiliste. Varianten, wie sie mit dem Modul neon-image entstehen, werden ausgeblendet. Ist etwa in einem Ordner eine Datei namens mein-bild.jpg abgelegt und es wurde am selben Ort eine kleinere Fassung namens mein-bild_kl.jpg gespeichert, erscheint nur der Eintrag für die Datei mein-bild.jpg in der Dateiliste.

Datei schreiben (PUT)

Aufruf von HTTP PUT fuer eine Datei ueberschreibt eine bestehende Datei mit dem im Body der HTTP-Nachricht uebergebenen Inhalt oder legt eine Datei mit diesem Inhalt an.

Beispiel

Aufruf via HTTP PUT an http://localhost:9292/daten/texte/test.txt

Der Body des HTTP PUT Aufrufs wird in die angegebene Datei geschrieben. Mit obigem Aufruf wird der Inhalt im Body des Aufrufs in die Datei /home/fred/www-daten/texte/test.txt geschrieben. Wenn die Datei existiert, wird sie überschrieben, sonst wird sie mit diesem Inhalt angelegt.

Datei schreiben (POST)

Aufruf von HTTP POST fuer eine Datei legt eine neue Datei mit dem im Body uebergebenen Inhalt an oder erzeugt eine neue Datei mit einer laufenden Nummer, falls diese Datei schon existiert.

Beispiel

Aufruf via HTTP POST an http://localhost:9292/daten/texte/test.txt

Der Body des HTTP POST Aufrufs wird in die unter dem angegebenen Namen neu angelegte Datei geschrieben. Mit obigem Aufruf wird die Datei /home/fred/www-daten/texte/test.txt neu angelegt und der Inhalt im Body des Aufrufs in die Datei geschrieben. Wenn die Datei schon existiert, wird eine neue Datei angelegt, deren Name eine Nummer angehängt wird, z.B. test-1.txt, und besagter Inhalt geschrieben.

Die Antwort liefert den Namen der Datei, die geschrieben wurde.

Ordner anlegen

Aufruf von HTTP POST fuer einen Ordner legt einen neuen Ordner an wenn er noch nicht existiert oder erzeugt einen HTTP-Fehler 422.

Beispiel

Aufruf via HTTP POST an http://localhost:9292/daten/pg/neon/dok/

Der Ordner dok wird im Ordner /home/fred/www-daten/pg/neon/ angelegt, wenn er noch nicht existiert. Wenn es schon einen Ordner dok am angegebenen Ort gibt, wird der HTTP-Fehler 422 Unprocessable Entity zurückgegeben.

Löschen

HTTP DELETE loescht die Liste der Dateien und Ordner im Body.

Beispiel

Aufruf von HTTP DELETE an http://localhost:9292/daten/pg/neon/

Datei- und Ordnerliste im Body einer Anfrage
["test.txt","dok"]

Die Datei test.txt und der Ordner dok werden aus dem Ordner /home/fred/www-daten/pg/neon/ gelöscht. Das Löschen geschieht rekursiv, es werden also auch alle Inhalte von dok gelöscht.

Vorsicht: Es gibt keine Sicherungsanfrage vorab, der Client muss selbst für geeignete Sicherheitsfunktionen sorgen, die dem Löschen vorgeschaltet werden.

Bilder

Beim Löschen von Dateien mit den Endungen jpg, jpeg oder png werden alle Dateien gelöscht, auch Varianten, wie sie mit dem Modul neon-image entstehen. Ist etwa in einem Ordner eine Datei namens mein-bild.jpg abgelegt und es wurde am selben Ort eine kleinere Fassung namens mein-bild_kl.jpg gespeichert, werden beide Fassungen gelöscht.

Kopieren

HTTP PUT mit dem Parameter ?copyFrom=pfad kopiert die Liste der Datei- oder Ordnernamen im Body der Anfrage vom Pfad in copyFrom zum Pfad dieser Anfrage.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/pg/neon/?copyFrom=/entwurf/texte/

Datei- und Ordnerliste im Body der Anfrage
["anleitung.adoc","dok","ordner-2","bild.jpg"]

Die Dateien und Ordner aus der Liste im Body der Anfrage werden vom Ordner /home/fred/www-daten/entwurf/texte in den Ordner /home/fred/www-daten/pg/neon kopiert. Das Kopieren erfolgt rekursiv, d.h. alle Inhalte von Ordnern werden mit verschoben.

Jede Datei, die im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden Nummer, dann wird der Quellordner ans Ziel kopiert.

Die Angabe des Quellpfades in copyFrom bezieht sich auf einen Pfad relativ zum Pfad, mit dem der FileManager eingeschaltet wurde.

Bilder

Beim Kopieren von Dateien mit den Endungen jpg, jpeg oder png werden alle Dateien kopiert, auch Varianten, wie sie mit dem Modul neon-image entstehen. Ist etwa in einem Ordner eine Datei namens mein-bild.jpg abgelegt und es wurde am selben Ort eine kleinere Fassung namens mein-bild_kl.jpg gespeichert, werden beide Fassungen kopiert.

Verschieben

HTTP PUT mit dem Parameter ?moveFrom=pfad verschiebt die Liste der Datei- oder Ordnernamen im Body der Anfrage vom Pfad in moveFrom zum Pfad dieser Anfrage.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/pg/neon/?moveFrom=/entwurf/texte/

Datei- und Ordnerliste im Body der Anfrage
["anleitung.adoc","dok","ordner-2","bild.jpg"]

Die Dateien und Ordner aus der Liste im Body der Anfrage werden vom Ordner /home/fred/www-daten/entwurf/texte in den Ordner /home/fred/www-daten/pg/neon verschoben. Das Verschieben erfolgt rekursiv, d.h. alle Inhalte von Ordnern werden mit verschoben.

Jede Datei, die im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden Nummer, dann wird der Quellordner ans Ziel verschoben.

Die Angabe des Quellpfades in moveFrom bezieht sich auf einen Pfad relativ zum Pfad, mit dem der FileManager eingeschaltet wurde.

Bilder

Beim Verschieben von Dateien mit den Endungen jpg, jpeg oder png werden alle Dateien verschoben, auch Varianten, wie sie mit dem Modul neon-image entstehen. Ist etwa in einem Ordner eine Datei namens mein-bild.jpg abgelegt und es wurde am selben Ort eine kleinere Fassung namens mein-bild_kl.jpg gespeichert, werden beide Fassungen verschoben.

Duplizieren

HTTP PUT mit dem Parameter ?duplicate legt die Kopie einer Datei am gegenwärtigen Ablageort an.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/texte/test.txt?duplicate

Im Ordner /home/fred/www-daten/texte wird ein Duplikat der Datei test.txt unter dem Namen test-Kopie.txt angelegt. Wenn es die Datei bereits gibt, wird dem Namen eine laufende Nummer angehängt, z.B. test-Kopie-2.txt.

Umbenennen

HTTP PUT mit dem Parameter ?renameTo=neuer Name benennt die Datei oder den Ordner um, sofern der neue Name noch nicht vergeben ist.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/texte/test.txt?renameTo=textdatei.txt

Die Datei /home/fred/www-daten/texte/test.txt erhält den neuen Namen textdatei.txt, sofern eine Datei solchen Namens in diesem Ordner noch nicht existiert.

Bilder

Beim Umbenennen von Dateien mit den Endungen jpg, jpeg oder png werden alle Dateien umbenannt, auch Varianten, wie sie mit dem Modul neon-image entstehen. Ist etwa in einem Ordner eine Datei namens mein-bild.jpg abgelegt und es wurde am selben Ort eine kleinere Fassung namens mein-bild_kl.jpg gespeichert, werden beide Fassungen umbenannt.

Packen

HTTP PUT mit dem Parameter ?zip packt den Ordner.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/texte/?zip

Der Inhalt des Ordners /home/fred/www-daten/texte wird komprimiert und als Datei /home/fred/www-daten/texte.zip erstellt. Das Packen erfolgt rekursiv, d.h. alle Inhalte des betreffenden Ordners werden ins komprimierte ZIP-Archiv gepackt.

Entpacken

HTTP PUT mit dem Parameter ?unzip entpackt eine ZIP-Archivdatei.

Beispiel

Aufruf von HTTP PUT an http://localhost:9292/daten/archive/mein-archiv.zip?unzip

Der Inhalt der ZIP-Archivdatei /home/fred/www-daten/archive/mein-archiv.zip wird in den Ordner /home/fred/www-daten/archive entpackt.

Lizenz

Alle hier beschriebenen Module außer dem Modul neon-up werden unter den Bedigungen der GNU Affero General Public License 3.0 bereitgestellt [9]. Das Modul neon-up unterliegt den Bedingungen der Apache License 2.0 [10].

Änderungsverlauf

Version 1

Vom 18. Juni 2021

http-base - Dateien und Streams ausliefern
http-realm - Nutzerverzeichnis zur Authentifizierung
http-oauth - Bearer Authentication für Neon
http-up - Dateien zu Neon heraufladen
http-adoc - Asciidoctor mit Neon transformieren
http-image - Bilder mit Neon verwenden

Version 2

Vom 2. Januar 2022

http-cm - Dateien mit Neon verwalten
http-template - Mustache-Vorlagen mit Neon verarbeiten

Version 3

Vom 26. Februar 2024

neon-auth [3] - Bearer Token Authentication für Neon 2
neon-image - Bilder mit Neon 2 verwenden
neon-adoc - AsciiDoc mit Neon 2 transformieren
neon-up - Dateien zu Neon 2 heraufladen
neon-template - Mustache-Vorlagen mit Neon 2 verwenden

Version 4

Vom 23. November 2024

neon-fm - Dateien und Ordner mit Neon 2 verwalten

Verweise