Zum Inhalt springen

OBS/Kostenpflichtige Module/RESTServer/Datei-Upload

Aus OBS Wiki
Kostenpflichtige Module

Internet-Shop
UPS
IMS Professional
SMS
Mehrlager-Verwaltung
Mehrsprachen Modul
Multilanguage Modul
EVA Marketing Tool
Termin-Projekte
Edifact-Schnittstelle
Backup Überwachung Email
OBS Geo Daten
DeliSprint / DPD
Filialen
Cashback
Moebelschnittstelle
Dokumenten Manager
DocuWare-Schnittstelle
OFML-Kalkulation
Versicherungsschaden
Gutschriftsanzeigen
Kameraverwaltung
DataInOut
OpenMasterData / IDS
Sammelpositionen



Datei-Upload

Ein Endpunkt nimmt Dateien nur entgegen, wenn er dafür freigeschaltet ist (re_upload = 1, siehe Endpunkte). Dann gilt nicht das JSON-Body-Limit von 10 MB, sondern die pro Endpunkt konfigurierte Grösse (re_upload_size, Standard 25 MB; Überschreitung -> 413).

Diese Seite beschreibt die Übertragung - was ein Client senden muss und was der Server antwortet. Was das Skript davon sieht, sind vier Aufrufe (oReader.UploadPath(), UploadName(), UploadType(), UploadSha()) und steht unter Scripting. Ein vollständiges Beispiel zeigt Beispiel 6.

HINWEIS: Der Server legt die Datei in einem temporären Verzeichnis ab und

verschiebt sie nicht selbst. Übernimmt das Skript sie nicht an ihren

Zielort, bleibt sie dort liegen.

Einfacher Upload (multipart/form-data)

Eine Datei pro Request. Name und Content-Type stammen aus der Content-Disposition der Datei-Partie (filename=). Der Server speichert die erste Datei-Partie und ruft das Skript auf.

Die übrigen Partien des Formulars - alles ohne filename= - liest das Skript über oReader.Form('<name>'). Der Wert ist UTF-8 und auf 1024 Zeichen begrenzt, der Name auf Buchstaben, Ziffern und Unterstrich reduziert. Zusatzangaben lassen sich damit im selben Request mitschicken, ohne sie an die URL zu hängen:

procedure Post(oReader: TxRestReader; oWriter: TxRestWriter);
var cPfad : string;
    cName : string;
    cTyp  : string;
    cBemerk: string;
begin
    cPfad   := oReader.UploadPath();
    cName   := oReader.UploadName();
    cTyp    := oReader.UploadType();
    cBemerk := oReader.Form('bemerkung');   // Formularfeld derselben Uebertragung

    // ... Datei aus cPfad ins DMS / Zielverzeichnis uebernehmen ...

    oWriter.Str('status'   , 'ok');
    oWriter.Str('dateiname', cName);
    oWriter.Status(201);
end;

Resumable/Chunked Upload (Content-Range)

Für grosse Dateien überträgt der Client die Datei in Teilstücken (Chunks) mit dem Header Content-Range: bytes START-END/TOTAL. Der Server hängt die Chunks sequentiell an eine Session-Datei an und behandelt unvollständige Uploads selbst - das Endpunkt-Skript läuft erst beim vollständigen Upload, und dann liefern oReader.UploadPath(), UploadName() und UploadType() dasselbe wie beim einfachen Upload. Für die Teilstücke läuft es nicht.

Name und Content-Type sind im Content-Range-Protokoll nicht enthalten; der Client liefert sie deshalb im ersten Chunk über den Header Upload-Metadata (Format wie bei tus: kommagetrennte Paare schlüssel base64wert, Werte Base64-kodiert):

Upload-Metadata: filename ZmlsZS5wZGY=,filetype YXBwbGljYXRpb24vcGRm

Erkannt werden die Schlüssel filename (Pflicht) und filetype (optional). Fehlt filename im ersten Chunk, wird der Upload mit 400 abgelehnt, ohne dass eine Datei angelegt wird. Folge-Chunks und Statusabfragen müssen die Metadaten nicht erneut senden.

Ablauf (vom Client gesteuert, der Server antwortet jeweils):

Request Server-Antwort
Erster Chunk Content-Range: bytes 0-1048575/5000000 + Upload-Metadata 308 Resume Incomplete + Header Upload-Id, Upload-Offset, Range
weitere Chunks (jeweils Upload-Id mitsenden) 308 mit aktualisiertem Upload-Offset
letzter Chunk (Bereich erreicht TOTAL) normale Skript-Antwort (z.B. 200/201)
Statusabfrage Content-Range: bytes */5000000 aktueller Upload-Offset, ohne anzuhängen (Resume)
Header Richtung Bedeutung
Content-Range Request bytes START-END/TOTAL; bytes */TOTAL nur als Statusabfrage
Upload-Metadata Request tus-Metadaten im ersten Chunk: filename (Pflicht), filetype (optional), Base64-kodiert
Upload-Id Request/Response Session-Kennung. Fehlt sie im ersten Request, erzeugt der Server eine und gibt sie zurück; alle Folge-Chunks müssen sie mitsenden.
Upload-Offset Response Anzahl der bereits gespeicherten Bytes (= Startoffset des nächsten Chunks)
Range Response Bereits gespeicherter Bereich (bytes=0-N)

Der Server hängt einen Chunk nur an, wenn START dem bereits gespeicherten Stand entspricht. Bei Abweichung (doppelter Chunk, Lücke) wird nicht angehängt, sondern der aktuelle Upload-Offset zurückgemeldet - der Client setzt ab dort neu auf. Eine separate Statusabfrage ist für ein Resume daher nicht zwingend nötig.

Überschreitet ein Chunk bzw. die Gesamtgrösse das Limit (re_upload_size), antwortet der Server mit 413 Payload Too Large.

HINWEIS: Der Upload-Status liegt prozesslokal im Speicher. Nach einem Neustart des Servers muss ein unvollständiger Upload neu begonnen werden.