Resend HTTP header - c#

I have application. It send request to my proxy class. Proxy must to parse http header string (I done this) and resend it request to server to get a video.
At first, mediacomponent connect to proxy:
var uri = new Uri("http://127.0.0.1:2233/files/1.mp4");
videoPlayer.Source = uri;
Play();
Proxy get http header string
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: 127.0.0.1:2233\r\n\r\n"
I replase host:
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: myserver.ru\r\n\r\n"
Now proxy must get video from server. What must I do?

When using .NET, you don't have to manually create the HTTP message itself. Instead, use the classes in the System.Net.Http namespace to form and send an HTTP message and process the response.
For example, sending an HTTP GET message to a URL can be as simple as:
var uri = new Uri("http://www.foobar.com/");
var client = new HttpClient();
string body = await client.GetStringAsync(uri);
Note that this general approach will download the entire contents of the resource at the given URI. In your case, you may not want to wait for the whole video to download before you start playing/processing/storing it. In which case, you might want to use the HttpClient.ReadAsStream() method which will return a stream from which you can read until the stream closes.

Related

HttpListener doesn't get parameters with # symbol

I start server this way:
HttpListener httpListener = new HttpListener();
httpListener.Prefixes.Add("http://localhost:11000/");
httpListener.Start();
while (true)
{
HttpListenerContext context = httpListener.GetContext();
HttpListenerRequest request = context.Request;
}
Then send two request:
http://localhost:11000/?abc=123
http://localhost:11000/?#abc=123
HttpListener catches first request with parameters, but second without any parameters. I need it because I'm trying implement Facebook Outh and move Facebook answer to my WPF App that listen special port, but Facebook response contains this symbol "#".
How I can recieve all parameters, if get request contains # symbol?
The browser never sends the part of uri after #.
It is by design, since # url fragments are used for client side navigation.
see RFC https://www.rfc-editor.org/rfc/rfc2396#section-4
If the code running on client can be altered by you, you can store the part of URI in an http header, or some other body part of the request.

Get instance of ApiController class from a URL directly

I am looking for a way to call the appropriate method (get, post etc.) on an ApiController class based on the URL and request type etc. without making a http request.
Background: We have an API application with numerous controllers that needs to also accept requests from a remote server. Due to restrictions I cannot control there is no way to open ports between the two servers to allow the remote server to make the request directly so we decided to forward the data using websockets (SignalR). I can send (within reason) whatever information is required.
I have tried the below:
HttpRequestMessage request = new HttpRequestMessage();
var bld = new UriBuilder
{
Port = 123,
Path = "api/v1/search",
Query = "query=search_string"
};
request.RequestUri = bld.Uri;
var httpCfg = AppConfiguration.Get().HttpConfig; //this is the same config that UseWebApi was called with and contains the routes.
var route = httpCfg.Routes.GetRouteData(request);
var controllerSelector = new DefaultHttpControllerSelector(httpCfg);
var descriptor = controllerSelector.SelectController(request);
route contains the controller name (search) but the call to SelectController throws an exception with a 404 response in it (I presume this indicates I am missing something from the fake request). The same URI works when sent as a direct http request so the routes do work as best I can tell.
Is there a better way to do this, or if not what am I missing from the request that is causing the 404?

Is there a simple way to create a new outbound HttpWebRequest from the inbound request?

I need to effect a type of reverse proxy from C# code. (Yes, I know that IIS has a reverse proxy, but for several reasons, I need to do this from code.)
So, my controller action will "relay" the inbound request to another URL, then return the response. Kind of like this:
public string Proxy()
{
// This would be an extension method; it's currently hypothetical
var newRequest = Request.GetRequestToNewUrl("http://newurl.com");
// Make the request and send back whatever we get
var response = newRequest.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.Something))
{
return reader.ReadToEnd();
}
}
The proxied request (to newurl.com) should be identical to the inbound request (headers, body, cookies, etc.), just to a different URL.
I've been playing around with it, and it's more complex than I thought. The inbound Request is an HttpRequestBase, and the proxy request will be an HttpWebRequest. They are fundamentally different types, and there's no direct translation between the two. So far, it's been a tedious process of copy and translating properties.
Before I spend a ton of time debugging all this, is there an easier way? There are a fair number of different types to represent an HTTP request:
HttpRequestBase
HttpWebRequest
HttpRequest
HttpRequestWrapper
Is there a way I'm not aware of to simply "reuse" the inbound request, while changing the URL? Or should I continue with my translation from HttpRequestBase?
yes, it is possible. You can reuse the Request content from an incoming request and the forward it by creating a new request of your own. Create a new client with the address where the request was supposed to be forwarded. And do a get or post with new HTTP client and just return the result.
var client = new HttpClient
{
BaseAddress = new Uri(destinationBaseAddress)
};
return await client.PostAsync(requestUrl, Request.Content);

How do I set up HttpClient PostAsync to call a new web browser

I am using HttpClient PostAsync to send data to a URI. However, the following code doesn't behave as expected:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string>
{
{"cpm_site_id",TOKEN},
{"apikey",API_KEY},
{"cpm_amount",input.Amount},
{"cpm_currency",input.Currency},
{"cpm_trans_id",input.Id},
{"cpm_custom",input.Custom},
};
// Get the parameters in the url encoded format
var content = new FormUrlEncodedContent(values);
//Send request
var response = await client.PostAsync(new Uri(Urls.GetUrl(Methods.Pay, IS_PRODUCTION_SITE)), content);
When the client closes their browser, I want to receive an event notification to call this code, send the above data to the client, and open a new browser instance to perform additional actions. However, this code doesn't accomplish this and I'm not sure exactly why.
I think you'll need to use something like Selenium to automate a web browser. The HttpClient can perform HTTP functions, but does not work like a web browser does.
See this SO post for a 'hello world' example
See this SO post for an example of capturing the browser close event. I've not done this with C#, but I'd imagine it'll be similar to this JAVA example.

Why does WebClient.UploadValues overwrites my html web page?

I'm familiar with Winform and WPF, but new to web developing. One day saw WebClient.UploadValues and decided to try it.
static void Main(string[] args)
{
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["thing1"] = "hello";
values["thing2"] = "world";
//A single file that contains plain html
var response = client.UploadValues("D:\\page.html", values);
var responseString = Encoding.Default.GetString(response);
Console.WriteLine(responseString);
}
Console.ReadLine();
}
After run, nothing printed, and the html file content becomes like this:
thing1=hello&thing2=world
Could anyone explain it, thanks!
The UploadValues method is intended to be used with the HTTP protocol. This means that you need to host your html on a web server and make the request like that:
var response = client.UploadValues("http://some_server/page.html", values);
In this case the method will send the values to the server by using application/x-www-form-urlencoded encoding and it will return the response from the HTTP request.
I have never used the UploadValues with a local file and the documentation doesn't seem to mention anything about it. They only mention HTTP or FTP protocols. So I suppose that this is some side effect when using it with a local file -> it simply overwrites the contents of this file with the payload that is being sent.
You are using WebClient not as it was intended.
The purpose of WebClient.UploadValues is to upload the specified name/value collection to the resource identified by the specified URI.
But it should not be some local file on your disk, but instead it should be some web-service listening for requests and issuing responces.

Categories