Why is my Windows CE device unable to successfully invoke my server's REST methods?

1.1k views Asked by At

This is related/sort of a followup to this question but contains more and more specific information.

I have a REST app running on my PC. I need to call some of the methods on the server from a handheld WindowsCE device that uses the compact framework.

I can contact the server's methods from Postman, so it's not a problem that way. In Postman, I use:

http://localhost:21609/api/inventory/sendXML/duckbill/platypus/bloo

...and with this I reach the breakpoint in this REST method on my server app:

[HttpPost]
[Route("api/inventory/sendxml/{userId}/{pwd}/{filename}")]
public async Task SendInventoryXML(String userId, String pwd, String fileName)

However, although using "PPP_PEER" is the way to contact the PC from the handheld device (127.0.0.1 doesn't fly, because the handheld sees that as being itself, and commits egregious acts of cannibalism when trying to contact that address) - as can be seen by this TCP code that does work from the handheld device:

string pingString = "PING|";
TcpClient client = new TcpClient("PPP_PEER", 7727);
try
{
    try
    {
        Stream s = client.GetStream();
        StreamReader sr = new StreamReader(s);
        StreamWriter sw = new StreamWriter(s) { AutoFlush = true };
        String response = String.Empty;

        if (firstRecord)
        {
            sw.WriteLine(pingString);
            . . .

...trying to use PPP_PEER to call the REST method fails.

Here is the code I use to try to do that:

    //HHSConsts
    public static string BASE_REST_URL = "http://PPP_PEER:21609/api/";

    . . .

    //frmMain
    private void SendInventories()
    {
        try
        {
            foreach (String tblname in listBoxWork.Items)
            {
                String xmlData = hhsdbutils.GetINVDataAsXMLFromTable(tblname, fileName);
                String uri = String.Format("{0}inventory/sendXML/duckbill/platypus/{1}",
HHSConsts.BASE_REST_URL, fileName);
                fileXferImp = HHSConsts.GetFileTransferMethodology();
                fileXferImp.SendDataContentsAsXML(uri, xmlData, tblname);
                . . .

// FileXferREST.cs
public void SendDataContentsAsXML(String destinationPath, String data, String fileName, 
String siteNumber, bool firstRecord, bool lastRecord)
{
    SendHTTPRequestNoCredentials(destinationPath, HttpMethods.POST, data, "application/xml"); 
}

public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, 
string data, string contentType)
{
    WebRequest request = WebRequest.Create(uri);
    try
    {
        request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
        request.ContentType = contentType;
        ((HttpWebRequest)request).Accept = contentType;
        ((HttpWebRequest)request).KeepAlive = false;
        ((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;

        if (method != HttpMethods.GET && method != HttpMethods.DELETE)
        {
            byte[] arrData = Encoding.UTF8.GetBytes(data);
            request.ContentLength = arrData.Length;
            using (Stream oS = request.GetRequestStream())
            {
                oS.Write(arrData, 0, arrData.Length);
            }
        }
        else
        {
            request.ContentLength = 0;
        }
    }
    catch (WebException webex)
    {
        HttpWebResponse hwr = (HttpWebResponse)webex.Response;
        HttpStatusCode hsc = hwr.StatusCode;
        String webExMsgAndStatusCode = String.Format("{0} Status code == {1}", webex.Message, 
hsc.ToString());
        ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FileXferREST.SendHTTPRequestNoCredentials: {0}", webExMsgAndStatusCode));
    }
    return request as HttpWebRequest;
}

No exception is thrown; it simply doens't work.

When attempting this call, I run rawcap to capture the packages being sent over the network with these command line args:

rawcap 127.0.0.1 [fileName].pcap

I then open the .pcap file in Wireshark, search for "21609" and get this TCP stream:

enter image description here

...I added the screen shot above to show the red/blue coloration for the request/response, but here is the entire rawcap/Wireshark conversation involving port 21609:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

POST /api//inventory/sendXML/duckbill/platypus/INV_3_20090307181658000.xml HTTP/1.0 Content-Type: application/xml Accept: application/xml Connection: Close Content-Length: 388 Host: ppp_peer:21609

112209003343742SOME DESC2.2testVendorID]6161.51.995.58HTTP/1.1 404 Not Found Cache-Control: private Content-Type: text/html; charset=utf-8 Server: Microsoft-IIS/8.0 X-SourceFiles: =?UTF-8?B?QzpccHJvamVjdFxnaXRcQ1N0b3JlXEhIUy5BUElcYXBpXGludmVudG9yeVxzZW5kWE1MXGR1Y2tiaWxsXHBsYXR5cHVzXElOVl8zXzIwMDkwMzA3MTgxNjU4MDAwLnhtbA==?= X-Powered-By: ASP.NET Date: Thu, 18 Dec 2014 17:23:01 GMT Connection: close Content-Length: 5016

IIS 8.0 Detailed Error - 404.0 - Not Found

HTTP Error 404.0 - Not Found

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable. Most likely causes:
    .
  • The directory or file specified does not exist on the Web server.
  • .
  • The URL contains a typographical error.
  • .
  • A custom filter or module, such as URLScan, restricts access to the file.
Things you can try:
    .
  • Create the content on the Web server.
  • .
  • Review the browser URL.
  • .
  • Check the failed request tracing log and see which module is calling SetStatus. For more information, click here.
Detailed Error Information: Module   IIS Web Core Notification   MapRequestHandler Handler   StaticFile Error Code   0x80070002 Requested URL   http://ppp_peer:21609/api/inventory/sendXML/duckbill/platypus/INV_3_20090307181658000.xml Physical Path   C:\project\git\CStore\HHS.API\api\inventory\sendXML\duckbill\platypus\INV_3_20090307181658000.xml Logon Method   Anonymous Logon User   Anonymous Request Tracing Directory   C:\Users\clay\Documents\IISExpress\TraceLogFiles\HHS.API More Information: This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.

View more information »

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

So to recap, "PPP_PEER" does work as a way for the handheld device to describe/contact the PC (it works with the TCP code), and the REST method is reachable from another process (such as Postman), but trying to call the method using PPP_PEER from the handheld device fail with the "404.0 - Not Found" error.

Why?

UPDATE

When I replace "PPP_PEER" with the machine name of the PC, the error changes from "404 - Not Found" to "503 - Service Unavailable":

enter image description here

But that is a bit of a rompecabeza, because the service is obviously available, as it is running and its breakpoint is hit when I call it from Postman.

UPDATE 2

Now this is odd: If I use the full machine name instead of just the "truncated" name, the error goes back to being 404 instead of 503:

enter image description here

So if I use PPP_PEER as the host name, I get a 404; if I use shannon2, I get a 503; if I use shannon2.sscs.ad, I again get 404. Should I blame this on Tim Berners-Lee, Al Gore, Andy Warhol, or someone else?

SO...those are my results on trying to follow Eric Law's first suggestion; there are two others, but: what would I edit the Host header to that might make a difference? Or overwrite it to what?

1

There are 1 answers

0
B. Clay Shannon-B. Crow Raven On BEST ANSWER

It seems as if the basic problem is trying to access a "server" app running locally on my PC (even though the handheld != the PC, it is "sort of" the same thing, after a fashion).

Now that the server app is running on a different machine on the network altogether, I'm able to hit it; albeit not yet totally unexceptionally, as can be seen here.