Datei mit Anhang via http "hochladen"

HarryR

Mitglied
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:
Java:
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
 
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
 
Der HTTP-Statuscode 401 Unauthorized gibt an, dass der Server die Anfrage aufgrund fehlender oder ungültiger Authentifizierung abgelehnt hat.
 
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
 
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.
 
@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:
Ohne den Code zu sehen kann man schlecht sagen, wo der Fehler im Code ist 🙂
 
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]
 

Zurück
Oben