Adding SSL cert causes 404 only in browser calls - c#

I am working in an internal corporate environment. We have created a webapi installed on iis on port 85. We call this from another MVC HelperApp on port 86. It all works as expected. Now we want to tighten security and add an SSL cert to iis on port 444 and bind it to our API.
Initially we test it with Postman, SoapUI, and a C# console app and it all works. Now we try calling it from our MVC HelperApp and it returns a 404 sometimes.
Deeper debugging; I put the code into a C# DLL (see below). Using the console app I call the Dll.PostAPI and it works as expected. Now I call that same Dll.PostAPI from the MVC HelperApp and it won't work. When I step through the code I make it as far as this line await client.PostAsync(url, data); and the code bizarrely ends, it doesn't return and it doesn't throw an exception. Same for Post and Get. I figure it makes the call and nothing is returned, no response and no error.
Also, if I change the url to "https://httpbin.org/post" or to the open http port85 on iss it will work. I have concluded that the C# code is not the problem (but I'm open to being wrong).
Therefore I have come to the conclusion that for some reason the port or cert is refusing calls from browsers.
We are looking at:
the "Subject Alternative Name" but all the examples show
WWW.Addresses which we are not using.
the "Friendly Name" on the cert creation.
and CORS Cross-Origin Resource Sharing.
These are all subjects we lack knowledge in.
This is the calling code used exactly the same in the console app and the web app:
var lib = new HttpsLibrary.ApiCaller();
lib.makeHttpsCall();
This is what's in the DLL that gets called:
public async Task<string> makeHttpsCall()
{
try
{
List<Quote> quotes = new List<Quote>();
quotes.Add(CreateDummyQuote());
var json = JsonConvert.SerializeObject(quotes);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var url = "https://httpbin.org/post"; //this works in Browser
//url = "https://thepath:444//api/ProcessQuotes"; //444 DOES NOT WORK in browsers only. OK in console app.
//url = "http://thepath:85/api/ProcessQuotes"; //85 works.
var client = new HttpClient();
var response = await client.PostAsync(url, data); //<<<this line never returns when called from browser.
//var response = await client.GetAsync(url); //same outcome for Get or Post
var result = await response.Content.ReadAsStringAsync();
return result;
}
catch (Exception ex)
{
throw;
}
}

Related

How can I log Get/Patch/Post statements being sent from my .NET library project?

I'm not sure there is anything wrong with my code, but I have a dll .net 4.8 library file that is hooked up to an ERP system that makes REST calls to a third party web based app that is unix-based. We are troubleshooting an issue regarding a strange error but something else came up where they said they are getting a lot of GET statements from the dll for URLs that require PATCH/POST and those urls (specifically one) doesn't have functionality set up for a GET statement.
Is is possible that the .NET objects are sending underlying HTTP calls?
So basically, I would like to log all of the REST statements that are being sent to verify, if possible, where they are coming from. I've combed my code and there is literally one entry point to this statement and I am sending a PATCH and the resource url doesn't require anything to be sent in the body except an empty string.
So is there a way to log all the HTTP calls going out from my project? See code below for my routine.
I've looked up how to log and I mostly get results for web projects, but this is a dll project and I'm not sure if those suggestions will work for this.
try
{
CVToken curToken = CVGlobalRestCalls.GetToken(Session);
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", curToken.Token);
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var jSettings = new JsonSerializerSettings();
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("PATCH"), string.Format("{0}/readytosend/{1}/complete", Globals.GetRESTURL(Session), JobID));
request.Content = new StringContent(JsonConvert.SerializeObject(string.Empty, Formatting.Indented, jSettings), Encoding.Default, "application/json-patch+json");
HttpResponseMessage response = httpClient.SendAsync(request).Result;
CVJob cvCompletedJob = JsonConvert.DeserializeObject<CVJob>(CVGlobalRestCalls.GetResponseContent(response));
outFile.WriteLine(string.Format("Invoice Group {0} has been pushed to CV", JobID.ToString()));
}
catch (Exception ex)
{
throw new Exception(string.Format(" {0}", ex.Message));
}

Simulating a web browser C#

I'm trying to extract data with HtmlAgilityPack from various websites by downloading their HTML code with client.DownloadStringAsync(). This has been working flawlessy so far, but I recently encountered a problem with one of the websites I tried to download this way. Instead of the actual content of the site which can be seen in a browser, it just said "Loading...". After checking networking in chrome, it seems that the GET request just gets a raw HTML, which doesn't actually include any of the data I need and instead it is mostly initialized by Javascript. I found the Selenium WebDriver which should do what I want it to, however I think it will conflict if I try to run all of that on a Raspberry Pi (which is what I'm designing this project for). If there are any alternatives, let me know or if it works on unix based systems too. Here is the Http Getter I used so far:
private async Task<string> HttpGet(string URL) {
using var client = new HttpClient();
using var request = new HttpRequestMessage {RequestUri = new Uri(URL), Method = HttpMethod.Get};
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead);
if (response.StatusCode == HttpStatusCode.NotFound) return "404";
return await response.Content.ReadAsStringAsync();
}
After attempting to use the aformentioned NuGet package with Chrome, I managed to get heaps of different errors which were all foreign to me. Here's my code:
private string SeleniumGet(string URL) {
ChromeOptions options = new ChromeOptions();
options.AddArgument("headless");
options.BinaryLocation = Directory.GetCurrentDirectory() + #"\chromedriver.exe"; //Probably not gonna work on an RPi
using ChromeDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl(URL);
return driver.PageSource; //Unsure if this is source code, doesn't really matter for now - program crashes when initiating chrome driver
}
Currently am stuck on it saying Invalid --log-level value., but I had other ones like unknown error: DevToolsActivePort file doesn't exist. however, I can't reproduce that one. Currently only the invalid log level error pops up, which crashes when constructing the ChromeDriver. Thanks for the help in advance. If the site I try to access matters, This is it. Looking at the GET request in networking shows the blank page with loading on it.

C# WPF POST Request to php file on https site on strato server not working

I want to post one or more values to a php file on a strato (the host) server on a https domain using a C# WPF desktop application. However, after several attempts with a test program nothing seems to work. The testing value is not posted to the server, the $_POST Array is empty, respectively. I do get an echoed answer from the server but its always 'Error' (See script below).
I did try this with several techniques as well:
Webclient / HttpClient
HttpWebRequest
Adjusting SecurityProtocolType
sending value as byte[]
and what not.
$_GET by the way works perfectly fine as I always get back the computed testing value from the php script. However, I would like to have a POST Request since I am sending user data to the server.
More precisely, I already have tried these solutions (and several similar ones):
How to make HTTP POST web request (basically all of them except 3rd Party)
C# HttpClient not sending POST variables
https://holger.coders-online.net/118
http://www.howtosolvenow.com/how-to-send-https-post-request-with-c/
Testing PHP Script:
$newnumber = 'Error';
if(isset($_POST['number']))
{
$newnumber = $_POST['number']+1;
}
echo $newnumber;
//keeps on returning 'Error'
Latest attempt of C# code:
string resultString = null;
string _url = "https://myURL.com/test.php";
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
HttpClient client = new HttpClient();
var content = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("number", "2"),
});
var response = await client.PostAsync(_url, content);
resultString = await response.Content.ReadAsStringAsync();
this._txt.Text = resultString;

Invalid PUT method from Webforms to Web API 2 (Azure)

I have a Web API in my Azure server and I'm making calls from an ASP.NET Webforms website.
I seem to be able to perform GET with no trouble. Now for the PUT, it's giving me this error:
The page you are looking for cannot be displayed because an invalid
method (HTTP verb) is being used
I was not able to DELETE either. I see some other topics where people disable some WebDav and stuff on their IIS servers and it works. But on Azure?
Below my code for the PUT:
HttpResponseMessage response = client.GetAsync("api/People/" + id).Result;
if (response.IsSuccessStatusCode)
{
var yourcustomobjects = response.Content.ReadAsAsync<People>().Result;
Uri peopleUrl = response.Headers.Location;
yourcustomobjects.name= "Bob";
response = await client.PutAsJsonAsync(peopleUrl, yourcustomobjects);
tbDebug.Text += await response.Content.ReadAsStringAsync();
}
Alright I grew tired of trying to fix this issue by enabling PUT.
So what I did, was I wrote a GET that makes the needed change in the database.
Cheers

HttpClient GET request fails, POST Succeeds

In a Xamarin application (backed by ASP.NET WebApi), I'm having trouble getting [all of] my GET requests to succeed -- they return 404. In fact, when watching network traffic in Fiddler, I don't even see the request happen.
Here is [basically] what I'm doing:
public async Task<bool> ValidateSponsor(string attendeeId, string sponsorId)
{
string address = String.Format("{0}/Sponsors/?attendeeId={1}&sponsorId={2}", BASE_URI, attendeeId, sponsorId);
var response = await client.GetAsync(address);
var content = response.content;
if (!response.IsSuccessStatusCode)
throw new HttpRequestException("Check your network connection and try again.");
string result = await content.ReadAsStringAsync();
return Convert.ToBoolean(result);
}
If I copy out the address variable and paste it into a browser, it succeeds. POST requests (to different methods, of course) succeed. I've also tried using the PCL version RestSharp but get the same results -- POST succeeds and GET fails.
Edit:
This looks like it also may only be a problem when deployed to Azure, it works fine locally.

Categories