?

Log in

No account? Create an account
A post in my journal with Perl. - LiveJournal Client Discussions [entries|archive|friends|userinfo]
LiveJournal Client Discussions

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

A post in my journal with Perl. [Oct. 17th, 2004|09:24 pm]
LiveJournal Client Discussions

lj_clients

[djdavejumpers]
Hi,
I'm trying to write something simple in Perl, to post a private message in my journal.
Is not working for me, though.

This is what I have done so far:

#!/usr/bin/perl -w
use IO::Socket::INET;
$MySocket=new IO::Socket::INET->new(
PeerPort=>80,
Proto=>'tcp',
PeerAddr=>'livejournal.com');

$msg="POST /interface/flat HTTP/1.0
Host: www.livejournal.com
Content-type: application/x-www-form-urlencoded
mode=postevent&user=LJUSER&password=LJPASSWORD&event=yomama+is+phat&security=private";
$MySocket->send($msg);
exit;


I tried just telnet www.livejournal.com and pasting $msg, and the connection gets' closed.
Am I missing something?
Also, how would you implement this, so that the password is not sent in clear text?.

I read http://www.livejournal.com/doc/server/ljp.csp.flat.postevent.html but says that password is Deprecated?
I'm confused.

Perhaps one of you can give me an example on what to put on that line that starts with "mode"

Thanks
-Dave-
linkReply

Comments:
[User Picture]From: hythloday
2004-10-18 11:09 am (UTC)
I believe you need a content-length header.
(Reply) (Thread)
From: wombat
2004-10-18 11:13 am (UTC)
Before looking at details, I can tell you that it won't work unless you add an empty line between the HTTP headers and the body (mode=... line).
(Reply) (Thread)
(Deleted comment)
[User Picture]From: vanbeast
2004-10-18 11:37 am (UTC)
Damn, you beat me to the LWP::UserAgent suggestion, but that's because I was whipping up...

#!/usr/bin/perl -w

use strict;
use LWP;

my $ua = LWP::UserAgent->new;
my $url = "http://www.livejournal.com/interface/flat";

my $msg = "yo+momma+is+phat";
my $sec = "private";
my $user = "LJUSER";
my $pass = "LJPASS";

my ($min, $hour, $day, $mon, $year) = (localtime)[1,2,3,4,5];

# year is $CALENDARYEAR - 1900
$year += 1900;

# month is 0-based
$mon++;

my $content = "mode=postevent&user=$user&password=$pass&event=$msg&security=$sec&year=$year&mon=$mon&day=$day&hour=$hour&min=$min";

my $resp = $ua->post($url, content=>$content);


:)
(Reply) (Parent) (Thread)
[User Picture]From: djdavejumpers
2004-10-18 11:41 am (UTC)
word thanks!
(Reply) (Parent) (Thread)
[User Picture]From: vanbeast
2004-10-18 11:43 am (UTC)
no problem :)

Obviously, this is quick-and-dirty and could use improvement, but it does work!

I must emphasize what others said, too: don't be tempted to do your own HTTP handling when there are good modules that do it for you :)
(Reply) (Parent) (Thread)
[User Picture]From: lordindra
2004-10-18 12:02 pm (UTC)
don't be tempted to do your own HTTP handling when there are good modules that do it for you :)

Thats one thing I love about Perl. 90% of any program I'm likely to write is already written for me, I just have to string a couple modules together and I'm done.

Ok, maybe its not quite that simple, but its pretty close.
(Reply) (Parent) (Thread)
[User Picture]From: djdavejumpers
2004-10-18 12:16 pm (UTC)
how do I make this use md5 password?
(Reply) (Parent) (Thread)
[User Picture]From: bleything
2004-10-18 12:19 pm (UTC)
Change "password" to "hpassword" and hash the thing. Check out the protocol docs for more info.

MD5 passwords are no more secure than plain-text, though... you should use challenge/response :)
(Reply) (Parent) (Thread)
[User Picture]From: djdavejumpers
2004-10-18 02:50 pm (UTC)
so after sending a getchallenge and printing
use strict;
use LWP;
use Digest::MD5 qw(md5_hex);

my $ua = LWP::UserAgent->new;
my $url = "http://www.livejournal.com/interface/flat";

my $content ="mode=getchallenge";

my $resp = $ua->post($url, content=>$content);
if ($resp->is_success) {
print $resp->content;
} else {
print "Bad luck this time\n";
}


I get the following

auth_scheme
c0
challenge
c0:1098129600:2579:60:9HzLA0ZptbzIOfB66fIS:0cb96c3f8b712d5755af206d2e4c709e
expire_time
1098132239
server_time
1098132179
success
OK


I can't seem to find how to parse these reponse, in order to grab the challenge response to do
my $response = md5_hex($result . md5_hex($pass));

How would you grab the response and put it in $result?

I know this is more like a PERL question, but I just though you would know.
thanks
(Reply) (Parent) (Thread)
[User Picture]From: djdavejumpers
2004-10-18 02:58 pm (UTC)
oh I figured it out.

my @lo = split(/\n/,$resp->content);

thanks for the tips.
(Reply) (Parent) (Thread)
[User Picture]From: sapphirecat
2004-10-19 06:10 am (UTC)
If you use a hash for it instead of an array, you can access it by name.

my %lo = split(/\n/, $resp->content);
my $response = md5_hex($lo{challenge} . md5_hex($pass));
(Reply) (Parent) (Thread)
(Deleted comment)
[User Picture]From: vanbeast
2004-10-18 11:48 am (UTC)
It doesn't escape anything :) Hence why I said it's hacky and needs improvement :)
(Reply) (Parent) (Thread)
[User Picture]From: vanbeast
2004-10-18 12:13 pm (UTC)
Actually, on that topic, I can't seem to find any url-encoding functions/modules anywhere, and neither can anyone here. We're probably just being dumb... do you know where I can find those?
(Reply) (Parent) (Thread)
(Deleted comment)
[User Picture]From: bleything
2004-10-18 12:18 pm (UTC)
Doesn't do URL encoding, just entitizing... at least as far as the CPAN page says.
(Reply) (Parent) (Thread)
[User Picture]From: lordindra
2004-10-18 12:20 pm (UTC)
URI::Escape includes the functions uri_escape and uri_unescape which will do that for you. Its part of the URI::URL module collection from CPAN includes this.

Page 21 of CGI Programming With Perl has the code for two functions that do the same thing, though it recommends using the ones from the module.
(Reply) (Parent) (Thread)
[User Picture]From: vanbeast
2004-10-18 12:21 pm (UTC)
Rad, that's what I was looking for. I knew I had seen it before, but just couldn't track it down.

Kinda painful to bring in two modules for a 10-line hack, though ;)
(Reply) (Parent) (Thread)
[User Picture]From: lordindra
2004-10-18 12:25 pm (UTC)
You only need to bring in URI::Escape. Its just that that module is part of the collection called URI::URL. Granted, you have to install the whole collection unless you want to go through some hoops, but you only have to bring in the one to your actual script to do the escaping/unescaping.
(Reply) (Parent) (Thread)
[User Picture]From: vanbeast
2004-10-18 12:32 pm (UTC)
Oh right, what I meant was URI::Escape and LWP :)
(Reply) (Parent) (Thread)
[User Picture]From: lordindra
2004-10-18 11:35 am (UTC)
I've got a basically functional LJ client in Perl/Tk, development has stopped because I just couldn't deal with the broken Tk text widget.

It supports private/friends/friend group/public posting, using the XML-RPC interface. So if you are willing to use that interface, you can lift the code out you need. It isn't terribly well commented I'm afraid, and I'm sure you know how evil 200 or so lines of poorly commented perl can look.

It also supports moods, can't remember if I ever got around to user pictures or current music.
(Reply) (Thread)
[User Picture]From: djdavejumpers
2004-10-18 12:45 pm (UTC)
where can I find it?
(Reply) (Parent) (Thread)
[User Picture]From: simonb
2004-10-18 05:58 pm (UTC)
Points in the direction of LJ::Simple
(Reply) (Thread)