0

I have some other posts where I've been working with posting data to a UPnP printer. Basically creating a control point from scratch (this is still POC and I'll be implementing across multiple device types so I'm trying to get basic understanding first). So far I'm able to discover the printer, request a print job and get back a data sink url to post the content to be printed. At this point I attempt a POST with simple xhtml data, but the request seems to time out every time with the following exception:

The remote server returned an error: NotFound.
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)

If I hit the url in the browser, I get back HTTP 405 Method Not Allowed

I'm wondering if the server is ignoring the post due to bad data, or I'm missing headers or something along these lines.

I've already gone through the docs on upnp.org for the Printer Basic service, along with SOAP 1.1 UPnP Profile, both of which greatly helped get as far as I have.

does anybody have any thoughts?

Here's a copy of my xhtml:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML-Print 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-print10.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
  <head>
    <title>test</title>
  </head>
  <body>
    <div>hello world</div>
  </body>
</html>

I'm using C# to create and send a HttpWebRequest. Here is the code that does that (I have a couple variations, another using WebClient)

    private void SendToPrinter(string printUri, string content)
    {
        var request = WebRequest.Create(new Uri(printUri)) as HttpWebRequest;
        request.Method = "POST";
        request.ContentType = "text/xml; charset=\"utf-8\"";
        request.ContentLength = content.Length;
        request.Headers[SoapHeaderName] = CreateJobHeader; // this probably isn't necessary

        request.BeginGetRequestStream(ar => 
        {
            var requestStream = request.EndGetRequestStream(ar);
            using (var sw = new StreamWriter(requestStream))
            {
                sw.Write(content);
                sw.Close();
            }

            request.BeginGetResponse(a =>
            {
                var response = request.EndGetResponse(a);
                var responseStream = response.GetResponseStream();
                using (var sr = new StreamReader(responseStream))
                {
                    var results = sr.ReadToEnd();
                }

            }, null);

        }, null);
    }

raw post data from fiddler

POST http://10.20.201.90/upnp/print/1d153438-1e90-1f0b-8b54-984be15df0fe HTTP/1.1
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:device:Printer:1#SendDocument"
Host: 10.20.201.90
Content-Length: 482
Expect: 100-continue

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;s:Envelope xmlns:s=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&lt;s:Body&gt;&lt;u:SendDocument xmlns:u=&quot;urn:schemas-upnp-org:device:Printer:1&quot;&gt;&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;head&gt;&lt;title&gt;test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;div&gt;hello world&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&lt;/u:SendDocument&gt;&lt;/s:Body&gt;&lt;/s:Envelope&gt;
earthling
  • 5,084
  • 9
  • 46
  • 90
  • Is the stray `"` after the closing html tag a typo? Are you remembering to escape the xhtml if its inside a SOAP messsage. If neither of these help, can you show the entire POST (i.e. HTTP headers + SOAP message as well as xhtml)? – simonc Sep 25 '13 at 21:56
  • trailing quote was a type. I'll update the question with my request data. – earthling Sep 26 '13 at 19:55
  • You haven't shown the request body. What is the value of `content` in `SendToPrinter`? Are you formatting it as a SOAP message? – simonc Sep 26 '13 at 21:53
  • It's the xhtml under the request object. I'm playing around with different formats now so it's continually changing. I have it wrapped in a soap Envelope at the moment – earthling Sep 26 '13 at 22:04
  • You need to escape the xhtml before inserting it into the soap envelope. This means that the xhtml will end up getting escaped twice. – simonc Sep 26 '13 at 22:32
  • I've tried escaping it, and escaping it twice. The results don't change. I don't believe that is the issue. Composing the SOAP message could be, but probably not escaping it. I found in the Bluetooth Spec (which is similar) a `SendDocument` action which follows `CreateJob`. I tried using this as my action with no luck, but it makes me think there might be another _soap action_ that I haven't found for sending the actual print content. – earthling Sep 26 '13 at 23:03

1 Answers1

0

One issue that kept me from printing was that the printer was set to ask which tray to print from. This blocked the message from being printed. Here's the final SOAP message. I did not escape it.

<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">
  <s:Body>
    <html xmlns=\"http://www.w3.org/1999/xhtml\">
      <head><title>test</title></head>
      <body><div>hello world</div></body>
    </html>
  </s:Body>
</s:Envelope>
earthling
  • 5,084
  • 9
  • 46
  • 90