I am making a post request on an Arduino device with the Ethernet shield. The server is a Node.js server, and I have handled the post request server-side with the same results both with formaline and formidable. The POST is processed, but it doesn't complete the file transfer.
loadstart: {"time":1339574854222}
"bytesReceived": 178,
"filesCompleted": 0
This is the code that sends the post:
String boundary = "--73249889599006000";
String URL = "/upload";
String contentType = "text/plain";
String fileName = "text.txt";
void sendData(){
String thisFile = "This is not the contents of thisFile";
Serial.println("connecting...");
// If you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
String postHeader = "POST " + URL + " HTTP/1.1\n";
postHeader += "Content-Type: multipart/form-data; boundary=";
postHeader += boundary + "\n";
postHeader += "Host: 192.168.3.78\n";
postHeader += "User-Agent: Arduino\n";
postHeader += "Referer: http://192.168.3.78/upload\n";
String requestHead = "\n--" + boundary + "\n";
requestHead += "Content-Disposition: form-data; name=\"upload\"; filename=\"" + fileName + "\"\n";
requestHead += "Content-Type: " + contentType + "\n\n";
String tail = "\n--" + boundary + "--\n\n";
int contentLength = requestHead.length() + thisFile.length() + tail.length();
postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";
char charBuf0[postHeader.length() + 1];
postHeader.toCharArray(charBuf0, postHeader.length() + 1);
client.write(charBuf0);
char charBuf1[requestHead.length() + 1];
postHeader.toCharArray(charBuf1, requestHead.length() + 1);
client.write(charBuf1);
char charBuf2[thisFile.length() + 1];
postHeader.toCharArray(charBuf2, thisFile.length() + 1);
client.write(charBuf2);
char charBuf3[tail.length() + 1];
postHeader.toCharArray(charBuf3, tail.length() + 1);
client.write(charBuf3);
}
Line endings and a few other tweaks sorted it. Here is the updated code that works well with formaline.
String boundary = "--73249889599006000";
String URL = "/upload";
String contentType = "text/plain";
String fileName = "text.txt";
void sendData(){
String thisFile = "This is not the contents of thisFile\r\n\r\n";
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
String postHeader = "POST " + url + " HTTP/1.1\r\n";
postHeader += "Content-Type: multipart/form-data; boundary=";
postHeader += boundary + "\r\n";
postHeader += "Host: 192.168.3.18\r\n";
postHeader += "User-Agent: Arduino\r\n";
postHeader += "Referer: http://192.168.3.18/upload\r\n";
String requestHead = "--" + boundary + "\r\n";
requestHead += "Content-Disposition: form-data; name=\"upload\"; filename=\"" + fileName + "\"\r\n";
requestHead += "Content-Type: " + contentType + "\r\n\r\n";
String tail = "--" + boundary + "--\r\n\r\n";
int contentLength = requestHead.length() + thisFile.length() + tail.length();
postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";
Serial.print("Content-Length: ");
Serial.println(String(contentLength, DEC));
char charBuf0[postHeader.length() + 1];
postHeader.toCharArray(charBuf0, postHeader.length() + 1);
client.write(charBuf0);
Serial.print(charBuf0);
char charBuf1[requestHead.length() + 1];
requestHead.toCharArray(charBuf1, requestHead.length() + 1);
client.write(charBuf1);
char charBuf2[thisFile.length() + 1];
thisFile.toCharArray(charBuf2, thisFile.length() + 1);
client.write(charBuf2);
Serial.print(charBuf2);
char charBuf3[tail.length() + 1];
tail.toCharArray(charBuf3, tail.length() + 1);
client.write(charBuf3);
Serial.print(charBuf3);
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}
}
Related
I am trying to create a file in Azure File Service:
https://learn.microsoft.com/en-us/rest/api/storageservices/create-file
I've seen and read multiple threads about this issue, but I can't figure out what might be the problem in my case... Most likely I am missing some small thing in the request which I cannot find.
The error I am getting: The MAC signature found in the HTTP request (...) is not the same as any computed signature.
The signature string I've used:
PUT
\n
\n
\n
\n
text/plain // Content-Type
\n
\n
\n
\n
\n
\n
x-ms-content-length:1000
x-ms-date:Tue, 20 Apr 2021 19:23:30 GMT
x-ms-type:file
x-ms-version:2015-02-21
/account/share/test
Authorization header:
SharedKey account:XXXXXXXXXX
I've used the HMACSHA256 for hashing the authorization header and signature string, it all works when I use other endpoint (List Shares: https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares), but I can't make it work for the file. I've seen this topic AZURE File Service - Upload PDF through REST API and I believe I am using very similar request, but with no success...
I appreciate any help : )
Edit:
I am not sure if I correctly set the content headers. For example, does the x-ms-content-length should be placed in the CanonicalizedHeaders string?
Edit2:
With regard to what Ivan Yang wrote, I made the code to work, but only when my CanonicalizedHeaders are built like that:
CanonicalizedHeaders := 'x-ms-content-length:1200'
+ LF + 'x-ms-date:' + UTCDateTimeText
+ LF + 'x-ms-file-attributes:Archive' + LF + 'x-ms-file-creation-time:Now' + LF + 'x-ms-file-last-write-time:Now' + LF + 'x-ms-file-permission:Inherit'
+ LF + 'x-ms-type:file' + LF + 'x-ms-version:2019-02-02';
If I have them in different order, then it crashes:
CanonicalizedHeaders := 'x-ms-date:' + UTCDateTimeText + LF +
'x-ms-content-length:1200' + LF +
'x-ms-version:2019-02-02' + LF +
'x-ms-file-attributes:Archive' + LF +
'x-ms-file-creation-time:Now' + LF +
'x-ms-file-last-write-time:Now' + LF +
'x-ms-file-permission:Inherit' + LF +
'x-ms-type:file';
How come does this make a difference?
Your signature string is incorrect(you're missing some "\n"). I'm using the x-ms-version:2019-02-02 instead of the older one x-ms-version:2015-02-21, and the correct signature string should look like this one:
"PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
Here is the c# code using create file api:
using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
namespace ConsoleApp25
{
class Program
{
static void Main(string[] args)
{
string Account = "storage_account_name";
string Key = "storage_account_key";
string FileShare = "file_share_name";
string FileName = "test555.txt";
string apiversion = "2019-02-02";
int content_length = 1200;
string content_type = "text/plain";
DateTime dt = DateTime.UtcNow;
string StringToSign = String.Format("PUT\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ content_type + "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-content-length:" + content_length
+ "\nx-ms-date:" + dt.ToString("R")
+ "\nx-ms-file-attributes:Archive" + "\nx-ms-file-creation-time:Now" + "\nx-ms-file-last-write-time:Now" + "\nx-ms-file-permission:Inherit"
+ "\nx-ms-type:file" + "\nx-ms-version:" + apiversion + "\n" // headers
+ "/{0}/{1}/{2}", Account, FileShare, FileName);
string auth = SignThis(StringToSign, Key, Account);
string method = "PUT";
string urlPath = string.Format("https://{0}.file.core.windows.net/{1}/{2}", Account, FileShare, FileName);
Uri uri = new Uri(urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.ContentLength = 0;
request.Headers.Add("x-ms-content-length", $"{content_length}");
request.Headers.Add("Content-Type", content_type);
request.Headers.Add("x-ms-type", "file");
request.Headers.Add("x-ms-date", dt.ToString("R"));
request.Headers.Add("x-ms-version", apiversion);
request.Headers.Add("x-ms-file-attributes", "Archive"); //note it is case-sensitive.
request.Headers.Add("x-ms-file-permission", "Inherit");
request.Headers.Add("x-ms-file-creation-time", "Now");
request.Headers.Add("x-ms-file-last-write-time", "Now");
request.Headers.Add("Authorization", auth);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//read the response code
Console.WriteLine("the response is:" + response.StatusCode);
}
Console.WriteLine("**completed**");
Console.ReadLine();
}
private static String SignThis(String StringToSign, string Key, string Account)
{
String signature = string.Empty;
byte[] unicodeKey = Convert.FromBase64String(Key);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);
return authorizationHeader;
}
}
}
I am trying to create an Azure SAS to a blob. However, I am getting authentication failed error. Whatever I try, I am not able to construct a well formed stringToSign or signiture.
The error says:
"Signature did not match. String to sign used was rl 2021-03-11T08:08:46Z 2021-03-12T08:08:46Z /blob/{myAccountName}/quickstartcontainer/sampleFile2813061026464365578.txt 2020-02-10 b "
My stringToSign is :
String stringToSign= "rl\n"+
"2021-03-11T08:08:46Z" +"\n" +
"2021-03-12T08:08:46Z"+ "\n"+
"\n"+
"\n"+
"\n"+
"\n"+
2020-02-10"+
"\n"+"\n"+"\n"+"\n"+"\n";
String signature = getHMAC256(key, stringToSign);
My SAS token uri is :
String sasToken = "?sp=rl"
+ "&st=" + "2021-03-11T08:08:46Z"
+ "&se=" + "2021-03-12T08:08:46Z"
+ "&sv=" + "2020-02-10"
+ "&sr=b"
+ "&sig=" + URLEncoder.encode(signature, "UTF-8");
The encryption function is:
public static String computeHMac256(final String base64Key, final String stringToSign) {
try {
byte[] key = Base64.getDecoder().decode(base64Key);
Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
hmacSHA256.init(new SecretKeySpec(key, "HmacSHA256"));
byte[] utf8Bytes = stringToSign.getBytes(StandardCharsets.UTF_8);
return Base64.getEncoder().encodeToString(hmacSHA256.doFinal(utf8Bytes));
} catch (NoSuchAlgorithmException | InvalidKeyException ex) {
throw new RuntimeException(ex);
}
}
How can I generate a well formed signiture for my sas uri?
According to the instructions provided here, your stringToSign should conform to the following structure:
StringToSign = signedPermissions + "\n" +
signedStart + "\n" +
signedExpiry + "\n" +
canonicalizedResource + "\n" +
signedIdentifier + "\n" +
signedIP + "\n" +
signedProtocol + "\n" +
signedVersion + "\n" +
signedResource + "\n"
signedSnapshotTime + "\n" +
rscc + "\n" +
rscd + "\n" +
rsce + "\n" +
rscl + "\n" +
rsct
Which is not the same as what you're doing. Essentially you're missing canonicalizedResource and signedResource parameters.
Please form your stringToSign properly and you should not get the error you're encountering. I think it should be something like (not tested though):
String stringToSign= "rl\n"+
"2021-03-11T08:08:46Z" +"\n" +
"2021-03-12T08:08:46Z"+ "\n"+
"/blob/{myAccountName}/quickstartcontainer/sampleFile2813061026464365578.txt 2020-02-10\n"+
"\n"+
"\n"+
"\n"+
2020-02-10"+"\n"+
"b\n"+"\n"+"\n"+"\n"+"\n"+"\n";
I want to generate SAS Token, as per the Azure Doc following is the example for BLOB. I am still getting error. Can you please identify what is the mistake I am doing.
StringToSign = signedpermissions + "\n" +
signedstart + "\n" +
signedexpiry + "\n" +
canonicalizedresource + "\n" +
signedidentifier + "\n" +
signedIP + "\n" +
signedProtocol + "\n" +
signedversion + "\n" +
rscc + "\n" +
rscd + "\n" +
rsce + "\n" +
rscl + "\n" +
rsct
URL = https://myaccount.blob.core.windows.net/mycontainer/test.txt
canonicalizedresource = "/blob/myaccount/mycontainer/test.txt
I am getting following error
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:4b1d1c59-c01e-0052-0197-ffe09f000000
Time:2020-03-21T15:44:34.2757923Z</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
Following is my code
public void getSasToken() {
this.storageName = 'zaindevtesting';
this.storageContainer = 'zaindevblob';
this.storageKey = 'xxxxxxZFQ==';
this.storageUrl ='https://zaindevtesting.blob.core.windows.net';
Datetime sasExpiry = Datetime.now();
sasExpiry.addMinutes(15);
Datetime sasStart = Datetime.now();
sasStart.addMinutes(-5);
string signedpermissions = 'rwdlac';
String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedservice = 'b';
String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
string signedidentifier = '';
string signedIP = '';
string signedProtocol = 'https';
string signedversion = '2015-04-05';
string rscc='';
string rscd='';
string rsce='';
string rscl='';
string rsct='';
string stringToSign =signedpermissions + '\n' +
signedstart + '\n' +
signedexpiry + '\n' +
canonicalizedresource + '\n' +
signedidentifier + '\n' +
signedIP + '\n' +
signedProtocol + '\n' +
signedversion + '\n' +
rscc + '\n' +
rscd + '\n' +
rsce + '\n' +
rscl + '\n' +
rsct;
string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8');
string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8');
String sasToken = '';
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
sasToken = EncodingUtil.base64Encode(data);
String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;
string sasURL = 'https://zaindevtesting.blob.core.windows.net/test.txt'+sasTokenString;
System.debug('sasURL--->'+sasURL);
System.debug(sasTokenString);
// return sasToken;
}
This code generate following SAS Link
https://zaindevtesting.blob.core.windows.net/test.txt??sv=2017-11-09&st=2020-03-21T15%3A44%3A07Z&se=2020-03-21T15%3A44%3A07Z&sr=b&sp=rwdc&sig=eJVbGWI4rcyjggOYAE308ilXEA/zAsFYbuNi24IZhX4=
Please try the following code:
public void generateSASToken()
{
string storageName = 'zaindevtesting';
string storageContainer = 'zaindevblob';
string storageKey = 'xxxx==';
string storageUrl ='https://zaindevtesting.blob.core.windows.net';
Datetime sasExpiry = Datetime.now();
sasExpiry = sasExpiry.addMinutes(15);
Datetime sasStart = Datetime.now();
sasStart = sasStart.addMinutes(-5);
string signedpermissions = 'r';
String signedstart = sasStart.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedexpiry = sasExpiry.formatGMT('YYYY-MM-dd\'T\'HH:mm:ss\'Z\'');
string signedservice = 'b';
String canonicalizedresource = '/blob/zaindevtesting/zaindevblob/test.txt';
string signedidentifier = '';
string signedIP = '';
string signedProtocol = '';
string signedversion = '2015-04-05';
string rscc='';
string rscd='';
string rsce='';
string rscl='';
string rsct='';
string stringToSign =signedpermissions + '\n' +
signedstart + '\n' +
signedexpiry + '\n' +
canonicalizedresource + '\n' +
signedidentifier + '\n' +
signedIP + '\n' +
signedProtocol + '\n' +
signedversion + '\n' +
rscc + '\n' +
rscd + '\n' +
rsce + '\n' +
rscl + '\n' +
rsct;
System.debug('stringToSign--->'+stringToSign);
string signedExpiryEncode = EncodingUtil.urlEncode(signedexpiry, 'UTF-8');
string signedStartEncode = EncodingUtil.urlEncode(signedstart, 'UTF-8');
String sasToken = '';
Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
Blob data = Crypto.generateMac('HMACSHA256', Blob.valueOf(stringToSign), unicodeKey);
sasToken = EncodingUtil.base64Encode(data);
sasToken = EncodingUtil.urlEncode(sasToken, 'UTF-8');
String sasTokenString= '?sv=' + signedversion + '&se=' + signedexpiry +'&st='+signedstart+'&sr='+signedservice+'&sp=' + signedpermissions + '&sig=' + sasToken;
string sasURL = 'https://zaindevtesting.blob.core.windows.net/zaindevblob/test.txt'+sasTokenString;
System.debug('sasURL--->'+sasURL);
System.debug(sasTokenString);
// return sasToken;
}
I just tried it with your storage account key and I was able to download the blob.
Found the following issues with your code:
Permissions has to be in specific order. You're using string signedpermissions = 'rwdlac'; which is not the correct order. I just specified the read permission.
Signed Protocol was specified in stringToString but was not included in the SAS URL. I omitted that from both places.
SAS Token was not URL encoded.
You generated SAS Token for zaindevtesting.blob.core.windows.net/zaindevblob/test.txt URL but forgot to include the blob container name in the final URL.
I have a problem that arduino upload a file in sdcard to MS azure cognitive service, such as use a image file for face identify. I have try use multipart http post to upload, and it is useful for another service but not MS azure.
Does anyone have experience in using "application/octet-stream" to upload a file to Azure server?
my multipart post function show below:
void wifisendfile()
{
//connect to wifi
WiFi.begin(ssid.c_str(), pass.c_str());
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
// wait 0.5 second for connection:
delay(500);
}
Serial.print("Wifi Connected,IP address: ");
Serial.println(WiFi.localIP());
//prepare httpclient
Serial.println("Starting connection to server...");
Serial.println(host);
WiFiClient client;
//start http sending
if (client.connect(host.c_str(), 80))
{
//open file
myFile = SD.open("/pic.jpg");
int filesize=myFile.size();
Serial.print("filesize=");
Serial.println(filesize);
String fileName = myFile.name();
String fileSize = String(myFile.size());
Serial.println("reading file");
if (myFile)
{
String boundary = "CustomizBoundarye----";
String contentType = "image/jpeg";
// post header
String postHeader = "POST " + url + " HTTP/1.1\r\n";
postHeader += "Host: " + host + ":80 \r\n";
postHeader += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n";
postHeader += "Accept-Charset: utf-8;\r\n";
String keyHeader = "--" + boundary + "\r\n";
keyHeader += "Content-Disposition: form-data; name=\"key\"\r\n\r\n";
String requestHead = "--" + boundary + "\r\n";
requestHead += "Content-Disposition: form-data; name=\"\"; filename=\"" + fileName + "\"\r\n";
requestHead += "Content-Type: " + contentType + "\r\n\r\n";
// post tail
String tail = "\r\n--" + boundary + "--\r\n\r\n";
// content length
int contentLength = keyHeader.length() + requestHead.length() + myFile.size() + tail.length();
postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";
// send post header
char charBuf0[postHeader.length() + 1];
postHeader.toCharArray(charBuf0, postHeader.length() + 1);
client.write(charBuf0);
//Serial.print("send post header=");
//Serial.println(charBuf0);
// send key header
char charBufKey[keyHeader.length() + 1];
keyHeader.toCharArray(charBufKey, keyHeader.length() + 1);
client.write(charBufKey);
//Serial.print("send key header=");
//Serial.println(charBufKey);
// send request buffer
char charBuf1[requestHead.length() + 1];
requestHead.toCharArray(charBuf1, requestHead.length() + 1);
client.write(charBuf1);
//Serial.print("send request buffer=");
//Serial.println(charBuf1);
// create buffer
const int bufSize = 2048;
byte clientBuf[bufSize];
int clientCount = 0;
// read myFile until there's nothing else in it:
while (myFile.available())
{
clientBuf[clientCount] = myFile.read();
clientCount++;
if (clientCount > (bufSize - 1))
{
client.write((const uint8_t *)clientBuf, bufSize);
clientCount = 0;
}
}
if (clientCount > 0)
{
client.write((const uint8_t *)clientBuf, clientCount);
//Serial.println("Sent LAST buffer");
}
// send tail
char charBuf3[tail.length() + 1];
tail.toCharArray(charBuf3, tail.length() + 1);
client.write(charBuf3);
//Serial.print(charBuf3);
}
Serial.println("end_request");
}
String lastline;
while(client.connected())
{
while(client.available())
{
String line = client.readStringUntil('\r');
lastline=line;
//Serial.print(line);
if(line.indexOf("{")>0)
{
client.stop();
}
}
}
Serial.println(lastline);
myFile.close();
Serial.println("closing connection");
}
After many days trying, I use sniffer to scan the package data in network. I found any data must be send by https to Azure Service. So that any file upload failed. After using HTTPS, files upload fine and get response from azure server.
While I am uplodaing multiple images in j2me to servlet, I am able to get first image in servlet but not able get second image. is something wrong in my code? could you please suggest
This is my code.
// For First Image uploading
String message1 = "";
message1 += "-----------------------------4664151417711" + CrLf;
message1 += "Content-Disposition: form-data; name=\"image1\"; filename=\"" + FILE1 + "\"" + CrLf;
message1 += "Content-Type: image/jpeg" + CrLf;
message1 += CrLf;
// the image is sent between the messages ni the multipart message.
String message2 = "";
message2 += CrLf + "-----------------------------4664151417711--" + CrLf;
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------4664151417711");
// might not need to specify the content-length when sending chunked data.
// conn.setRequestProperty("Content-Length", String.valueOf((message1.length() + message2.length() + imgData.length)));
System.out.println("open os");
os = conn.openOutputStream();
System.out.println(message1);
os.write(message1.getBytes());
// SEND THE IMAGE
int index = 0;
int size = 1024;
do{
System.out.println("write:" + index);
if((index+size)>imgData1.length){
size = imgData1.length - index;
}
os.write(imgData1, index, size);
index+=size;
progress(imgData1.length, index); // update the progress bar.
}while(index<imgData1.length);
// For Second Image uploading
message1 = "";
message1 += "-----------------------------4664151417711" + CrLf;
message1 += "Content-Disposition: form-data; name=\"image2\"; filename=\"" + FILE2 + "\"" + CrLf;
message1 += "Content-Type: image/jpeg" + CrLf;
message1 += CrLf;
// the image is sent between the messages ni the multipart message.
message2 = "";
message2 += CrLf + "-----------------------------4664151417711--" + CrLf;
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------4664151417711");
// might not need to specify the content-length when sending chunked data.
// conn.setRequestProperty("Content-Length", String.valueOf((message1.length() + message2.length() + imgData.length)));
System.out.println(message1);
os.write(message1.getBytes());
// SEND THE IMAGE
int index = 0;
int size = 1024;
do{
System.out.println("write:" + index);
if((index+size)>imgData2.length){
size = imgData2.length - index;
}
os.write(imgData2, index, size);
index+=size;
progress(imgData2.length, index); // update the progress bar.
}while(index<imgData2.length);
Its working fine If I modify the code as below
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------4664151417711");
os = conn.openOutputStream();
os.write(message1.getBytes());
// For First Image uploading
String message1 = "";
message1 += "-----------------------------4664151417711" + CrLf; message1 += "Content-Disposition: form-data; name=\"image1\"; filename=\"" + FILE1 + "\"" + CrLf; message1 += "Content-Type: image/jpeg" + CrLf; message1 += CrLf;
os.write(message1.getBytes());
// SEND THE IMAGE
int index = 0;
int size = 1024;
do{
System.out.println("write:" + index);
if((index+size)>imgData1.length){
size = imgData1.length - index;
}
os.write(imgData1, index, size);
index+=size;
progress(imgData1.length, index); // update the progress bar.
}while(index<imgData1.length);
// For Second Image uploading
String message2 = "";
message2 += "-----------------------------4664151417711" + CrLf;
message2 += "Content-Disposition: form-data; name=\"image2\"; filename=\"" + FILE2 + "\"" + CrLf;
message2 += "Content-Type: image/jpeg" + CrLf; message1 += CrLf;
os.write(message2.getBytes());
// SEND THE IMAGE
//int index = 0;
int size = 1024;
do{
System.out.println("write:" + index);
if((index+size)>imgData2.length){
size = imgData2.length - index;
}
os.write(imgData2, index, size);
index+=size;
progress(imgData2.length, index); // update the progress bar.
}while(index<imgData2.length);
String message3 = "\r\n-----------------------------4664151417711--\r\n";
os.write(message3.getBytes());