Webserver nanoHttpd upload nicht möglich

  • 14 Antworten
  • Letztes Antwortdatum
E

eminwargo

Neues Mitglied
0
Hallo,

ich habe es geschafft einen Webserver auf Android zu starten. Der Server ist auch mit dem Rechner per IP und Port erreichbar.

Wenn ich jetzt eine Datei hochladen möchte tut sich nichts... Ich weiß nicht ob die Datei in einem temp Ordner landet oder sonst wie verschwindet habe nichts gefunden.

Ich habe eig. alle nötigen Permissions gesetzt, Speicherkarte Lesen und Schreiben und Internet Berechtigungen.

Code:
        public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
            uri = "<html><body><form name='up' method='post' enctype='multipart/form-data'>"
                    + "<input type='file' name='file' /><br /><input type='submit'name='submit' value='Upload'/></form></body></html>";
            return new Response(uri);
        }

Ist es irgendwie möglich eine index.html datei zu starten oder die uploads zu speichern?

Ich habe noch einen anderen html code welche an php gebunden ist aber ich weiß nicht wie ich das in android einbinden soll...
 
Ich versteh gerade nicht was du da machst.

Sieht für mich so aus, dass du in deinem Code nur das Formular raus sendest.

Wo wird denn der Upload verarbeitet?
Von alleine passiert das nicht.

Und warum überschreist du uri mit dem HTML Inhalt o_O
Und was ist Response für eine Klasse?
Die Standard Java Klasse hat keinen Constructor der einen String annimt, wenn ich mich nicht vertue.
 
Das ist meine Klasse:
Code:
public class MainActivity extends Activity {

    private static final int PORT = 8080;
    private MyHTTPD server;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onResume() {
        super.onResume();

        try {
            server = new MyHTTPD();
            server.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class MyHTTPD extends NanoHTTPD {

        public MyHTTPD() throws IOException {
            super(PORT);
        }

        public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
            uri = "<html><head><title>Dateiupload</title></head><body><p><font face=\"Arial, Helvetica, sans-serif\" size=\"6\">Dateiupload via HTML </font></p>"
                    + "<form method=\"post\" action=\"upload.php\" enctype=\"multipart/form-data\">Datei:<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\"><input type=\"file\" name=\"datei\" "
                    + "size=\"40\" maxlength=\"100000\"><input type=\"submit\" name=\"Submit\" value=\"Senden\"></form></body></html>";
            return new Response(Response.Status.OK, MIME_HTML, uri);
        }
    }
}

Zumindest kann ich so die HTML-Page sehen?!

Ich habe noch eine upload.php Datei, ich glaube die ist nicht mit Android kompatibel. Auf einem Appache Server funktioniert der Upload in Kombination mit der index.html und der upload.php Datei.
Wird denn nicht der Upload automatisch gemacht?
 
Zuletzt bearbeitet:
Nein, da wird gar nichts automatisch gemacht.
Gerade nanoHTTP hat so gut wie keine eingebauten Features in dem Sinne.

Wenn ich das richtig verstehe wird die serve methode IMMER aufgerufen, wenn du die Seite aufrufst.

Hier müsstest du dann unterscheinde ob du ein normalen get request hast oder ein POST request.

Wenn du auf Upload klickst kommst du wieder in die die gleiche Methode, die bei dir aber nichts anderes macht, als wieder die uri (WARUM?) zu überschreiben und als normalen Response zurück zu geben.

Du musst da alles selbst per Hand machen.
Dazu musst du dich in HTTP einlesen.

Wenn du ein Upload machst sollte die Datei in der files Map sein.
Wenn ich den SourceCode richtig verstehe (hab den aber jetzt nur überflogen)

Musste dann nur noch speichern.
 
Das ist richtig die serve Methode wird eig. Immer aufgerufen.

Ich habe in der Uri method=post angegeben.
Wie soll das denn aussehen muss das denn nicht alles in der serve Methode stehen?
 
Ich verstehe das Protokoll da nicht so ganz:
Zum Datei-Upload nimmt man doch HTTP PUT requests, nicht HTTP POST?!
Sonst überträgst du bestenfalls den Dateinamen.
(Oder hab ich da jetzt was missverstanden?)

ADD: okay, ich habe was missverstansden, POST sollte eigentlich gehen
 
Zuletzt bearbeitet:
DU könntest dir 2 methoden bauen die eine nennst du get die andere post z.B.
In der serve() Methode machst du dann nur noch:

if (method.quals(Method.GET)) {
return get(.....)
} else {
return post(.....)
}

post() und get() bekommen einfach die gleichen Parameter wie die serve Methode.
Und geben auch ein Response Objekt zurück.

Da drin kannste dann übersichtlicher weiterarbeiten.

@DieGoldeneMitte
Jein.
POST daten können auch Dateien beinhalten.

POST schickt die Daten an eine vorhandene Resource, die diese dann verarbeitet.
PUT hingegen erstellt oder aktualisiert eine (vorhandene) Resource.

PUT wird aber sehr selten benutzt.
bei REST services kann das mehr Sinn machen.
Sagen wir dein RESTService hat Json objekte.
Mit PUT könnte man jetzt einfach ein neus unter einer bestimmten URI anlegen.
/animals/dog

Wenn dein Server lieber entscheiden soll wohin mit dem Hund dann lieber per POST an
/animaldistributor

Hier wäre dein Json Object nur mitgesendet an den Service und dieser entscheidet was er damit macht.
er legt es evtl auch unter animals/dog ab evtl aber auch unter /animals/shelter/dog

Deswegen sind die weitaus meisten Formulare auch POST Forms.
Da dort dann beispielsweise eine php datei liegt, die entscheidet was mit den Daten passiert.
 
Zuletzt bearbeitet:
Danke erst einmal für die nützlichen Antworten:thumbsup:.

Die Unterscheidung zwischen POST und GET habe ich eingebunden.
Aber was soll ich am HTML Code ändern und brauche ich für den upload eine PHP Datei?

Der veränderte Code (Inner Class):
Code:
    private class MyHTTPD extends NanoHTTPD {               

        public MyHTTPD() throws IOException {
            super(PORT);
        }

        public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
            if (method.equals(Method.GET)) {
                return get(uri, method, headers, parms, files);
            }
            return post(uri, method, headers, parms, files);
        }

        public Response get(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
            String get = "<html><body><form name='up' method='post' enctype='multipart/form-data'>"
                    + "<input type='file' name='file' /><br /><input type='submit'name='submit' "
                    + "value='Upload'/></form></body></html>";
            return new Response(get);
        }

        public Response post(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
            String post = "<html><body><form name='up' method='post' enctype='multipart/form-data'>"
                    + "<input type='file' name='file' /><br /><input type='submit'name='submit' "
                    + "value='Upload'/></form></body></html>";
            return new Response(post);
        }
    }
 
DU brauchst keine PHP Datei.
Im Moment machst du in beiden Methoden ja das gleiche.

Du musst in der Post Methode halt die Dateien auswerten, die vermutlich in der files Map stehen.

Guck doch mal ob da was drin steht, wenn du dein Formular abschickst.
Ansonsten fehlt dir meiner Meinung nach die Grundlage in HTTP dafür, dass du hier quasi deinen eigenen Server schreiben willst.

Die Doku zu dem nanoHTTPD ist leider etwas dünn.
Aber im Prinzip kannst du dein String post auf eine Antwort verkürzen die in etwas heißen sollte "<html><body>Upload erfolgreich</body></html>".

Du musst halt vorher die Datei aus der files Map auslesen.
Wie genau die da drin ist (und ob sie überhaupt da drin ist) kann ich dir aber nicht sagen.
 
Habe es nun geschafft die hochgeladenen Dateien zu lesen....
Aber man könnte jetzt auf der Html page alles mögliche an Dateitypen hochladen könnte ich das irgendwie festlegen welche Dateien hochgeladen werden können ?
 
Jein, entweder prüfst du das schon auf der html seite mit javascript ab.
oder aber erst wenn du den datei namen hast.
Aber: der Dateiname kann beliebig verändert werden, wenn du sicher gehen willst musst du die Datei zumindest teilweise einlesen soweit, bis du weißt was für eine Datei das ist.

Und dann wenns eine erlaubte ist weiter machen, wenn nicht abbrechen und eine Fehlermeldung ausgeben.

Aber die Details musst du dir selber ausdenken und umsetzen, da ich nicht weiß welche dateien du erlauben willst und auf anhieb weiß ich auch nicht ab wann man die erkennt.
Musst du dich mal durch googlen
 
Die hochgeladene Datei wird nicht richtig eingelesen.
Könnte es an meiner Variante des InputStream oder OutputStream liegen ?

Code:
public void createFile(File in, File out) throws FileNotFoundException, IOException {
            // in Pfad zur Temp Datei in /data/data/...
            // out Ausgabedatei auf der Speicherkarte
            InputStream inputStream = null;
            OutputStream outputStream = null;

            
            inputStream = new FileInputStream(in);

            
            outputStream =
                    new FileOutputStream(out);

            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            inputStream.close();
            outputStream.close();
        }

Eingabedatei:

Code:
XXXXXXXXXXX      111

XXXXXX 222

XXXXX 333


XXXXXX 4444

XXXXXX  5555 


XXXXX 6666

Ausgabedatei:

Code:
------WebKitFormBoundaryWKyCPgZELpqDeBdc
Content-Disposition: form-data; name="file"; filename="text.rtf"
Content-Type: text/rtf

{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural

\f0\fs24 \cf0 XXXXXXXXXXX      111\
\
XXXXXX 222\
\
XXXXX 333\
\
\
XXXXXX 4444\
\
XXXXXX  5555 \
\
\
XXXXX 6666}
------WebKitFormBoundaryWKyCPgZELpqDeBdc
Content-Disposition: form-data; name="submit"

Upload
------WebKitFormBoundaryWKyCPgZELpqDeBdc--
 
Was ist das denn für eine Datei?
Das sieht mir alles richtig aus.
Das ist eine RTF datei, die hat solche Formatierungen mit drin.

Wenn du die original Datei z.B. mit WordPad unter Windows anguckst siehst du die halt nicht.

Scheint mir alles richtig zu sein was da steht.
Wo siehst du dir denn den Inhalt der original Datei an?
 
Hab sie mit dem Mac erstellt...
Da stehen ja aber noch mehr Informationen drinne... Die auch im Source Code von NanoHttpd stehen Beispiel:
Content-Disposition:
Content-Type:

Die stehen alle in dieser Methode von Nanohttpd
decodeMultipartData()

Vllt wäre auch diese Methode die richtige aber ich kann mit den Parametern einfach nichts anfangen:

saveTmpFile()
 
Wie baust du dir denn das File Objekt zusammen?
Also was ist bei dir das Object File in?
 
Zurück
Oben Unten