public static bool SendPingback(Uri source, Uri target, Uri pingbackUri, Action <string> logError, out int errorCode, out string serverMessage) { HttpRequestUtil http = new HttpRequestUtil(pingbackUri); string xmlrpc = @"<?xml version=""1.0""?><methodCall><methodName>pingback.ping</methodName><params>" + @"<param><value><string>{0}</string></value></param>" + @"<param><value><string>{1}</string></value></param></params></methodCall>"; xmlrpc = String.Format(xmlrpc, HttpUtility.HtmlEncode(source.AbsoluteUri), HttpUtility.HtmlEncode(target.AbsoluteUri)); byte[] postdata = Encoding.UTF8.GetBytes(xmlrpc); if (http.Post(pingbackUri.PathAndQuery, "application/xml", postdata, postdata.Length) != HttpStatusCode.OK) { logError(String.Format("POST {0}: {1}/{2}", pingbackUri, (int)http.StatusCode, http.StatusCode)); errorCode = (int)http.StatusCode; serverMessage = "The server returned an http error " + (int)http.StatusCode; } else { if (!http.ContentType.StartsWith("text/xml", StringComparison.OrdinalIgnoreCase) && !http.ContentType.StartsWith("application/xml", StringComparison.OrdinalIgnoreCase)) { logError("Expected content type: application/xml, found: " + http.ContentType); } try { XmlLightDocument doc = new XmlLightDocument(Encoding.UTF8.GetString(http.Content)); XmlLightElement error = doc.SelectSingleNode("methodResponse/fault"); if (error != null) { XmlLightElement faultCode = error.SelectSingleNode("value/struct/member[name/text()='faultCode']/value/int"); XmlLightElement faultString = error.SelectSingleNode("value/struct/member[name/text()='faultString']/value"); if (faultCode == null || !int.TryParse(faultCode.InnerText, out errorCode)) { errorCode = 0; } serverMessage = faultString != null ? faultString.InnerText : "Unknown Error"; } else { serverMessage = doc.SelectRequiredNode("/methodResponse/params/param/value").InnerText; errorCode = 0; return(true); } } catch (Exception e) { logError("Error parsing response: " + e.Message); serverMessage = "Unable to parse xml response."; errorCode = 0; } } return(false); }
public IContentResponse Post(string method, string rawUrl, NameValueCollection headers, Stream inputStream) { try { try { Assert("POST", method); Assert("application/xml", headers["Content-Type"]); if (int.Parse(headers["Content-Length"]) > 4096) { throw new ArgumentException("Content exceeds limit of 4096 bytes."); } string xmessage; using (TextReader rdr = new StreamReader(inputStream, Encoding.UTF8, false)) xmessage = rdr.ReadToEnd(); XmlLightDocument doc = new XmlLightDocument(xmessage); Assert("methodCall", doc.Root.LocalName); Assert("pingback.ping", doc.SelectRequiredNode("/methodCall/methodName").InnerText); XmlLightElement[] args = doc.Select("/methodCall/params/param").ToArray(); if (args.Length != 2) { throw new ArgumentException("Invalid number of arguments, expected: 2"); } Uri source, dest; if (!Uri.TryCreate(args[0].InnerText, UriKind.Absolute, out source) || !Uri.TryCreate(args[1].InnerText, UriKind.Absolute, out dest)) { throw new ArgumentException("Invalid uri format."); } RecordPingback(source, dest); return(new DynamicResponse("application/xml", Encoding.UTF8.GetBytes(@"<?xml version=""1.0""?><methodResponse><params><param><value>Accepted</value></param></params></methodResponse>") )); } catch (ArgumentException e) { return(new DynamicResponse("application/xml", Encoding.UTF8.GetBytes( String.Format( @"<?xml version=""1.0""?> <methodResponse> <fault> <value> <struct> <member><name>faultCode</name><value><int>{0}</int></value></member> <member><name>faultString</name><value><string>{1}</string></value></member> </struct> </value> </fault> </methodResponse>", 0, HttpUtility.HtmlEncode(e.Message))))); } } catch (Exception err) { Log.Error(err); return(HttpErrorHandler.InternalServerError.GetResponse(method, rawUrl, headers, inputStream)); } }