# Datei mit Anhang via http "hochladen"



## HarryR (26. Nov 2021)

Hallo,

ich möchte eine Datei auf einen Webserver hochladen.
Vom "Hersteller" der Webseite gab es ein curl-Beispielscript, das leidlich funktioniert.
Ich programmiere meine Anwendung aber in Java (sonst wäre ich nicht hier, oder 
Meine bisherigen Versuche in Jav enden immer in einem 401-Fehler.

Vielleicht könnt ihr mir helfen !?
Zuerst mal ein paar Infos zum Programierstand in Java:

[CODE lang="java" title="Imports"]import org.apache.http.Header;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;

import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;[/CODE]

Ich zeige auch gerne Abschnitte des Codes, aber .. der ist relativ kompliziert, daher vesrschone ich euch erst mal damit

und zeige euch lieber mal das was ich via wireshark an Infos habe.
Das erklärt das Problem vielleicht auch besser.

[CODE lang="html" title="python-Client (funktionierend)"]Hypertext Transfer Protocol
    PUT /api/sensor/upgrade?usr=XXXX&passwd=YYYYY HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): PUT /api/some/call?usr=XXXXn&passwd=YYYY HTTP/1.1\r\n]
            [PUT /api/some/call?usr=XXXX&passwd=YYYY HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: PUT
        Request URI: /api/some/call?usr=XXXX&passwd=YYYY
            Request URI Path: /api/some/call
            Request URI Query: usr=XXX&passwd=YYY
                Request URI Query Parameter: usr=XXX
                Request URI Query Parameter: passwd=YYYY
        Request Version: HTTP/1.1
    Host: 10.130.31.25\r\n
    User-Agent: curl/7.58.0\r\n
    Accept: */*\r\n
    Content-Length: 21597945\r\n
        [Content length: 21597945]
    Expect: 100-continue\r\n
    \r\n
    [Full request URI: http://10.130.31.25/api/some/call?usr=XXX&passwd=YYYY]
    [HTTP request 1/1]
    [Response in frame: 16970]
    File Data: 21597945 bytes
    Data (21597945 bytes)
        Data: 504b03040a00000800005545894eb2d6ae87b7020000b702...
        [Length: 21597945]
[/CODE]

Der Aufruf dazu ist:

```
curl --no-proxy ""  -ss  -T DATEI "http://IP/api/some/call?$usr=XXX&passwd=YYYY"
```

So sollte es dann auch aussehen, wenn ich es mit den obigen imports und dem "richtigen" Java-Code 
hinbekomme.

Das komische ist. Wenn ich meine Java-Versuche mit wireshark mitsniffe gibt es noch nicht einmal 
ein http in der Protokoll-Spalte .. das wird nur als TCP "dekodiert" ..
Irgendetwas mache ich falsch.

Vielen Dank und Grüße
bleibt gesund
Harry


----------



## mrBrown (26. Nov 2021)

Ohne den Code zu sehen kann man schlecht sagen, wo der Fehler im Code ist


----------



## HarryR (26. Nov 2021)

mrBrown hat gesagt.:


> Ohne den Code zu sehen kann man schlecht sagen, wo der Fehler im Code ist


Da hast du recht, aber der Code ist so aufwendig (hmm, vielleicht das falsche Wort), bis ich den auf
das gekürzt habe was interessant wäre ..

Ich hoffe eher auf ein kleines "Tutorial" mit ein paar Zeilen Code wie "ihr" es machen würdet.

Grüßle Harry


----------



## mrBrown (26. Nov 2021)

HarryR hat gesagt.:


> Da hast du recht, aber der Code ist so aufwendig (hmm, vielleicht das falsche Wort), bis ich den auf
> das gekürzt habe was interessant wäre ..


In deinem ersten Beitrag stehen nur imports?


----------



## Oneixee5 (26. Nov 2021)

Der HTTP-Statuscode 401 Unauthorized gibt an, dass der Server die Anfrage aufgrund fehlender oder ungültiger Authentifizierung abgelehnt hat.


----------



## HarryR (26. Nov 2021)

mrBrown hat gesagt.:


> In deinem ersten Beitrag stehen nur imports?


Ja, damit wollte ich "anzeigen" mit welchen Frameworks/Bibliotheken/Jars ich arbeite.

Für heute ist erst mal Schluss, wenn es notwendig ist extrahiere ich mal den Code und schicke ihn.
Viele Grüße


----------



## HarryR (26. Nov 2021)

Oneixee5 hat gesagt.:


> Der HTTP-Statuscode 401 Unauthorized gibt an, dass der Server die Anfrage aufgrund fehlender oder ungültiger Authentifizierung abgelehnt hat.


Stimmt, aber irgendwie auch nicht, ich glaube das ist eine Fakeantwort des Servers, weil er mit etwas anderem nicht zufrieden ist.
Ist kein normaler Webserver von der Stange (zb kein apache).
Die Authentifizierung bekommt schon den richtigen User/Pw, es wird sogar die Datei gesendet, aber halt nicht so, wie der Webserver es gerne hätte. Das Problem ist irgendwie, dass der binäre Inhalt NICHT als MultiPart gesendet werden soll (das geht schief) , sondern als ich nenne es mal "SinglePart". Auch nicht als FormData. Daher habe ich ja den curl-Ausschnitt gezeigt, ich dachte da erkennt man (ihr), was zu tun ist, damit genau dieses Format auch von Java (bzw den Bibliotheken) erzeugt wird. Ich zitiere mal aus der Spezifikation des Herstellers (gekürzt):

[CODE lang="java" title="Spezifikation"]upgrade Sends an upgrade / plugin .....  Checks file-extension before returning.  Protokoll: PUT     Auth: ADMIN/passwd[/CODE]

Das ist leider nicht viel Info, dazu gab es noch das Beispielscript (curl .. siehe oben).

Viele Grüße


----------



## Oneixee5 (26. Nov 2021)

HarryR hat gesagt.:


> ich glaube das ist eine Fakeantwort


In der Softwareentwicklung etwas zu glauben ist Irrsinn! Es ist wichtig zu wissen was los ist. Softwareentwicklung ist ja keine Kirche.
Offensichtlich versuchst du auch Username und Passwort als Parameter in der URL mitzuschicken - für jeden lesbar!?


----------



## HarryR (26. Nov 2021)

Oneixee5 hat gesagt.:


> In der Softwareentwicklung etwas zu glauben ist Irrsinn! Es ist wichtig zu wissen was los ist. Softwareentwicklung ist ja keine Kirche.
> Offensichtlich versuchst du auch Username und Passwort als Parameter in der URL mitzuschicken - für jeden lesbar!?


Das ist eine Antwort die mich wirklich weiter bringt ... 
hilft es dir, wenn ich glauben durch vermuten ersetze ?
Ich habe diese API nicht entwickelt ich muss nur mit ihr arbeiten.


----------



## mihe7 (27. Nov 2021)

@HarryR, Dein erster Post lässt sich zusammenfassen als: "Ich verwende den Apache HTTP Client, hier ein paar Infos wie der Datenstrom im funktionierenden Python-Programm aussieht, wo liegt der Fehler in meinem Java-Code?"

Versteh mich nicht falsch, die gegebenen Infos können durchaus nützlich sein, nur fehlt das Wesentliche:


mrBrown hat gesagt.:


> Ohne den Code zu sehen kann man schlecht sagen, wo der Fehler im Code ist


----------



## HarryR (29. Nov 2021)

So, ich habe mal den Code aus einer längeren "generalistischen" Methode extrahiert (Die Methode macht wesentlich mehr, aber das ist hier nicht von Belang).

[CODE lang="java" title="Stripped Code"]RequestConfig rConfig = RequestConfig.custom()
  .setConnectTimeout(TIMEOUT_CONNECT * MILLISECS)
  .setConnectionRequestTimeout(TIMEOUT_REQUEST * MILLISECS)
  .setSocketTimeout(TIMEOUT_SOCKET * 1000).build();

   HttpRequestBase method = null;;
   CloseableHttpClient client =  HttpClientBuilder.create().setDefaultRequestConfig(rConfig).build();

   method = new HttpPut(urlStr);break;
   method.setHeader("Accept-Encoding","*/*");
   method.setHeader("Content-Type","application/zip");
   // in byteArrayList.getFileInByte().get(bIdx).getFileInByte() befindet sichdie bereits eingelesene Datei
   entity = new ByteArrayEntity(byteArrayList.getFileInByte().get(bIdx).getFileInByte());
   CloseableHttpResponse response = null;
   try
   {
     response = client.execute(method);
     response.close();
     client.close();
    }[/CODE]


----------



## mihe7 (29. Nov 2021)

Was soll in Zeile 9 das break?


----------



## mrBrown (29. Nov 2021)

Wo übergibst du denn User und Password? Wenn es einen 401 gibt ist das relevant…


----------



## HarryR (29. Nov 2021)

mihe7 hat gesagt.:


> Was soll in Zeile 9 das break?


Das ist ein Relikt, bitte ignorieren


----------



## HarryR (29. Nov 2021)

mrBrown hat gesagt.:


> Wo übergibst du denn User und Password? Wenn es einen 401 gibt ist das relevant…


Ist in der Url bereits drinnen


----------



## mrBrown (29. Nov 2021)

HarryR hat gesagt.:


> Ist in der Url bereits drinnen


Ich würde dort den Fehler vermuten


----------



## HarryR (8. Dez 2021)

So, das Problem hat sich auf einen Fehler in der API reduziert.


----------

