Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I avoid a "Bad Request - Invalid Hostname" error when making a REST call from a Compact Framework client?

I used this code from here to try to call a REST Controller method on a Web API server app from a Compact Framework client:

public static void SendXMLFile3(string uri, string data)
{
    WebRequest request = WebRequest.Create (uri);
    request.Method = "POST";
    string postData = data;
    byte[] byteArray = Encoding.UTF8.GetBytes (postData);
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = byteArray.Length;
    Stream dataStream = request.GetRequestStream ();
    dataStream.Write (byteArray, 0, byteArray.Length);
    dataStream.Close ();
    WebResponse response = request.GetResponse ();
    MessageBox.Show(((HttpWebResponse) response).StatusDescription);
    dataStream = response.GetResponseStream ();
    StreamReader reader = new StreamReader (dataStream);
    string responseFromServer = reader.ReadToEnd();
    MessageBox.Show(responseFromServer);
    reader.Close ();
    dataStream.Close ();
    response.Close ();
}

...I had earlier tried this code, which I got from the book "Microsoft .NET Compact Framework":

public static void SendXMLFile2(string uri, string data)
{
    WebRequest req = WebRequest.Create(uri);
    req.Method = "Post";
    req.ContentType = "text/plain; charset=utf-8";
    byte[] encodedBytes = Encoding.UTF8.GetBytes(data);
    req.ContentLength = encodedBytes.Length;

    Stream requestStream = req.GetRequestStream();
    requestStream.Write(encodedBytes, 0, encodedBytes.Length);
    requestStream.Close();

    WebResponse result = req.GetResponse();
    MessageBox.Show(result.ToString());
}

...but I get "400 - Bad Request" with the new (as well as the old) code.

My initial attempt also does not work, with the same result (400):

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create(uri);
    myHttpWebRequest.AllowWriteStreamBuffering=false;
    string postData = "<Command><DSD><line_id>1</line_id><invoice_no>david_dsd</invoice_no>. . .</DSD></Command>"; // TODO: if this works, replace it with the real data
    myHttpWebRequest.Method="POST";
    UTF8Encoding encodedData = new UTF8Encoding();
    byte[]  byteArray=encodedData.GetBytes(postData);
    myHttpWebRequest.ContentType = "application/xml";
    myHttpWebRequest.ContentLength=byteArray.Length;
    Stream newStream=myHttpWebRequest.GetRequestStream();
    newStream.Write(byteArray,0,byteArray.Length);
    newStream.Close();
    HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();
    return myHttpWebResponse.StatusDescription;
}

There is much more about the plethora of variations I have tried here, where I have reached my length-of-post limit.

UPDATE

Note that the Server code doesn't know/care that the file is XML:

[HttpPost]
[Route("api/inventory/sendXML/{userId}/{pwd}/{filename}")]
public async Task SendInventoryXML(String userId, String pwd, String fileName)
{
    Task task = Request.Content.ReadAsStreamAsync().ContinueWith(t =>
    {
        var stream = t.Result;
        using (FileStream fileStream = File.Create(String.Format(@"C:\HDP\{0}.xml", fileName), (int)stream.Length))
        {
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    });
}

UPDATE 2

I tried Charles to see if it would pick up the local HTTP traffic, but it is also deaf to such (like Fiddler, without special ministrations, anyway). This is what Charles looks like after getting the "400 - Bad Request" error:

enter image description here

UPDATE 3

I found this suggestion somewhere to get Fiddler to show local HTTP traffic:

Tools--> Fiddler Options. Choose Connections tab. Check the 'USe PAC Script' option.

...but it didn't work - I still see no HTTP traffic when getting the "400 (Bad Request)" message.

UPDATE 4

I am now seeing "400 (Bad Request)" in Fiddler 2, too; to get it, I enter any of the following in Postman (don't see this in Fiddler when calling from CE/CF/handheld app):

http://SHANNON2:21608/api/inventory/sendXML/su/su/blablee // Hostname
http://SHANNON2.:21608/api/inventory/sendXML/su/su/blablee // Hostname with Fiddler-fooler appended "."
http://192.168.125.50:21608/api/inventory/sendXML/su/su/blablee // IP Address

(Fiddler does not capture anything if I replace the hostname or IP Address with "localhost")

Note: For these URLs in Postman, I have "Post" (as opposed to GET, etc.) selected, and an XML file attached.

Inspectors.Headers in Fiddler shows:

POST /api/inventory/sendXML/su/su/blablee HTTP/1.1

Although I consider this a minor debugging victory, I still don't see why I'm getting the "400" error.

Fiddler tells me, in the Inspectors.WebView pane:

Bad Request - Invalid Hostname

--------------------------------------------------------------------------------

HTTP Error 400. The request hostname is invalid.

How can that be? When I run it from Postman, I hit the breakpoint in the server - if the hostname is invalid, why is it being reached?

UPDATE 5

Testing the call from Fiddler Composer and Postman, the only way I can reach the breakpoint in the server code is by using "localhost" - replacing that with the PC's IPAddress (192.168.125.50) or HostName (SHANNON2) does not reach the breakpoint. While "interesting," calling "localhost" from the handheld device is obviously not an option.

UPDATE 6

Related new question here.

UPDATE 7

The crux of the biscuit was adding at the command prompt either this:

netsh http add urlacl url=http://shannon2:80/ user=everyone

...or this:

netsh http add urlacl url=http://shannon2:8080/ user=everyone

See Update 5 here for more details

like image 603
B. Clay Shannon-B. Crow Raven Avatar asked Sep 08 '14 17:09

B. Clay Shannon-B. Crow Raven


People also ask

How do I fix a bad request invalid hostname?

To resolve the issue, configure IWSVA not to overwrite the Host header: Open the /etc/iscan/intscan. ini configuration file of IWSVA and set “ProxyPreserveHost" to "yes". This prevents the proxy from overwriting the Host header of requests before forwarding them to the original server.

How do I fix HTTP error 400 the request hostname is invalid?

Double Check the Domain Address One of the most common causes of HTTP status 400 bad request error is a wrong URL. This may include a mistyped URL, malformed syntax, and illegal characters in the URL. It's easy to mistype a URL, so be sure to check the domain name spelling.

What does invalid host name mean?

If you're getting an "invalid hostname", it doesn't mean your DNS isn't responding... it (in all likelihood) means your DNS is responding to your DNS query with an NXDOMAIN which means no record for that hostname exists in the DNS zone.

Why is my postman 400 Bad Request?

The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).


1 Answers

Adding my observations, if you are facing the issue Bad Request - Invalid Hostname while calling the API from Postman. Something like this.

enter image description here

Consider adding the Host in Headers, it will work.

enter image description here

Updated after someone is not able to view the image: If the images are not loading, then basically this you have to do:

Basically, you have to add Content-Length and Host. Postman auto calculates when the request is sent. These can be enabled in postman by unhiding auto-generated headers in Postman. or you can set by your own.

like image 95
KushalSeth Avatar answered Sep 28 '22 07:09

KushalSeth