Hey there, trying to use C# WebRequest class to send a simple search (via POST to get the sid then GET to get the results) and I can't get the first step to work. I either seem to get 401 Not Authorized (but it works via curl cmdline), or 400 Bad Request, depending on how I pass the authentication. I've tried every combination I can think of. Oh, and using the SDK is not an option.
Here's the code that posts the search, using my custom class WebAPI (a simple wrapper) which I will provide code for later:
WebAPI api = new WebAPI();
api.Trust(); // we trust our local splunk server (this disables SSL certificate checking!!!)
string username = "<removed>";
string password = "<removed>";
string scheme = "https";
string address = "169.00.000.168";
uint port = 2711;
string path = "/services/search/jobs";
string post_content = "search=\"search index=mmogbrain sourcetype=dreadnought_profile host=DN-GL-MM-000 earliest=-1m@m latest=now|table _time,connections\"";
string url = api.BuildUrl(scheme, address, port, path, null);
string result = api.Post(url, content, username, password);
Here's the code for WebAPI helper class:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
namespace SixFoot.Core
{
public class WebAPI
{
public void Trust()
{
ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
}
public void Post(string url, string content)
{
Post(url, content, null, null);
}
public string Post(string url, string content, string username, string password)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(content);
request.ContentLength = byteArray.Length;
if (username != null && password != null)
{
string authInfo = username + ":" + password;
authInfo = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;
}
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
string message = ex.Message;
WebResponse errorResponse = ex.Response;
if (errorResponse != null)
{
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
message = reader.ReadToEnd();
}
}
throw;
}
}
public Dictionary<string, object> ParseJson(string json)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return (Dictionary<string, object>) serializer.DeserializeObject(json);
}
public string BuildUrl(string scheme, string address, uint port, string path, string query)
{
UriBuilder builder = new UriBuilder(scheme, address, (int) port);
builder.Path = path;
builder.Query = query;
return builder.Uri.AbsoluteUri;
}
// snip removed similar Get methods...but I'm no getting that far. ;-(
}
}
Any thoughts? The above code returns "401 Bad Request". Posting the exact same strings via curl works and returns a sid.
Thanks in advance for any help...
... View more