Can 'Clicky Web Analytics' be utilized in a C# WinForms environment?
The only thing I can spot is a HTML code snippet for websites.
They also accept HTTP requests, but I believe they are just for polling data, not for pushing new events/stats to Clicky.
I realize it is probably called 'Clicky Web Analytics' for a reason (i.e. only website/web app based stat tracking), but I could really use a C# solution right about now.
Here is how to track custom events from C# to your clicky site:
private static void TrackStatWithClicky(string eventValue)
{
// Prepare HTTP request
WebRequest request = WebRequest.Create
(
"http://in.getclicky.com/in.php?" +
"site_id=" + ClickySiteID + //click site id , found in preferences
"&sitekey_admin=" + ClickySiteAdminKey + //clicky site admin key, found in preferences
"&ip_address=" + GetLocalIPAddressString() + //ip address of the user - used for mapping action trails
"&type=custom" +
"&href=" + eventValue.Replace(" ", "_") + //string that contains whatever event you want to track/log
"&title=APPNAME Action" +
"&type=click"
);
request.Method = "GET";
// Get response
WebResponse response = request.GetResponse();
response.Close();
}
public static string GetLocalIPAddressString()
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
return "";
}
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
return host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
}
Some of the information here was usefull in figuring it out: https://clicky.com/help/custom/manual#internal
They appear to have an API for Manual data logging. Specifically, they mention Logging internal events:
Logging data from an internal script
Clicky lets you log data from an internal script, such as PHP, ASP, Perl, etc. Other services don't offer this feature because they don't document their incoming "API", and they only verify incoming data from the referrer. Clicky is different.
It seems to be really made for your backend webserver scripts to also contribute user data, but I'm pretty sure you could make the web API calls from whatever language you'd like, including a WinForms script. Not really what it's made for, but hey, why not? Just issue a GET request with the URL-encoded parameters:
How to talk to our tracking servers
The page you want to talk to is at http://in.getclicky.com/in.php. This is the same script that our tracking code talks to. You just need to send the right parameters, and we'll log it.
So you'll need to port their example PHP Script to C# and you'll be good to go.
Related
I know this is possible using Puppeteer in js, but I'm wondering if anyone has figured out how to proxy on a page level in PuppeteerSharp (different proxies for different tabs)?.
it seems I can catch the request, but I'm not sure how to adjust the proxy.
page.SetRequestInterceptionAsync(true).Wait();
page.Request += (s, ev) =>
{
// what to do?
}
Edit
I am aware that I can set the proxy at the browser level like so;
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
Args = new[] { "--proxy-server=host:port" }
});
var page = await browser.NewPageAsync();
await page.AuthenticateAsync(new Credentials() { Username = "username", Password = "password" });
But this is not what I'm trying to do. I'm trying to set the proxy for each page within a single browser instance. I want to test lots of proxies so spawning a new instance of the browser just to set the proxy is too much overhead.
You can use different browser instances for each logical instances. I mean instead of trying to set different proxy for each page/tab with different proxy just create new browser instance and set proxy via launch args.
If this solution doesn't fit your needs, check this question. There is library for NodeJS which give ability to use different proxy per each page/tab. You can check that library source code and implement same things inside your C# application.
That library is using very simple method. Instead of sending requests via puppeter's browser/page library send request via nodejs http tools. It can be done by using method page.setRequestInterception. So library intercept each request from page, after that gather data and send request via http tools. I used C# a long time ago. So maybe I am wrong, but you can try to use HttpWebRequest or something similar. After you get result you should use method request.respond and pass response results there. In this way you can put any kind of proxy inside your application. Check here code of library.
I am making a launcher for Minecraft. 1.6.2 changed a lot, so the way you login is different. If any of you have any knowledge of logging into minecraft using C#, I would appreciate it.
wClient.DownloadString("http://login.minecraft.net/?user=" + strUsername + "&password=" + strPassword + "&version=13");
I believe this used to be a valid way of doing it, but I am not quite sure anymore. Help is appreciated, thanks.
In reply to TheUnrealMegashark's comments to Rhys Towey's Answer. I have been working really hard to get it to launch, but. Its throwing me off a bit. The very next update will include a 1.6 fix. Just got to figure it out.
The proper answer to your question is that the web link that fetches the Session is still currently in use. Nothing new there.
Beware! You must know that your
"http://login.minecraft.net/?user=" + strUsername + "&password=" +
strPassword + "&version=13"
Is unsafe. It sends the password of the user through the internet in plain text. it can be subject to "Man in the Middle" attacks.
One of the proper ways to encrypt the connection is to use HTTPS with POST. Using POST, I avoid sending all of the data in the request URL and send the data through POST. Using HTTPS, I encrypt any data sent after the request URL returns. HTTPS makes POST encrypted, thus removing "Man in the Middle" attacks.
You can use GET with HTTPS and it still be secure (from what i have read). But, it is considered an unsafe practice. Although it is safe in all accounts between your computer and the connected device, anywhere else it might be seen and be subject to "Man behind you Attack". What I mean is that when you send this URL, it is possible for your computer to record the URL in some sort of history, or, display it in an address bar in plain text. Although, sense your not making a web browser and the URL is not displayed, this could possibly all be forgotten.
But, If it were me, I would still play it safe and just use the safer strategy.
To use HTTPS with POST.
Here is a sample of code i use in my "AtomLauncher." This code will send the POST data to the URL and return a string. Goto http://www.minecraftwiki.net/wiki/Minecraft.net to get more info on the string that is returned.
string mcURLData = "Error";
using (WebClient client = new WebClient()) // Get Data from Minecraft with username and password
{
// This a Text control for my Program, ignore this commented line if you wish.
// this.Invoke(new MethodInvoker(delegate { homeLabelTop.Text = "Connecting to Minecraft.net..."; }));
try
{
System.Collections.Specialized.NameValueCollection urlData = new System.Collections.Specialized.NameValueCollection();
urlData.Add("user", "UserName");
urlData.Add("password", "MYPa22w0rd");
urlData.Add("version", "13");
byte[] responsebytes = client.UploadValues("https://login.minecraft.net", "POST", urlData);
mcURLData = Encoding.UTF8.GetString(responsebytes);
}
catch
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
mcURLData = "Internet Disconnected.";
}
else
{
mcURLData = "Can't connect to login.minecraft.net.";
}
}
}
To use HTTPS with GET
just simply change the
http
in your code to
https
In other news.
I have fixed my code. Feel free (when its uploaded) to use it.
For your information, you need to know that when 1.6.X launches it creates a natives folder of which it starts using immediately. What I have done to fix this was to run 1.6.2 and copy the natives folder it created and removed the number.
Created "version/1.6.2/1.6.2-natives-###"
Copied it to "version/1.6.2/1.6.2.natives"
Point my program to "natives" folder I created.
What I'll end up doing in the future is automatically checking for the natives folder and if it doesn't exist, I'll have it download natives from the internet.
(I would love to know where minecraft is getting its current natives so i can essentially do the same thing. Unless, what it does is download it from the internet every time it launches. If true, that's kind of ugly. Seeing as I have bandwidth usage limits.)
This is a follow-up to Choosing a Connection String based on kind of request for which I got no answer and what I thought worked doesn't.
I have a webservice that needs to choose a specific connection string based on the user calling it from a browser or from a client application.
I tried:
HttpContext.Current != null? ConnectionStrings["Website"].ConnectionString : ConnectionStrings["Client"].ConnectionString
but realized that at some point even if I'm using the client application, there is some HttpContext (if someone can explain why it'd be great) but the Browser field under Request is "Unknown". So, then I tried:
if ( HttpContext.Current != null )
{
if ( HttpContext.Current.Request.Browser != "Unknown" )
{
//browser connection string here
}
else
//client app connection string here
}
else
//client app connection string here
This worked wonders when debugging, but on testing environment it still points to Browser connection string even when calling from the client app, as if at some point the Browser isn't "Unknown" ...
Is there a MUCH easier/simpler way to do this? The way I'm doing it seems really ugly.
I'm quite desperate at the moment as I have no idea why this is happening..
Rather than detecting and switching on the browser type, consider these two suggestions:
Add Custom Request Headers
In your various callers, define a new custom header in your Http request.
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("CallerType", "ClientApp"); // "Browser", etc.
Then you know exactly and reliably what type of client is calling. This would be hard to get wrong, and couldn't be spoofed/mistaken.
Include The Caller Type in the QueryString
myService.asmx?BrowserType=1
Add a simple new querystring parameter to your .asmx webmethod. This will work just the same in a controlled environment, but if other users/developers get it wrong, or malform the expected values, you'd have to take other measures to correct/handle.
Both allow you to easily determine the connString on the incoming value. Perhaps the absense of a modifier/header, you could assume a default. Your sample question has 2 basic outcomes, and either suggested solution will be easy to extend (browser, client app, iPhone, whathaveyou).
I need to get the free Google charts working over SSL without any security errors. I am using c# and asp.net.
As Google charts does not support SSL by default, I am looking for a robust method of using there charts but ensuring my user doesn't get any security warnings over their browser.
One thought was to use a handler to call the charts api and then generate the output my site needs.
Similar to Pants are optional blog post. I haven't been able to get this example working at this stage.
Any suggestions, or samples are welcome.
Thanks
the Google Charts API is now available over HTTPS at via https at chart.googleapis.com.
Source: http://www.imperialviolet.org/2010/11/29/charthttps.html
We do this automatically in the NetQuarry Platform - it's pretty simple, although you do force the image to come through your site vs. charts.google.com, making your browser run the request through a single connection.
Since a chart is just a link to an image, what we do is to build the link to the chart (a much more complex process, obviously), then add the whole link to the query string on an internal handler (handler.ashx?req=chart& ). So the new link looks like this:
handler.ashx?act=chrt&req=chart&cht=p3&chs=450x170&chd=s:HAR9GBA&chl=New|In%20Progress|Responded|Won't%20Respond|On%20Hold|Future|Review|&chg=20,20,1,5&chg=10,25,1,5&chco=0A477D
Then, we simply download the image data and write it back as the response.
Here's the code:
Blockquote
private void GoogleChart(HttpContext cxt)
{
const string csPrefix = "?act=chrt&req=chart&";
HttpRequest req = cxt.Request;
HttpResponse rsp = cxt.Response;
string sUrl = cxt.Request.RawUrl;
int nStart = sUrl.IndexOf(csPrefix, StringComparison.OrdinalIgnoreCase);
rsp.Clear();
if (nStart > 0)
{
sUrl = "http://chart.apis.google.com/chart?" + sUrl.Substring(nStart + csPrefix.Length);
System.Net.WebClient wc = new System.Net.WebClient();
byte[] buffer = wc.DownloadData(sUrl);
cxt.Response.ClearContent();
cxt.Response.ClearHeaders();
cxt.Response.ContentType = "application/octet-stream";
cxt.Response.AppendHeader("content-length", buffer.Length.ToString());
cxt.Response.BinaryWrite(buffer);
}
}
I Have a partial solution that has one issue.
here is the link to my new post asking for help with a specific problem regarding my solution
My Attempt at a SSL handler
I'm looking for ways to detect/estimate the country from which a http-request is coming in ASP.NET.
I know there are some solutions with services/country lookups but I never used one.
I'm looking for small/clean solutions.
It's for helping someone filling out a form so it does not have to be 100% accurate.
Thanks in advance..
You can make a simple HTTP request to this URL:
http://api.hostip.info/get_html.php?ip=207.46.197.32
using the value of the REMOTE_ADDR server variable. That will return the country and city like this:
Country: UNITED STATES (US)
City: New York, NY
I use that service for a web form just as you describe. Occasionally it doesn't know the answer, but usually it's very good (and it's free and simple 8-)
In C#, you can use System.Net.WebRequest.Create to read from the URL.
You can use one of available web services to match an incoming request to a country.
Otherwise you may decide to grab the MaxMind database file (GeoLite Country), read from this file in your application and perform a match. Thus you will be independent from a third-party service, only pulling regularly updates for the database file.
Also check out similar questions:
Geolocation web service recommendations
Know a good IP address Geolocation Service?
If you choose to use the REMOTE_ADDR server variable, you can be fairly certain that the IP that you recover accurately represents the nation of origin of that user. It is fairly uncommon for a user to be accessing the Internet from outside of the country that he is currently in, with a few notable exceptions, such as those who choose to surf though an anonymous proxy server, such as is discussed below. If, however, you want to get the state that a user is coming from, or authenticate the identity of a user, you're out of luck as far as any even remotely reliable method is concerned.
More info here.
This is what I've used:
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
'url': 'http://www.freegeoip.net/json/#(HttpContext.Current.Request.UserHostAddress)',
'type': 'GET',
'success': function(data) {
// for example
if (data.country_code === "GB") {
... further logic here
}
}
});
});
</script>
Simple, and it works.
I just had to do this so here's a working example (specific to France) which may be of use to someone:
string userIP = Request.ServerVariables["REMOTE_ADDR"];
string localeAPIURL = "http://api.hostip.info/get_html.php?ip=" + userIP;
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(localeAPIURL);
r.Method = "Get";
HttpWebResponse res = (HttpWebResponse)r.GetResponse();
Stream sr = res.GetResponseStream();
StreamReader sre = new StreamReader(sr);
// check response for FRANCE
string s = sre.ReadToEnd();
string sub = s.Substring(9, 6);
if (sub == "FRANCE")
{
Response.Redirect("http://fr.mysite.com");
}