I am using android okhttp to send multipart data i.e image and text to wcf service. I am able to send and parse partial data at the server using a custom MultipartParser class as mentioned here.
When my file gets written to the server it gets corrupted due to some unwanted chars from the Multipart data gets written with bytes[I found this out by opening the image in notepad++ which showed encoded bytes and unwanted chars]. I am able to remove those by adding the regex matcher for contentLenMatch but still a newline is being written at the start of the file, hence showing it as corrupted.
I need to know how to remove the blank spaces or \n from the data before writing it to a file.
Code :
public class MultipartParser {
public IDictionary<string, string> Parameters = new Dictionary<string, string>();
public MultipartParser(Stream stream) {
this.Parse(stream, Encoding.UTF8);
}
public MultipartParser(Stream stream, Encoding encoding) {
this.Parse(stream, encoding);
}
public string getcontent(Stream stream, Encoding encoding) {
byte[] data = ToByteArray(stream);
string content = encoding.GetString(data);
string delimiter = content.Substring(0, content.IndexOf("\r\n"));
string[] sections = content.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in sections) {
Match nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
string name = nameMatch.Value.Trim().ToLower();
if (!string.IsNullOrWhiteSpace(name)) {
int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;
}
string strRet = ""; //Parameters["name"];
return strRet;
}
private void Parse(Stream stream, Encoding encoding) {
this.Success = false;
byte[] data = ToByteArray(stream);
string content = encoding.GetString(data);
int delimiterEndIndex = content.IndexOf("\r\n");
if (delimiterEndIndex > -1) {
string delimiter = content.Substring(0, content.IndexOf("\r\n"));
Regex re = new Regex(@"(?<=Content\-Type:)(.*?)");
Match contentTypeMatch = re.Match(content);
re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
Match filenameMatch = re.Match(content);
// to match Content-Length and remove ***Unwanted chars***
re = new Regex(@"(?<=Content\-Length:)(.*)");
Match contentLenMatch = re.Match(content);
if(contentLenMatch.Success){
contentLenMatch = contentLenMatch.NextMatch();
}
if (contentTypeMatch.Success && filenameMatch.Success) {
this.ContentType = contentTypeMatch.Value.Trim();
this.Filename = filenameMatch.Value.Trim();
// changed from contentTypeMatch to contentLenMatch
// startIndex must point to the 1st byte
// from where the file needs to be written
// Need to remove extra \n that gets written to the file
int startIndex = contentLenMatch.Index + contentLenMatch .Length + "\r\n\r\n".Length;
byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
int endIndex = IndexOf(data, delimiterBytes, startIndex);
int contentLength = endIndex - startIndex;
byte[] fileData = new byte[contentLength];
Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
this.FileContents = fileData;
this.Success = true; }
} }
private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex) {
int index = 0;
int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
if (startPos != -1) {
while ((startPos + index) < searchWithin.Length) {
if (searchWithin[startPos + index] == serachFor[index]) {
index++;
if (index == serachFor.Length) {
return startPos;
}
} else {
startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
if (startPos == -1) {
return -1;
}
index = 0;
}
}
}
return -1;
}
private byte[] ToByteArray(Stream stream) {
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream()) {
while (true) {
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public bool Success {
get;
private set;
}
public string ContentType {
get;
private set;
}
public string Filename {
get;
private set;
}
public byte[] FileContents {
get;
private set;
}
public string Imgname {
get;
private set;
}