wowza streaming c# HTTP get method for livestreamrecord - c#

Hello I need some help with livestreamrecord recording via http url c# calls,
I can start and stop a stream recording using:
http://[username]:[password]#[wowza-ip-address]:8086/livestreamrecord?app=live&streamname=myStream&action=startRecording
When inputting it directly in to a browser or when I redirect my webpage to it from code, but when I try to do the same from c# on a webpage nothing happens.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://[username]:[password]#[wowza-ip-address]:8086/livestreamrecord?app=live&streamname=myStream&action=startRecording);
request.Method = "GET";
request.Proxy = new WebProxy("[wowza-ip-address]", 8086);
request.Credentials = new NetworkCredential("[username]", "[password]");
request.ContentType = "application/x-www-form-urlencoded";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stm = response.GetResponseStream();
When I first tried to set it up I kept getting 401 unauthorized error which the code above no long throws, but now I'm stuck as no error is thrown and still no recording is started.
The response returns:
<html><head><title>Wowza Streaming Engine 4 Perpetual Edition 4.0.1 build10615</title></head><body>Wowza Streaming Engine 4 Perpetual Edition 4.0.1 build10615</body></html>
Which indicates it is not reaching the livestreamrecord page.
Ben

Sovled the problem, thier was a 302 redirect on the request which was producing the 401 unauthorized responses. Adding:
request.AllowAutoRedirect = false;
and removing:
request.Proxy = new WebProxy("[wowza-ip-address]", 8086);
Resolved the problem.
With Proxy in, it didn't throw an error but also didn't record. Removing Proxy allowed the record command to work but throw the 401 response which was then resolved by setting AllowAutoRedirect to false.

Related

https request fails only in .net web app

I am trying to patch a .net web application that after years of working started failing to get UPS shipping quotes, which is impacting web business dramatically. After much trial and error, I found the following code that works just fine in a console application:
static string FindUPSPlease()
{
string post_data = "<xml data string>";
string uri = "https://onlinetools.ups.com/ups.app/xml/Rate";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// get response and send to console
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
return "done";
}
This runs in Visual Studio just fine and gets a nice little response from UPS that the XML is, of course, malformed.
But, if I paste this function into the web application without changing a single character, an exception is thrown on request.GetRequestStream():
Authentication failed because the remote party has closed the transport stream.
I tried it in a couple of different place in the application with the same result.
What is there about the web application environment that would affect the request?
It turns out to be a TLS issue. I guess the console app uses a higher protocol by default than the web application, although none was specified. So, all you have to do is add the following line(s) of code sometime prior to making the request:
using System.Net;
...
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
That was all it took, though I spent an enormous amount of getting there.
Here is the response from UPS on the issue:
Effective January 18, 2018, UPS will only accept TLS 1.1 and TLS 1.2 security protocols... 100% of requests from customers who are on TLS 1.0 while using production URLS (onlinetools.ups.com/tool name) will be rejected.
Anyway, hope this helps someone.
Jim
Can you try setting the Credentials to your request object like following.
request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
Try setting the default credentials or check if there is any proxy server set and pass it like in the example below.
The example is given for WebClient.
I was having problem with setting Default Credential, as proxy was enabled on the server. So i passed the proxy URL and port with credentials which can access it.
using (System.Net.WebClient web = new System.Net.WebClient())
{
//IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy;
//defaultWebProxy.Credentials = CredentialCache.DefaultCredentials;
//web.Proxy = defaultWebProxy;
var proxyURI = new Uri(string.Format("{0}:{1}", proxyURL, proxyPort));
//Set credentials
System.Net.ICredentials credentials = new System.Net.NetworkCredential(proxyUserId, proxyPassword);
//Set proxy
web.Proxy = new System.Net.WebProxy(proxyURI, true, null, credentials);
web.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var result = web.UploadString(URL, "");
return result;
}

Authentication to REST API: digest type with cookie (c#)

I have a service REST API where I tryied to connect.
Using browser all is ok.
But in c# I always have an unauthorized answer.
I investigated this issue using fiddler and find out that in first unsuccessful reuest server returns some cookie, and browser use it in next session together with username/password (digest type).In this case second session is successful.
But when I try to send request using c# (I tried work with System.Net.WebClient and HttpWebRequest) I don't get response (I had timeout exception after some time).
My code:
WebClient webClient = new WebClient();
CredentialCache cache = new CredentialCache();
Uri prefix = new Uri(Url);
cache.Add(prefix, "Digest", new NetworkCredential(login, password));
webClient.Credentials = cache;
...
string response = webClient.DownloadString(restRequest);
Last line throws exception.
When I investigated this issue in Fiddler I found out that in first session with status 401 we recieved cookie (like on picture below).
fiddler's picture
Browser sends this cookie in next request and authentication happens successfully.
But in c# I couldn't geet this response with status 401. As I see in fiddler studio try to open new session 10-20 times during each next seconds before timeout exception will be thrown. And my response in null.
Also I have other environment without required cookie, there my code is working.
Please, give me a piece of advise hoe to get response with Status 401 and get cookie from it to set it to another request.
thanks
Mike
I resolved this issue using HttpWebRequest with defined empty (not null) CookieContainer.
My code:
HttpWebRequest request1;
HttpWebResponse response1 = null;
String responseBody;
request1 = (HttpWebRequest) WebRequest.Create(requestString);
request1.Credentials = cache;
request1.CookieContainer = new CookieContainer();
response1 = (HttpWebResponse) request1.GetResponse();
using (StreamReader stream = new StreamReader(response1.GetResponseStream(), Encoding.UTF8))
{
responseBody = stream.ReadToEnd();
}
In this implementation after first session with status 401 requests provide cookie from first session to next one and it returns with status code 200 OK.

Cancel HTTPWebRequest when server goes down

I have created a Windows Service that calls a API (that returns JSON) with HTTPWebRequest.
The API doesn't return anything until it has something to "deliver". So I set the timeout quite high and lets the request wait until it receivs a response.
The problem is that when I test to turn off or disconnect the server running the API. The HTTPWebRequest doesn't stop the request. So I can't know if the API server has gone down.
The request code:
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(Url);
Request.Method = "POST";
Request.ContentType = "application/x-www-form-urlencoded";
Request.ContentLength = PostData.Length;
Request.Timeout = Timeout;
Request.KeepAlive = true;
using (StreamWriter sw = new StreamWriter(Request.GetRequestStream()))
{
sw.Write(PostData);
}
using (HttpWebResponse Response = (HttpWebResponse)Request.GetResponse())
{
using (StreamReader sr = new StreamReader(Response.GetResponseStream()))
{
ResponseText = sr.ReadToEnd();
}
}
Is there anyway to "break" the request when the requested server goes down?
I have tried using the webbrowser to call the API server and after a while disconnect it and that return an error to the webpage.
you could use a background worker only cecking if the server is online. It has some disatvantages but may work fine.
It is always good to keep the requests asynchronous (See the BeginXXX methods in HttpWebRequest - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx).
Using the asynchronous APIs ensures that you are not blocked until you get a response from the server.
In addition to using the asynchronous APIs, you can have a heart-beat requests (that could be just a HEAD HTTP request to a ping service on the server, which returns an empty body and HTTP 200 status), to keep track that the server is alive. If this request times out, then server is not alive - in which case, you can cancel / just 'forget' that the request has been made.

Can I send an empty HTTP POST WebRequest object from C# to IIS?

Do I need to just slap some random garbage data in a WebRequest object to get by the HTTP status code 411 restriction on IIS?
I have an HttpPost action method in an MVC 3 app that consumes a POST request with all the relevant information passed in the querystring (no body needed).
[HttpPost] public ActionResult SignUp(string email) { ... }
It worked great from Visual Studio's built in web host, Cassini. Unfortunately, once the MVC code was live on IIS [7.5 on 2008 R2], the server is pitching back an HTTP error code when I hit it from my outside C# form app.
The remote server returned an error:
(411) Length Required.
Here is the calling code:
WebRequest request = WebRequest.Create("http://somewhere.com/signup/?email=a#b.com");
request.Method = "POST";
using (WebResponse response = request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseReader = new StreamReader(responseStream)) {
// Do something with responseReader.ReadToEnd();
}
Turns out you can get this to go through by simply slapping an empty content length on the request before you send it.
WebRequest request = WebRequest.Create("http://somewhere.com/signup/?email=a#b.com");
request.Method = "POST";
request.ContentLength = 0;
Not sure how explicitly giving an empty length vs. implying one makes a difference, but IIS was happy after I did. There are probably other ways around this, but this seems simple enough.
I believe you are required to set a Content-Length header anytime you post a request to a web server:
http://msdn.microsoft.com/en-us/library/system.web.httprequest.contentlength.aspx
You could try a GET request to test it.

HttpWebRequest.GetResponse: "The underlying connection was closed: An unexpected error occurred on a receive."

I've written a C# Windows service (.NET Framework 3.5, C# 3.0) that posts files & HTML form information to a remote server, and then stores the XML server response in a database. Here is the main chunk of pertinent code:
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
request.KeepAlive = false;
request.Timeout = 600000;
request.ReadWriteTimeout = 600000;
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userAgent;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Push it out there
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
return request.GetResponse() as HttpWebResponse;
My service works properly for all small files, but I get the following error when I try to send larger files (8-9 MB).
The underlying connection was closed: An unexpected error occurred on a receive.
I looked at the outgoing request using Fiddler, and was able to glean the following info:
HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html
Connection: close
Timestamp: 12:25:04.067
ReadResponse() failed: The server did not return a response for this request.
The failure occurs ~7 minutes after I call request.GetResponse(). Is there any way to identify who shut down the connection? And is there anything else I should try on my end to resolve this issue? Thanks in advance!
Since you mention it working for small files, but not larger, I'd suggest checking the max file upload size on the server. I believe the default is 4mb. http://support.microsoft.com/kb/295626
EDIT: Noticed the link above is somewhat out of date. Here's one for iis7: http://www.cyprich.com/2008/06/19/fixing-file-upload-size-limit-in-iis-7/

Categories