I'm using VS 2010 (C#). I'm trying to encrypt (decrypt) a file as it is being uploaded (downloaded) from an FTP site. I thought this would be quicker than using a local temp file to encrypt before upload and decrypt after download. I get an error on the code below. I just can't seem to get the various stream types in alignment (i.e. FileStream, CryptoStream, and Stream). Any help is much appreciated.
public void Upload(byte[] desKey, byte[] desIV)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(UserName, Password);
FileStream fStream = File.Open(SourceFile, FileMode.OpenOrCreate);
CryptoStream responseStream = new CryptoStream(fStream, new DESCryptoServiceProvider().CreateDecryptor(desKey, desIV), CryptoStreamMode.Read);
byte[] fileContents = Encoding.UTF8.GetBytes(responseStream.ToString());
responseStream.Close(); ///ERROR here
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
Unit Test:
public void CleanEncryptUploadTest()
{
FT.ftp uploadTest = new FT.ftp();
uploadTest.UserName = "ausername";
uploadTest.Password = "apassword";
uploadTest.SourceFile = "D:\\Temp\\Test\\file.txt";
uploadTest.Destination = "ftp://ftp.mysite.com/test2.txt";
byte[] key = ASCIIEncoding.ASCII.GetBytes("TestZone");
byte[] initVector = ASCIIEncoding.ASCII.GetBytes("TestZone");
uploadTest.Upload(key, initVector);
}
This worked for me, I used a memory stream and wrote the encrypted bytes to it instead. Also changed the cryptostream mode to write.
public void Upload(byte[] key, byte[] iv)
{
byte[] fileContents;
using (FileStream inputeFile = new FileStream(this.SourceFile, FileMode.Open, FileAccess.Read))
{
using (MemoryStream encryptedStream = new MemoryStream())
{
using (CryptoStream cryptostream = new CryptoStream(encryptedStream, new DESCryptoServiceProvider().CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
byte[] bytearrayinput = new byte[inputeFile.Length];
inputeFile.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
fileContents = encryptedStream.ToArray();
}
}
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(this.UserName, this.Password);
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
Related
I am using HttpWebRequest.GetStreamData() to get data from stream and then writing a couple of files in that variable.
Before calling the GetResponse() method on the stream, I need to get the copy of data and put it in text format.
Here's my code snippet
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.Method = "POST";
string requestbody = "Some Body Text"
Stream rs = wr.GetRequestStream();
foreach (fragment in Documents).ToList())
{
byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes(requestbody);
rs.Write(requestBytes, 0, requestBytes.Length);
FileStream fileStream = new FileStream(fragment.FilePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Flush();
fileStream.Close();
fileStream = null;
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("Trailer Text");
rs.Write(trailer, 0, trailer.Length);
}
}
using (StreamReader strm = new StreamReader(rs))
{
string text = strm.ReadToEnd();
}
rs.Close();
rs = null;
The issue is I get error "stream was not readable".
When I check the property rs.canread, it is set to false.
Can anyone help me reading the content of my rs stream.
I have tried a couple of methods but none seems to be working as of now.
I am calling a third party service, which return a pdf file by IO.Stream. I need to change to MemoryStream, and save to a pdf file.
cRequestString = ".....";//You need to set up you own URL here.
//Make the API call
try
{
byte[] bHeaderBytes = System.Text.Encoding.UTF8.GetBytes(GetUserPasswordString()); //user and pa for third party call.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(cRequestString);
request.Method = WebRequestMethods.Http.Get;
request.PreAuthenticate = true;
request.ContentType = "application/pdf";
request.Accept = "application/pdf";
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bHeaderBytes));
MemoryStream memStream;
WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
memStream = new MemoryStream();
//read small blocks to show correctly
byte[] buffer = new Byte[1023];
int byteCount;
do
{
byteCount = stream.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
memStream.Seek(0, SeekOrigin.Begin);//set position to beginning
return memStream;
}
catch
{
return null;
}
//save MemoryStream to local pdf file
private void SavePDFFile(string cReportName, MemoryStream pdfStream)
{
//Check file exists, delete
if (File.Exists(cReportName))
{
File.Delete(cReportName);
}
using (FileStream file = new FileStream(cReportName, FileMode.Create, FileAccess.Write))
{
byte[] bytes = new byte[pdfStream.Length];
pdfStream.Read(bytes, 0, (int)pdfStream.Length);
file.Write(bytes, 0, bytes.Length);
pdfStream.Close();
}
}
You could do the following.
using (Stream stream = response.GetResponseStream())
using(MemoryStream memStream = new MemoryStream())
{
memStream = new MemoryStream();
stream.CopyTo(memoryStream);
// TODO : Rest of your task
}
More details on Stream.CopyTo on MSDN
I am trying to create an XML file from an object and save it to an FTP. My code successfully creates the file in the FTP, but the file just says NULL. PORequest is my object. Here is a screenshot:
Here is my code:
static void FTPXmlFile(PORequest req, string fileNameToCreate, string ftpUrl, string ftpPassword, string ftpUserName)
{
MemoryStream memoryStream = SerializeToStream(req);
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl + fileNameToCreate);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.UseBinary = false;
byte[] buffer = new byte[memoryStream.Length];
memoryStream.Read(buffer, 0, buffer.Length);
memoryStream.Close();
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(buffer, 0, buffer.Length);
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
static MemoryStream SerializeToStream(object o)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
return stream;
}
Update:
Here is the code that worked:
static MemoryStream GetMemoryStream(object req)
{
XmlSerializer xmlSerializer = new XmlSerializer(req.GetType());
string s = null;
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, req);
s = textWriter.ToString();
}
MemoryStream memoryStream = new MemoryStream();
StreamWriter writer = new StreamWriter(memoryStream);
writer.Write(s);
writer.Flush();
memoryStream.Position = 0;
return memoryStream;
}
I have an XML data which I would like to compress it using GZipStream and upload it to webservice. I would like to create the gzip file in memory instead of of creating it in local disk. I have tried the following:
public string class1(string url, string xml)
{
byte[] data = Encoding.ASCII.GetBytes(xml);
MemoryStream memory = new MemoryStream();
GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
byte[] zip=memory.ToArray();
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(url);
wReq.Method = "POST";
wReq.ContentType = "application/zip";
var reqStream = wReq.GetRequestStream();
reqStream.Write(zip,0,zip.Length);
reqStream.Close();
var wRes = wReq.GetResponse();
var resStream = wRes.GetResponseStream();
var resgzip = new GZipStream(resStream, CompressionMode.Decompress);
var reader = new StreamReader(resgzip);
var textResponse = reader.ReadToEnd();
reader.Close();
resStream.Close();
wRes.Close();
return textResponse;
}
After writing data to webservice the server unzips the file and processess it. While the server decompresses the data an exception is thrown in server "Premature end of file". Please help me in this.
Add below method to convert Stream to MemoryStream
public static MemoryStream Read(Stream stream)
{
MemoryStream memStream = new MemoryStream();
byte[] readBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) > 0)
memStream.Write(readBuffer, 0, bytesRead);
return memStream;
}
then call as below.
var wRes = wReq.GetResponse();
var memstream = Read(wRes.GetResponseStream());
var resgzip = new GZipStream(memstream, CompressionMode.Decompress);
var reader = new StreamReader(resgzip);
var textResponse = reader.ReadToEnd();
Currently i am using following code , is there any better (means fast) way to upload a file, here is my complete code, it is called at each file upload:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("request_uri_string");
FileStream fileStream = new FileStream("path_to_my_file",
FileMode.Open, FileAccess.Read);
Stream requestStream = request.GetRequestStream();
byte[] buffer = new Byte[checked((uint)Math.Min(4096,
(int)fileStream.Length))];
int bytesRead = 1;
while (bytesRead != 0)
{
bytesRead = fileStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
}
requestStream.Close();
fileStream.Close();
String responseFromServer = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (((HttpWebResponse)response).StatusDescription.Contains("OK"))
{
Encoding encode = System.Text.Encoding.GetEncoding(((HttpWebResponse)response).CharacterSet);
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream, encode);
responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
}
response.Close();
Probably not faster, but easier:
WebClient client = new WebClient();
//client.Credentials = new NetworkCredential("username", "password");
client.UploadFile(uriString,fileName);