Friday, May 17, 2013

testing if an http client support cookies via php

Cookies! Such a fundamental part of sessions on the web!

If you're making a little client for http things, like on a mobile device, and you're like me, then you might want to run a test to make sure the system you're using is properly configured to use cookies.

http://nik.chankov.net/2010/01/16/detecting-if-the-cookies-are-enabled-with-php/ is a start, but the example program both 1. assumes it's called "info.php" at the root of the site, 2. requires the client to follow location changes in the header style redirects and 3. you probably still might need a server to put it on.

So I made http://kirk.is/tools/testcookies/redirect.php -- its content is
<?php
setcookie('test', 1, time()+3600);

if(!isset($_GET['cookies'])){
    header('Location:redirect.php?cookies=true');
}

if(count($_COOKIE) > 0){
    echo "YES";
} else {
    echo "NO";
}
?>
If your client has cookies enabled AND can follow the redirect, it will return YES, or else NO.

But the redirection following is kind of an arbitrary requirement, so I have also made http://kirk.is/tools/testcookies/set.php to set a cookie:
<?php
setcookie('foo', 'bar', time()+(86400*7));
?>SET COOKIE
 and http://kirk.is/tools/testcookies/get.php to return YES or NO if it could read that cookie:
<?php
if($_COOKIE['foo'] == 'bar'){
echo "YES";
} else {
echo "NO (".$_COOKIE['foo'].")";
}
?>

Please note that results are best the first time you run it, subsequent runs may be letting you see old cookies. (Hmm, maybe I should expire the cookies once they're read?)

Anyway, I used curl to test this, and learned the default settings of curl don't support cookies or redirection, so I was getting a lot of false negative results.

The line I ended up with is
curl -L -b cookies.txt -c cookies.txt http://kirk.is/tools/testcookies/FILENAME.PHP

The -L follows any location changes, the -b lets it use an old cookie file (i.e. a text file on the local system it will store the cookies in) and -c writes out the cookies that occured in that session. Those are 3 things a typical browser is always doing, and a small http client might or might not do.

Thursday, May 16, 2013

css munging in jquery

jQuery obviously has many tools for manipulating the css styles of individual items and classes of items, but sometimes you just want to glom some stuff as a tag of css so it applies to new stuff as well.
The stackoverflow page jQuery create CSS rule / class @ runtime has some decent solutions. My favorite is:
    $("<style>")
    .prop("type", "text/css")
    .html("\
    #my-window {\
        position: fixed;\
        z-index: 102;\
        display:none;\
        top:50%;\
        left:50%;\
    }")
    .appendTo("head");
Admittedly, I was doing fancier stuff to put into the .html tag (so all the string continues on next line slashes weren't needed) but still, it got the job done.

osx terminal/unix shell protip: get a calendar

Most Unix-y systems will show you a calendar for the current month if you type "cal" at the prompt... or type "cal 2013" or whatever for the full year. Slightly faster than Google, IMO. (Almost as good as figuring out the view on your cellphone I guess.)

Tuesday, May 14, 2013

converting wonky wavs to mp3s in the osx terminal commandline via sox and lame

SoX (Sound eXchange) is a promising, mutliplatform commandline tool but like too many open source projects it makes life a pain in the ass if you want to output MP3s (because of potential licensing blah blah blah). (Audacity, the general standard for audio editing for cheapskates, has a cleaner way of enabling MP3 support but it's not really usable as a commandline tool.)

Trying to get SoX running with MP3 support proved beyond me:
1. The default download doesn't have it.
2. "Sox Wrap", a UI for withs own version of SoX won't do it, outputting a 0-byte file
3. I installed "Homebrew", a tool for installing extra software on OSX. I hoped "brew install sox --with-libmp3lame" or "brew install sox --with-mad --with-lame" might do it, but no. (troublingly, I can put --with-anystupidname and homebrew doesn't report that as a problem, so I have no way of knowing if the '--with's are working.)
4 I tried to follow the instructions at http://ggkarman.de/tech/building-sox-with-mp3-support-on-osx/ I'm not 100% sure I'm downloading the right tarballs, but when I tried to compile the sox part with --with-mad --with-lame it tells me can't find libmad, and I haven't done enough with compiling to know what I'm doing wrong.

So, the solution turned out to be downloading LAME (which besides providing libraries for other programs also has its own commandline tool) and then doing a two step process:
sox wonky.wav -b 16 better.wav
lame better.wav --preset medium better.mp3
(Sox is  much better at reading the wonky wav file, so it still has to be in the loop.)



minimal soundmanager2 quickstart

I'm proud of lowLag.js but sometimes it's overkill when you just want the flexibility SoundManager2 provides. I think I've isolated the 2 files and boilerplate code you need to just play a sound.

Copies of the files are available here: one .js and the Flash fallback. (I admit I've had some problems trying to specify alternate locations for the Flash, so it's safest to put that file in the same directory as the page itself.) So put "soundmanager2.js" and "soundmanager2_debug.swf" in the folder as the file, add
<script src="soundmanager2.js"></script>
and then in add something like
<script>
soundManager.setup({
    useHighPerformance:true, 
    onready:sm2Ready ,
    debugMode: true,
}
);

function sm2Ready(){
    soundManager.createSound({
        id: "asphault",
        autoLoad: true,
        url: "asphault.mp3"
    });
};

function sm2play(){
    soundManager.play("asphault");
}
</script>
That's it! You can see it in action. The code is a little complex because you need a callback to create the sounds after SM2 says it's ready. (There's also an "experimental feature" where the argument to url in createSound({}); can be an array of different files, if you're trying to support browsers that might not support every file format.)

(Of course for real work you should probably go to the SoundManager2 website and grab the latest files and read the documentation... this page is just for when you're in a hurry.)

Friday, May 10, 2013

OSX PROTIP: mouse-based cursor positioning in Terminal

One of the drawbacks to, say, running emacs on a remote system to edit a file via ssh was that you lost cursor positioning via mouse. NOT TRUE! On OSX, holding the option key and clicking is able to reposition the cursor, even in a crazy beast like emacs.

webscraping in PHP 101

Recently I had to make a "webscraper" web service to present a simple interface to a rather complex login and settings change for a 3rd party website that was not set up as a webservice.

A few things learned: one is http://www.hurl.it/  is a pretty cool tool for hitting faking web requests. It had some options to view each step of a login process that had a lot of redirects, and we could see where automated javascript even got in the mix.

The key turned out to be grepping out the jsessionid and using that, and the other key was not trying to skips steps in the redirection, even if they seemed like they shouldn't affect attempting to login (also, clearly printing out the response at each step was helpful, being a bit formal about it.)

We selected PHP for this. Initially I tried to get us to Perl, where I wouldn't have to look up how to do every simple task, but the LWP library was segfaulting (maybe confused by having to make the https requests? Not sure, but it wasn't worth dwelling on)

I don't like PHP... I first tried to use it in the early-2000s, where it was kind of a beta-feeling project, and it has never felt fully baked to me. Unlike Perl which has odd syntaxes that reflect its history but always feels rock-solid and with damn few "oh, Perl is this way because that was easier for the implementor of Perl to write it", PHP still feels like the Preprocessor-for-Perl that it started as. It also has a "Guess What I Mean" philosophy I don't trust... for example, the standard curl functions I used by default blast the result of the request to stdout. While I admit this may be a fairly common use case, the more Unix-ish way of doing it would be to just return the value, and then the programmer can trivially print out that result if they want.

Anyway, for future reference, here's what a POST ended up looking like in PHP
function doPOST($url,$payload){
  print "<h1>POST to $url with $payload</h1>\n";
  //open connection
  $ch = curl_init();
  //set the url, number of POST vars, POST data
  curl_setopt($ch,CURLOPT_URL, $url);
  curl_setopt($ch,CURLOPT_POST, 1);
  curl_setopt($ch,CURLOPT_POSTFIELDS, $payload);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
#  curl_setopt($ch, CURLOPT_VERBOSE, 1);
  curl_setopt($ch, CURLOPT_HEADER, 1);

  $response = curl_exec($ch);
//get the header as separate from the body
  $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  $header = substr($response, 0, $header_size);
  $body = substr($response, $header_size);
  curl_close($ch);
  print "<hr>$header<hr>".htmlentities($body)."<hr><hr>";
  return $header;
}
The $payload param should be url encoded key1=val1&key2=val2 type data.... (In both iOS programming and here, I'm surprised making the coders do the encoding themselves and sending the POST raw like that is the more common option.)

Tuesday, May 7, 2013

quick ref for future self: old school servet and jsp pairing

The other week I was converting some servlets that had a lot of embedded HTML to Servlet/JSP pairs (a preferred mutant MVC variant I like called "Model 2 Plus".) So a few notes to when I have to do that again (these were from a sticky I left to make a blog entry about, hence less haphazard nature of the examples.)

In the servlet, I wanted to put some information (a ContactList instance named contacts) into the request for later retrieval:

req.setAttribute("contacts", contacts);
RequestDispatcher dispatcher = 
        getServletContext().getRequestDispatcher("/admin/test.jsp");

dispatcher.forward(req,resp);

Then telling the JSP about the object:
 <%@ page import="com.mycompany.util.ContactList" %>
and later to loop over it:
<TABLE>
<%
ContactsList contacts = (ContactsList)request.getAttribute("contacts");
for (int i=0;i<contacts.size();i++) {
Contact contact = contacts.get(i);
%>
<TR>
<TD><%= contact.getID() %></TD>
<TD><%= contact.getName() %></TD>
</TR>
<% } %>

I guess I felt more comfortable with the "do flaps" ( <% %> that execute code) and the "show flaps" ( <%=  %> that show a value) then using one of the taglibs-- yeah, having code embedded in HTML is a bit rough and less "pure", but A. I actually LIKE that my code looks/smells different than my looping markup, B. I kind of dislike having two ways of saying something, and C. I prefer to have fewer moving parts... I really liked how old school JSPs got precompiled directly into servlets, and how you could even crack open the intermediate generated servlets and see how things got translated.