Im working on a win form project that I should get some information from specific URL.
I mean I should listen to this url :
http://xxx.xxx.xxx.xxx:8080/getsms
and when It will change to
http://xxx.xxx.xxx.xxx:8080/getsms?Destination=$Destination&Source=$Source&ReceiveTime=$ReceiveTime&MsgBody=$MsgBody
and I have to parse the contex as well.
so how can I know when exactly there is a request in this url?
Is it a good way that I use httpListener? Its my code for that:
public static void SimpleListenerExample(string[] prefixes)
{
HttpListener listener = new HttpListener();
// Add the prefixes.
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.Start();
//Console.WriteLine("Listening...");
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
// You must close the output stream.
output.Close();
listener.Stop();
}
private void button2_Click(object sender, EventArgs e)
{
string[] test = { "http://www.damavand.co.ir:80/" };
SimpleListenerExample(test);
}
but it has not worked. I dont know why. It dosent have any error, but I cant get any response. should I set any server configuration? How? and how can I test my program that I be sure there is a request.
Thanks for any response ...
Related
I use the code below to get an oAuth code using a browser login, it works just fine ie. auth code is returned BUT there is some timing issue between responseOutput.WriteAsync() and http.stop().
When in debug (breakpoint on **** below), then the response is returned to the browser as expected.
If I the comment out the line http.stop() (**** below), then the response is returned to the browser as expected.
BUT If I run the code as usual then the browser shows "page cannot be found", so, it looks as though responseOutput.WriteAsync() is not actually completing (not begin 'awaited').
Do I need to do anything else to ensure that the response is completely sent before stopping the listener?
await GetAuthorizationCode();
public async Task GetAuthorizationCode() {
// Creates an Listener
string redirectUri = "http://127.0.0.1:12345";
HttpListener http = new HttpListener();
http.Prefixes.Add(redirectUri);
http.Start();
// Open auth page in browser
string authUri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?........";
var authorizationRequest = authUri;
Process.Start(authorizationRequest);
// Wait for auth response.
HttpListenerContext context = await http.GetContextAsync();
var sCode = context.Request.QueryString.Get("code");
//Send response to the browser.
HttpListenerResponse response = context.Response;
string responseString = string.Format("<html><head></head><body>Auth OK.</body></html>");
var buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
using (Stream responseOutput = response.OutputStream)
{
await responseOutput.WriteAsync(buffer, 0, buffer.Length);
responseOutput.Close();
}
//****** this line causes problems
http.Stop();
AuthorizationCode = sCode;
}
It seems that I have to set KeepAlive prior to http.stop()
response.KeepAlive = False
Somehow even with calling response.close and/or with a 'using' block around the response it still needed this setting.
From an old http handler I made some time ago, I have this code:
protected static void WriteString(HttpListenerResponse response, HttpContentType contentType, Encoding encoding, string content)
{
byte[] outputBuffer = encoding.GetBytes(content);
response.ContentType = contentType.Value + "; charset=" + encoding.BodyName;
response.ContentLength64 = outputBuffer.Length;
response.Close(outputBuffer, true);
}
This code have been active on a program that usually stayed days if not weeks serving few thousand requests each day and never had any kind of issues regarding memory leaks.
From docs:
You can customize the response by setting various properties, such as
StatusCode, StatusDescription, and Cookies. Use the
HttpListenerResponse.OutputStream property to obtain a Stream instance
to which response data can be written. Finally, send the response data
to the client by calling the Close method.
https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistenerresponse?view=net-6.0
Oposed to my though, the HttpListener docs states to close the output stream:
https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-6.0
Which is quite confusing:
System.IO.Stream output = response.OutputStream;
output.Write(buffer,0,buffer.Length);
// You must close the output stream.
output.Close();
listener.Stop();
I would suggest to try the follwing code:
using (Stream responseOutput = response.OutputStream)
{
await responseOutput.WriteAsync(buffer, 0, buffer.Length);
//The following two lines are possibly unnecesary in an unsing statement
//responseOutput.Flush(); //Ensure content placed on the right place
//responseOutput.Close();
}
response.Close();
http.Stop();
--- Update ---
I could run the following code under .Net6.0 without any issue and got the response content on the browser:
class Program
{
static async Task Main(string[] args)
{
await RunUntilServeOneRequest();
}
private static async Task RunUntilServeOneRequest()
{
Console.WriteLine("Starting...");
// Creates an Listener
string listenUri = "http://127.0.0.1:12346/";
HttpListener http = new HttpListener();
http.Prefixes.Add(listenUri);
http.Start();
// Wait for request.
Console.WriteLine("Awaiting request to " + listenUri);
HttpListenerContext context = await http.GetContextAsync();
//Send response to the browser.
HttpListenerResponse response = context.Response;
string responseString = string.Format($"<html><head></head><body>Hello world: {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}</body></html>");
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
using (Stream responseOutput = response.OutputStream)
{
await responseOutput.WriteAsync(buffer, 0, buffer.Length);
responseOutput.Close();
}
response.Close();
Console.WriteLine("Request answered");
http.Stop();
}
}
So, here's a scenario that I made up, in which I am making my own web browser and I want to make sure I'm sending correct POST text to web server.
For that to be achieved, I need to get the POST text that WebRequest creates for me before I invoke GetResponseStream().
I tried to read through the stream from WebRequest.GetRequestStream(), but I assume that isn't a way to do that.
I do NOT want plain HTML text responsed from web server.
The POST text that I need to gain must look like something like this as follows :
POST http://www.some_web_server.com/default.aspx HTTP/1.1
Cache-Control : max-age=0 Connection : keep-alive .....
Thanks in advance.
[UPDATE]
It's clear that I already have all fomulated request(POST) text in my WebRequest instance.
Is there any way conveniently to just get the whole plain text from it, rather than using separated get properties such as ContentType or Headers?
(Because I am lazy to 'assemble' all the headers that I specified into the whole complete POST text, which web server will eventually see.)
// This might be a very poor code to approach.
public void Show_Full_POST_Text(WebRequest req)
{
// For example.
String strRawText = req.GetRequestLiteral();
// Your POST text looks like this!
ShowToUser(strRawText);
}
public void Foo()
{
// ...
Show_Full_POST_Text(req);
var ResponseStream = req.GetResponseStream();
// Continue.
}
If your saying that you don't want to get some headers via the request properties e.g "request.ContentType" and other via the header collection, then you can just use the header collection as it already contains the key for ContentType.
using System;
using System.Collections.Generic;
using System.Net;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.example.com");
request.Method = "POST";
request.ContentType = "image/png";
Console.WriteLine(GetRequestAsString(request));
Console.ReadKey();
}
public static string GetRequestAsString(HttpWebRequest request)
{
string str = request.Method + " " + request.RequestUri + " HTTP/" + request.ProtocolVersion + Environment.NewLine;
string[] headerKeys = request.Headers.AllKeys;
foreach (string key in headerKeys)
{
str += key + ":" + request.Headers[key];
}
return str;
}
}
}
Your question is pretty vague, however, I believe what you're looking for is including the headers within the Webrequest. The MSDN has a good example. See below:
public static void Main (string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (args[0]);
// Set some reasonable limits on resources used by this request
request.MaximumAutomaticRedirections = 4;
request.MaximumResponseHeadersLength = 4; //This sets the max headers coming back to your response.
// Set credentials to use for this request.
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
Console.WriteLine ("Content length is {0}", response.ContentLength);
Console.WriteLine ("Content type is {0}", response.ContentType);
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
Console.WriteLine ("Response stream received.");
Console.WriteLine (readStream.ReadToEnd ());
response.Close ();
readStream.Close ();
}
I want to use webclient or httpRequest to make request on some URL. It ok if the web don't need authetication, But if website need credentical then the respond not ok. I use example code of Microsoft like below:
public class Test
{
// Specify the URL to receive the request.
public static void Main (string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (args[0]);
// Set some reasonable limits on resources used by this request
request.MaximumAutomaticRedirections = 4;
request.MaximumResponseHeadersLength = 4;
// Set credentials to use for this request.
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
Console.WriteLine ("Content length is {0}", response.ContentLength);
Console.WriteLine ("Content type is {0}", response.ContentType);
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
Console.WriteLine ("Response stream received.");
Console.WriteLine (readStream.ReadToEnd ());
response.Close ();
readStream.Close ();
}
}
Who have experience about this please help me in more detail.
HttpResponseCode has a property called StatusCode which specifies if the request has failed or succeeded. There are various status code which you can find online. But the one you are looking for is 401 which means unauthorized and 200 is for request that is successful. You can add following line after request.GetResponse() to check whether your request was successful or not.
if (response.StatusCode == HttpStatusCode.OK){
// you can continue parsing your response here.
}elseif(response.StatusCode == HttpStatusCode.Unauthorized){
// this means your request has failed due to authentication issue.
}
I'm trying to excecute some post request, I censored the site because it has some sensitive data.. Well here's the code:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.someaddress.com");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("sdata", ""));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
Log.d("MyTag", "works till here.");
try {
HttpResponse response = httpclient.execute(httppost);
// String responseBody = EntityUtils.toString(response.getEntity());
// Log.d("MyTag", responseBody);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
It crashes on that line:
HttpResponse response = httpclient.execute(httppost);
Here's the logcat which really says nothing to me:
http://pastebin.com/F0YAiNLD
What could be the problem? Why is it crashing?
I'm trying to translate this C# code to JAVA. The C# code works but the JAVA code isn't.
Here's the C# code:
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
string pData = "";
byte[] sdata = encoding.GetBytes(pData);
HttpWebRequest request = new HttpWebRequest(new Uri("http://www.someaddress.com"));
request.ContentType="application/x-www-form-urlencoded";
request.ContentLength = sdata.Length;
Stream nStream=request.GetRequestStream();
nStream.Write(sdata,0,sdata.Length);
nStream.Close();
HttpWebResponse response =
(HttpWebResponse) request.GetResponse();
I'm not an Android developer but a simple Google search for "Android NetworkOnMainThreadException" shows that this exception is thrown when you attempt to do network actions on the main event thread (the name is pretty self-descriptive), and that instead you should be making these type of network calls on a background thread.
Typically in GUI apps it is a bad idea to do work in the main thread that can block (such as a network HTTP call) since it will block the main animation loop.
Have you run into this problem? I run code remarkably similar to that from a this previous question, When in nUnitTest mode and the URI includes "/?test&format=xml" the nUnit test fails with and IOException, "Unable to read data from the transport connection: The connection is closed."
However the Fiddler trace that was running at the time shows the very xml I expected.
I've recreated the request headers exactly (almost) as they are sent when sent through the browser.
Finally, if I leave off the "/?test&format=xml" from the URI, I get the html I would have otherwise expected.
SOURCE CODE:
public virtual bool Run()
{
var request = CreateRequest();
var response = GetResponse(request);
var responseString = ReadResponse(response);
this.SetResults(responseString);
return this.IsSuccessful;
}
protected internal virtual HttpWebRequest CreateRequest()
{
var address = TestConfig.Address;
var request = (HttpWebRequest)WebRequest.Create(address);
request.Accept = "*/*";
request.UseDefaultCredentials = true;
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
return request;
}
protected internal virtual HttpWebResponse GetResponse(HttpWebRequest request)
{
var response = (HttpWebResponse) request.GetResponse();
return response;
}
protected internal virtual string ReadResponse(HttpWebResponse response)
{
var stream = response.GetResponseStream();
var responseString = ReadResponse(stream);
stream.Close();
response.Close();
return responseString;
}
protected internal virtual string ReadResponse(Stream stream)
{
var reader = new StreamReader(stream);
var responseString = reader.ReadToEnd();
return responseString;
}
The error message "Unable to read data from the transport connection: The connection is closed." doesn't really tie up with the fact you're seeing Fiddler getting a html response body back.
Check the StatusCode of the HttpWebResponse (should be 200 if ok), also wrap the request in try/catch block (example from http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.statuscode(v=vs.80).aspx)
try
{
// Creates an HttpWebRequest for the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for a response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
Console.WriteLine("\r\nResponse Status Code is OK and StatusDescription is: {0}",
myHttpWebResponse.StatusDescription);
// Releases the resources of the response.
myHttpWebResponse.Close();
}
catch(WebException e)
{
Console.WriteLine("\r\nWebException Raised. The following error occured : {0}",e.Status);
}
catch(Exception e)
{
Console.WriteLine("\nThe following Exception was raised : {0}",e.Message);
}
If you're creating and disposing of the HttpWebRequest object quickly you might be getting the socket going into a time_wait state as it is shutting down, then you can't re-open it again until it has completely closed. If this is the case, look into using another port or changing the time the connection lives for.