HttpWebResponse send to web browser? - c#

I am new to c# and am making a simple proxy to edit certain headers.
I have used HttpLisenter to get the request and then used HttpWebRequest and Response to edit, send and receive.
Now I need some help to send the edited response back to the web browser. Does anyone have any links or examples? Im stumped :)
Thanks

Here's a short example:
public void ProcessRequest(HttpContext context)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create([NEW_URL]);
request.Timeout = 1000 * 60 * 60;
request.Method = context.Request.HttpMethod;
if (request.Method.ToUpper() == "POST")
{
Stream sourceInputStream = context.Request.InputStream;
Stream targetOutputStream = request.GetRequestStream();
sourceInputStream.CopyTo(targetOutputStream);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
context.Response.ContentType = request.ContentType;
using (response)
{
Stream targetInputStream = response.GetResponseStream();
Stream sourceOutputStream = context.Response.OutputStream;
targetInputStream.CopyTo(sourceOutputStream);
}
}
This assume the following extension method is defined (I think using this makes the sample more readable):
public static void CopyTo(this Stream input, Stream output)
{
using (input)
using (output)
{
byte[] buffer = new byte[1024];
for (int amountRead = input.Read(buffer, 0, buffer.Length); amountRead > 0; amountRead = input.Read(buffer, 0, buffer.Length))
{
output.Write(buffer, 0, amountRead);
}
}
}

You could save the response to an html file and then start the browser with a command to open the file.
class Program
{
static int Main() {
WebRequest wr = HttpWebRequest.Create("http://google.com/");
HttpWebResponse wresp = (HttpWebResponse)wr.GetResponse();
string outFile = #"c:\tmp\google.html";
using (StreamReader sr = new StreamReader(wresp.GetResponseStream()))
{
using(StreamWriter sw = new StreamWriter(outFile, false)) {
sw.Write(sr.ReadToEnd());
}
}
BrowseFile(outFile);
return 0;
}
static void BrowseFile(string filePath)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
startInfo.Arguments = filePath;
Process.Start(startInfo);
}
}

Take a look at source code for existing proxy servers.
Mini Proxy Server (c#)
Web Proxy Server (c#)

Related

Bot Framework - Using Custom Speech Service Error 400 C#

I created a bot with bot framework and now i'm trying to use the CustomSpeech service instead of the bing SpeechToText Service that works fine. I have tried various way to resolve the problem but i get the error 400 and i don't know how to solve this.
The method where i would like to get the text from a Stream of a wav pcm audio:
public static async Task<string> CustomSpeechToTextStream(Stream audioStream)
{
audioStream.Seek(0, SeekOrigin.Begin);
var customSpeechUrl = "https://westus.stt.speech.microsoft.com/speech/recognition/interactive/cognitiveservices/v1?cid=<MyEndPointId>";
string token;
token = GetToken();
HttpWebRequest request = null;
request = (HttpWebRequest)HttpWebRequest.Create(customSpeechUrl);
request.SendChunked = true;
//request.Accept = #"application/json;text/xml";
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.ContentType = "audio/wav; codec=\"audio/pcm\"; samplerate=16000";
request.Headers["Authorization"] = "Bearer " + token;
byte[] buffer = null;
int bytesRead = 0;
using (Stream requestStream = request.GetRequestStream())
{
// Read 1024 raw bytes from the input audio file.
buffer = new Byte[checked((uint)Math.Min(1024, (int)audioStream.Length))];
while ((bytesRead = audioStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
string responseString = string.Empty;
// Get the response from the service.
using (WebResponse response = request.GetResponse()) // Here i get the error
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
}
dynamic deserializedResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(responseString);
if (deserializedResponse.RecognitionStatus == "Success")
{
return deserializedResponse.DisplayText;
}
else
{
return null;
}
}
At using (WebResponse response = request.GetResponse()){} i get an exception (Error 400).
Am I doing the HttpWebRequest in the right way?
I read in internet that maybe the problem is the file audio... but then why with the same Stream bing speech service doesn't return this error?
In my case the problem was that i had a wav stream audio that doesn't had the file header that Cris (Custom Speech Service) needs. The sulution is creating a temporary file wav, read the file wav and copy it in a Stream to send it as array to Cris
byte[] buffer = null;
int bytesRead = 0;
using (Stream requestStream = request.GetRequestStream())
{
buffer = new Byte[checked((uint)Math.Min(1024, (int)audioStream.Length))];
while ((bytesRead = audioStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
or copy it in a MemoryStream and send it as array
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(audioStream.ToArray(), 0, audioStream.ToArray().Length);
requestStream.Flush();
}

Monitoring upload progress with HttpWebRequest

I've recently written a C# function that does a multi part form post for uploading files. To track the progress, I'd write the form data to the request stream at 4096 bytes at a time and call back with each write. However, it seems that the request does not even get sent until GetResponseAsync() is called.
If this is the case, is the reporting of every 4096 bytes written to the request stream an accurate reporting of upload progress?
If not, how can I accurately report progress? WebClient is out of the question for me, this is in a PCL Xamarin project.
private async Task<string> PostFormAsync (string postUrl, string contentType, byte[] formData)
{
try {
HttpWebRequest request = WebRequest.Create (postUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = contentType;
request.Headers ["Cookie"] = Constants.Cookie;
byte[] buffer = new byte[4096];
int count = 0;
int length = 0;
using (Stream requestStream = await request.GetRequestStreamAsync ()) {
using (Stream inputStream = new MemoryStream (formData)) {
while ((count = await inputStream.ReadAsync (buffer, 0, buffer.Length)) > 0) {
await requestStream.WriteAsync (buffer, 0, count);
length += count;
Device.BeginInvokeOnMainThread (() => {
_progressBar.Progress = length / formData.Length;
});
}
}
}
_progressBar.Progress = 0;
WebResponse resp = await request.GetResponseAsync ();
using (Stream stream = resp.GetResponseStream ()) {
StreamReader respReader = new StreamReader (stream);
return respReader.ReadToEnd ();
}
} catch (Exception e) {
Debug.WriteLine (e.ToString ());
return String.Empty;
}
}
Please note that I am asking about monitoring progress of an upload at 4096 bytes at a time, not a download
I ended up accomplishing this by setting the AllowWriteStreamBuffering property of the WebRequest equal to false and the SendChunked property to true.
HOWEVER Xamarin.PCL (Profile 78) does not allow you to access these properties of the HttpWebRequest, so I had to instantiate my HttpWebRequest and return it from a dependency service in my platform specific project (only tested in iOS).
public class WebDependency : IWebDependency
{
public HttpWebRequest GetWebRequest(string uri)
{
var request = WebRequest.Create (uri) as HttpWebRequest;
request.SendChunked = true;
request.AllowWriteStreamBuffering = false;
return request;
}
}
And then to instantiate my web request -
HttpWebRequest request = DependencyService.Get<IWebDependency>().GetWebRequest(uri);

How to upload many text files from local computer to ftp using c# .net?

I need to upload text file from local machine to ftp server using c#.
I've tried folowing code but it did't work.
private bool UploadFile(FileInfo fileInfo)
{
FtpWebRequest request = null;
try
{
string ftpPath = "ftp://www.tt.com/" + fileInfo.Name
request = (FtpWebRequest)WebRequest.Create(ftpPath);
request.Credentials = new NetworkCredential("ftptest", "ftptest");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.KeepAlive = false;
request.Timeout = 60000; // 1 minute time out
request.ServicePoint.ConnectionLimit = 15;
byte[] buffer = new byte[1024];
using (FileStream fs = new FileStream(fileInfo.FullPath, FileMode.Open))
{
int dataLength = (int)fs.Length;
int bytesRead = 0;
int bytesDownloaded = 0;
using (Stream requestStream = request.GetRequestStream())
{
while (bytesRead < dataLength)
{
bytesDownloaded = fs.Read(buffer, 0, buffer.Length);
bytesRead = bytesRead + bytesDownloaded;
requestStream.Write(buffer, 0, bytesDownloaded);
}
requestStream.Close();
}
}
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
request = null;
}
return false;
}// UploadFile
any suggestions ???
You need to actually send the request by calling GetResponse().
You can also make your code much simpler by calling fs.CopyTo(requestStream).
I tinkered around with a bit ftp code and got the following, which seems to work pretty well for me.
ftpUploadloc is a ftp://ftp.yourftpsite.com/uploaddir/yourfilename.txt
ftpUsername and ftpPassword should be self explanatory.
Finally currentLog is the location of the file you're uploading.
Let me know how this worked out for you, if anyone else has any other suggestions I welcome those.
private void ftplogdump()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUploadloc);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
StreamReader sourceStream = new StreamReader(currentLog);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
// Remove before publishing
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}

Download a file from a form post

I have a c# script that does 2 things
This script connects a my web server to get a pin number generated,
It then makes a connection where its post a form with that pin number it gets from my web server,
The problem is when the form is posted it responds with an application now i need to run this application i don't care if i have to save the exe then run it or if i can run it from memory
Here is my script sofar
string[] responseSplit;
bool connected = false;
try
{
request = (HttpWebRequest)WebRequest.Create(API_url + "prams[]=");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
connected = true;
}
catch(Exception e)
{
MessageBox.Show(API_url + "prams[]=");
}
if (!connected)
{
MessageBox.Show("Support Requires and Internet Connection.");
}
else
{
request = (HttpWebRequest)WebRequest.Create(API_url + "prams[]=");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string responceString = reader.ReadToEnd();
responseSplit = responceString.Split('\n');
WebRequest req = WebRequest.Create("https://secure.logmeinrescue.com/Customer/Code.aspx");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes("Code=" + responseSplit[1]);
req.ContentLength = bytes.Length;
Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
WebResponse responce = req.GetResponse();
hasDownloaded = true;
}
Well you could save the response into a file and then run it (assuming it's an executable of course):
using (var response = req.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var output = new FileStream("test.exe", FileMode.Create, FileAccess.Write))
{
var buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
Process.Start("test.exe");

Can I do a file upload to a web API using a web file as the source using streaming?

In C# rather than having to dowloading a file from the web using httpwebrequest, save this to file somewhere, and then upload to a webservice using a POST with the file as one of the parameters...
Can I instead somehow open a reader stream from httpwebresponse and then stream this into the http POST? Any code someone could post to show how?
In other words I'm trying to avoid haing to save to disk first.
Thanks
Something like that should do the trick :
HttpWebRequest downloadRequest = WebRequest.Create(downloadUri) as HttpWebRequest;
using(HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
HttpWebRequest uploadRequest = new HttpWebRequest(uploadUri);
uploadRequest.Method = "POST";
uploadRequest.ContentLength = downloadResponse.ContentLength;
using (Stream downloadStream = downloadResponse.GetResponseStream())
using (Stream uploadStream = uploadRequest.GetRequestStream())
{
byte[] buffer = new byte[4096];
int totalBytes = 0;
while(totalBytes < downloadResponse.ContentLength)
{
int nBytes = downloadStream.Read(buffer, 0, buffer.Length);
uploadStream.Write(buffer, 0, nBytes);
totalBytes += nRead;
}
}
HttpWebResponse uploadResponse = uploadRequest.GetResponse() as HttpWebResponse;
uploadResponse.Close();
}
(untested code)

Categories