#!/usr/bin/perl
# $Id: prontobrowser,v 1.5 2001/04/12 06:58:58 muhri Exp $
BEGIN {
$libpath = $0;
$libpath =~ s!/[^/]+$!!;
$libpath =~ s!/bin$!/lib/pronto!;
if (! -e $libpath) {
die _("Can't find required files in ") . $libpath . "\n";
};
}
use lib "$libpath";
use lib "$libpath/modules/lib/perl5/site_perl/5.005";
my ($HTMLWIDGET);
eval 'use Csc::HTML; $HTMLWIDGET = "CscHTML";' or eval 'use Gtk::HTML; $HTMLWIDGET = "GtkHTML";';
use Gtk;
init Gtk;
use URI::URL;
use IO::Socket;
use MIME::Types;
use File::Copy;
require 'prontolib.pl';
Gtk::Widget->set_default_colormap(Gtk::Gdk::Rgb->get_cmap());
Gtk::Widget->set_default_visual(Gtk::Gdk::Rgb->get_visual());
if ($HTMLWIDGET eq "GtkHTML") {
init Gtk::HTML;
} else {
init Csc::HTML;
}
&read_prefs;
$conn=&open_db_conn;
$url = $ARGV[0];
if ($url ne "") {
&init_webbrowser($url);
} else { &init_webbrowser }
sub init_webbrowser {
my ($url) = @_;
my ($window, $bg, $query, $sql, @row);
if (not defined $url) { $url = $prefs{'HomePage'};}
$wb_win = new Gtk::Window("toplevel");
$wb_win->signal_connect('destroy' => sub { $wb_win->destroy; undef $wb_win; Gtk->exit(0);});
$wb_win->signal_connect('delete_event' => \&Gtk::false);
$wb_win->set_default_size('640','480');
$wb_win->set_policy(1,1,0);
$wb_win->set_title("Pronto Mini Browser");
$wb_win->{'vbox'} = new Gtk::VBox(0,0);
$wb_win->{'vbox'}->show;
$wb_win->show;
$wb_win->add($wb_win->{'vbox'});
$window = $wb_win->window;
$bg = $wb_win->style->bg('normal');
$wb_win->{'menu'} = new Gtk::MenuBar;
$wb_win->{'menu'}->{'file'} = new Gtk::MenuItem("File");
$wb_win->{'menu'}->{'file'}->show;
$wb_win->{'menu'}->show;
$wb_win->{'menu'}->append($wb_win->{'menu'}->{'file'});
$wb_win->{'menu'}->{'view'} = new Gtk::MenuItem("View");
$wb_win->{'menu'}->{'view'}->show;
$wb_win->{'menu'}->append($wb_win->{'menu'}->{'view'});
$wb_win->{'view_menu'} = new Gtk::Menu;
$wb_win->{'menu'}->{'view'}->set_submenu($wb_win->{'view_menu'});
$wb_win->{'view_menu'}->{'debug'} = new Gtk::CheckMenuItem("Debug");
$wb_win->{'view_menu'}->{'debug'}->set_active(0);
$wb_win->{'view_menu'}->{'debug'}->show;
$wb_win->{'view_menu'}->{'debug'}->signal_connect("toggled" => \&debug);
$wb_win->{'view_menu'}->append($wb_win->{'view_menu'}->{'debug'});
$wb_win->{'file_menu'} = new Gtk::Menu;
$wb_win->{'menu'}->{'file'}->set_submenu($wb_win->{'file_menu'});
$wb_win->{'file_menu'}->{'new'} = new Gtk::MenuItem("New Window ..");
$wb_win->{'file_menu'}->{'new'}->signal_connect("activate" => \&new_window);
$wb_win->{'file_menu'}->{'new'}->show;
$wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'new'});
$wb_win->{'file_menu'}->{'home'} = new Gtk::MenuItem("Home");
$wb_win->{'file_menu'}->{'home'}->signal_connect("activate" => \&wb_view_url, $prefs{'HomePage'});
$wb_win->{'file_menu'}->{'home'}->show;
$wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'home'});
$wb_win->{'file_menu'}->{'back'} = new Gtk::MenuItem("Back");
$wb_win->{'file_menu'}->{'back'}->signal_connect("activate" => \&wb_view_url, "back");
$wb_win->{'file_menu'}->{'back'}->show;
$wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'back'});
$wb_win->{'file_menu'}->{'search'} = new Gtk::MenuItem("Search");
$wb_win->{'file_menu'}->{'search'}->show;
$wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'search'});
$wb_win->{'file_menu'}->{'close'} = new Gtk::MenuItem("Close");
$wb_win->{'file_menu'}->{'close'}->signal_connect("activate" => sub { $wb_win->destroy; undef $wb_win; Gtk->exit(0); });
$wb_win->{'file_menu'}->{'close'}->show;
$wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'close'});
$wb_win->{'file_menu'}->show;
$wb_win->{'vbox'}->pack_start($wb_win->{'menu'},0,0,0);
$wb_win->{'handlebox'} = new Gtk::HandleBox();
$wb_win->{'handlebox'}->show;
$wb_win->{'toolbar'} = new Gtk::Toolbar('horizontal', 'both');
$wb_win->{'toolbar'}->set_button_relief('none');
$wb_win->{'toolbar'}->set_tooltips($prefs{'ToolTips'});
$wb_win->{'toolbar'}->border_width('2');
$wb_win->{'toolbar'}->show;
$wb_win->{'handlebox'}->add($wb_win->{'toolbar'});
$wb_win->{'vbox'}->pack_start($wb_win->{'handlebox'},0,0,0);
$wb_win->{'back_button'} = $wb_win->{'toolbar'}->append_item("Back","Click here to go back a page", "",new_pixmap("$prefs{'PixmapDir'}/back.xpm", $window, $bg));
$wb_win->{'home_button'} = $wb_win->{'toolbar'}->append_item("Home","Click here to go to your homepage", "",new_pixmap("$prefs{'PixmapDir'}/top.xpm", $window, $bg));
$wb_win->{'entry'} = new Gtk::Entry;
$wb_win->{'entry'}->set_text($url);
$wb_win->{'entry'}->show;
$wb_win->{'toolbar'}->append_widget($wb_win->{'entry'}, "Type a URL here and press enter to go to that page", "");
$wb_win->{'entry'}->set_usize(300,25);
$wb_win->{'go_button'} = new Gtk::Button;
$wb_win->{'go_button'}->show;
my ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm($window,$bg,"$prefs{'PixmapDir'}/go.xpm");
$wb_win->{'go_button'}->{'pixmap'} = new Gtk::Pixmap($pixmap, $mask);
$wb_win->{'go_button'}->{'pixmap'}->show;
$wb_win->{'go_button'}->add($wb_win->{'go_button'}->{'pixmap'});
$wb_win->{'bookmarks'}->{'button'}= new Gtk::Button("Bookmarks");
$wb_win->{'bookmarks'}->{'button'}->set_usize(75,25);
$wb_win->{'bookmarks'}->{'button'}->show;
$wb_win->{'toolbar'}->append_widget($wb_win->{'go_button'}, "Click here to load page", "");
$wb_win->{'toolbar'}->append_widget($wb_win->{'bookmarks'}->{'button'}, "Bookmarks", "");
$wb_win->{'toolbar'}->insert_space(2);
$wb_win->{'toolbar'}->insert_space(4);
$wb_win->{'toolbar'}->insert_space(6);
$wb_win->{'toolbar'}->set_space_size(10);
$wb_win->{'statusbar'} = new Gtk::Statusbar;
$wb_win->{'statusbar'}->show;
$wb_win->{'progress'}=new Gtk::ProgressBar;
$wb_win->{'progress'}->set_usize(200,20);
$wb_win->{'progress'}->show;
$wb_win->{'popup'} = new Gtk::Menu;
$wb_win->{'popup'}->{'sep'} = new Gtk::MenuItem;
$wb_win->{'popup'}->show;
$wb_win->{'popup'}->{'sep'}->show;
$wb_win->{'popup'}->append($wb_win->{'popup'}->{'sep'});
$wb_win->{'popup'}->{'new'} = new Gtk::MenuItem("Open in a new Window...");
$wb_win->{'popup'}->{'new'}->signal_connect("activate" => \&load_new);
$wb_win->{'popup'}->append($wb_win->{'popup'}->{'new'});
$wb_win->{'popup'}->{'new'}->show;
$wb_win->{'popup'}->{'save'} = new Gtk::MenuItem("Save Link As...");
$wb_win->{'popup'}->{'save'}->signal_connect("activate" => \&download_url);
$wb_win->{'popup'}->{'save'}->show;
$wb_win->{'popup'}->append($wb_win->{'popup'}->{'save'});
$wb_win->{'bookmarks'}->{'popup'} = new Gtk::Menu;
$wb_win->{'bookmarks'}->{'popup'}->{'bm_page'} = new Gtk::MenuItem("Bookmark Current Page");
$wb_win->{'bookmarks'}->{'popup'}->{'bm_page'}->signal_connect("activate" => \&add_bookmark, $wb_win);
$wb_win->{'bookmarks'}->{'popup'}->{'bm_page'}->show;
$wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{'bm_page'});
$wb_win->{'bookmarks'}->{'popup'}->{'sep'} = new Gtk::MenuItem;
$wb_win->{'bookmarks'}->{'popup'}->{'sep'}->show;
$wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{'sep'});
$sql = "select id, title, url from bookmarks order by id";
$query=$conn->prepare($sql);
$query->execute();
while (@row=$query->fetchrow_array()) {
$wb_win->{'bookmarks'}->{'popup'}->{$row[0]} = new Gtk::MenuItem($row[1]);
$wb_win->{'bookmarks'}->{'popup'}->{$row[0]}->signal_connect("activate" => \&wb_view_url, $row[2]);
$wb_win->{'bookmarks'}->{'popup'}->{$row[0]}->show;
$wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{$row[0]});
}
if ($HTMLWIDGET eq "GtkHTML") {
$wb_win->{'html'} = new Gtk::HTML;
} else {
$wb_win->{'html'} = new Csc::HTML;
}
if ($THREADS == 1) {
$wb_win->{'html'}->signal_connect('url_requested' => \&thread_lwu);
} else {
$wb_win->{'html'}->signal_connect('url_requested' => \&load_wb_url);
}
$wb_win->{'html'}->signal_connect('link_clicked' => \&wb_view_url);
$wb_win->{'html'}->signal_connect('title_changed' => \&set_title);
$wb_win->{'html'}->signal_connect('on_url' => \&wb_status);
$wb_win->{'html'}->signal_connect('submit' => \&on_submit);
$wb_win->{'html'}->signal_connect('redirect' => \&on_redirect);
$wb_win->{'html'}->set_editable(0);
$wb_win->{'html'}->enable_debug(0);
$wb_win->{'sw'} = new Gtk::ScrolledWindow(undef, undef);
$wb_win->{'sw'}->set_policy('automatic', 'automatic');
$wb_win->{'sw'}->show;
$wb_win->{'sw'}->add($wb_win->{'html'});
$wb_win->{'vbox'}->pack_start($wb_win->{'sw'},1,1,0);
$wb_win->{'hbox'}= new Gtk::HBox(0,0);
$wb_win->{'hbox'}->show;
$wb_win->{'vbox'}->pack_end($wb_win->{'hbox'},0,0,0);
$wb_win->{'hbox'}->pack_start($wb_win->{'statusbar'},1,1,0);
$wb_win->{'hbox'}->pack_end($wb_win->{'progress'},0,0,0);
$wb_win->{'html'}->realize;
$wb_win->{'html'}->show;
$wb_win->{'html'}->signal_connect('button_press_event' => \&wb_mouse_click);
$wb_win->{'entry'}->signal_connect("activate" => \&wb_entry_url);
$wb_win->{'back_button'}->signal_connect("clicked" => \&wb_view_url, "back");
$wb_win->{'home_button'}->signal_connect("clicked" => \&wb_view_url, $prefs{'HomePage'});
$wb_win->{'go_button'}->signal_connect("clicked" => \&wb_entry_url);
$wb_win->{'bookmarks'}->{'button'}->signal_connect("clicked" => sub {$wb_win->{'bookmarks'}->{'popup'}->popup(undef, undef, 0, 0);});
$wb_win->{'file_menu'}->{'search'}->signal_connect("activate" => sub { $wb_win->{'html'}->search; });
&wb_view_url(undef, $url);
return 1;
}
sub set_title {
my ($widget, $title) = @_;
$wb_win->set_title($title)
}
sub add_bookmark {
my ($widget, $wb_win) = @_;
my ($sql, $query, $title, $address, $id);
$title = $wb_win->{'html'}->get_title();
$address = $wb_win->{'current'}->as_string;
print ("title = $title\naddress = $address\n");
$sql = "insert into bookmarks (id, title, url) values (?, ?, ?)";
$query = $conn->prepare($sql);
$id = &newid('bookmarks', $conn);
$query->execute($id, $title, $address);
$wb_win->{'bookmarks'}->{'popup'}->{$id} = new Gtk::MenuItem($title);
$wb_win->{'bookmarks'}->{'popup'}->{$id}->signal_connect("activate" => \&wb_view_url, $address);
$wb_win->{'bookmarks'}->{'popup'}->{$id}->show;
$wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{$id});
return 1;
}
sub debug {
my ($widget) = @_;
if ($widget->active) {
$wb_win->{'html'}->enable_debug(0);
} else {
$wb_win->{'html'}->enable_debug(1);
}
}
sub on_submit {
my ($widget, $method, $action, $encoding) = @_;
if ($method eq "GET") {
$action.="?$encoding";
&wb_view_url(undef, $action);
} elsif ($method eq "POST") {
$wb_win->{'length'} = length($encoding);
$wb_win->{'message'} = $encoding;
print ("$wb_win->{'message'}\n");
if (!$action) {$action = $wb_win->{'current'}; }
&wb_view_url(undef, $action);
} else {
print ("Unsupported Form Method: $method\nAction: $action\nEncoding: $encoding\n");
}
return 1;
}
sub redirect_timer_event {
my ($redirect_url) = @_;
Gtk->timeout_remove($redirect_timerID);
undef $redirect_timerID;
&wb_view_url(undef, $redirect_url);
}
sub on_redirect {
my ($widget, $url, $delay) = @_;
if (not defined $redirect_timerID) {
$redirect_timerID = Gtk->timeout_add($delay * 1000, \&redirect_timer_event, $url);
}
}
sub wb_mouse_click {
my ($widget, $event) = @_;
if ($event->{'button'} != 3) {
return 1;
}
if (!$wb_win->{'mouse_url'}) {
return 1;
}
$wb_win->{'popup'}->popup(undef, undef, $event->{'button'}, $event->{'time'});
return 1;
}
sub gtkhtml_mouse_click {
my ($widget, $popup, $url, $event) = @_;
if ($event->{'button'} != 3) {
return 1;
}
if(!defined $$url) {
return 1;
}
if($$url =~ /^file:$prefs{'MailDir'}\/tmp\//) {
$popup->popup(undef, undef, $event, $event->{'time'});
}
return 1;
}
sub wb_status {
shift;
my $url = shift;
if (defined $url) {
my $stat = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1);
$wb_win->{'statusbar'}->push(1,$stat);
$wb_win->{'mouse_url'} = $stat;
} else {
$wb_win->{'statusbar'}->pop(1);
$wb_win->{'mouse_url'} = "";
}
return 1;
}
sub wb_entry_url {
my ($url);
$url = $wb_win->{'entry'}->get_text;
if ($url !~ /^\w+:/) { $url = "http://" . $url; }
&wb_view_url(undef, $url);
return 1;
}
sub wb_view_url {
my ($widget, $url) = @_;
if (!$url) { return 1; }
my ($request, $host, $port, $path, $type, $header, $status, $st_num, $full_url, $socket, $redirect_url, $back);
$back = 0;
if ($url =~ /^mailto:(.+)/) {
my ($address, @fields);
$address = $1;
$fields[0] = $address;
$fields[1] = "";
$fields[2] = "";
my $child;
unless ($child = fork) {
die "cannot fork: $~" unless defined $child;
exec("pronto $address");
}
#&init_msg_window(0, undef, \@fields);
return 1;
}
if (not defined $wb_win) {
&init_webbrowser($url);
return 1;
}
if ($url eq "back") {
if (defined @{$wb_win->{'history'}}) {
my $tmp = pop @{$wb_win->{'history'}};
if ($tmp) { $url = $tmp; $back = 1;} else { return 1; }
} else {
return 1;
}
}
if (defined $wb_win) {
$wb_win->{'statusbar'}->pop(1);
}
$wb_win->{'progress'}->set_activity_mode(1);
if ($url =~ /^file:(.+)/) {
$full_url = $url;
my $path = $1;
if (-d $path) { # its a directory
if ($path !~ /\/$/) { $path.="/"; }
$wb_win->{'entry'}->set_text($full_url);
$wb_win->{'current'} = $full_url;
$wb_win->{'base'} = $full_url;
$type = "text/html";
my $i = 1000;
opendir DIR, $path;
my @entries = grep !/^\.\.?$/, readdir DIR;
closedir(DIR);
open (TMP,">$prefs{'MailDir'}/temp.html");
print TMP ("<html><head><title>Items in $path</title></head><body>\n");
print TMP ("<p><h1>Items in $path</h1></p>\n");
print TMP ("<a href=\"file:$path\">.</a><br>\n");
my $tmp = $path;
$tmp =~ s/(.*\/)\w+\/$/$1/;
print TMP ("<a href=\"file:$tmp\">..</a><br>\n");
foreach (sort(@entries)) {
if (-d "$path$_") {
print TMP ("<a href=\"file:$path$_/\">$_</a><br>\n");
} else {
print TMP ("<a href=\"file:$path$_\">$_</a><br>\n");
}
}
print TMP ("</body></html>");
close(TMP);
$full_url = "file:$prefs{'MailDir'}/temp.html";
} else { # its a file of some sort
($type) = MIME::Types::by_suffix($1);
if (!$type) { $type = "application/unknown"; }
}
} else {
$full_url = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1);
# $full_url =~ s/%(\w\w)/chr(hex($1))/eg;
$full_url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/;
if (!$3) { $path = "/"; } else { $path = $3; }
if (!$2) { $port = 80; } else { $port = $2; }
if (!$1) { return 1; } else { $host = $1; }
if ($prefs{'Proxy'}) {
$socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1;
print $socket "HEAD $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
} else {
$socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1;
print $socket "HEAD $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
}
CONTINUE: $status = <$socket>;
$/ = "";
$header = <$socket>;
$/ = "\n";
$status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1;
if ($st_num == 301 || $st_num == 302) {
$header =~ /Location: ?(.+)/i and $redirect_url = $1;
&wb_view_url(undef, $redirect_url);
return 1;
} elsif ($st_num == 100) {
goto CONTINUE;
} elsif ($st_num != 200) {
&err_dialog("$status");
return 1;
}
$header =~ /Content-Type: ?(.+)/i and $type = $1;
}
if ($type !~ /text\//i) {
if ($type =~ /image\//) {
$full_url =~ s/ /%20/g;
open (TMP,">$prefs{'MailDir'}/temp.html");
print TMP ("<html><head><title>$full_url</title></head><body><img src=$full_url></body></html>");
close(TMP);
$full_url = "file:$prefs{'MailDir'}/temp.html";
} else {
&download_url(undef, $full_url);
return 1;
}
}
if (defined $wb_win->{'current'} && $back != 1) {
push @{$wb_win->{'history'}}, $wb_win->{'current'};
}
$wb_win->{'current'} = $full_url;
$wb_win->{'base'} = $full_url;
$wb_win->{'entry'}->set_text($full_url);
if ($THREADS == 1) {
&thread_lwu($wb_win->{'html'}, $full_url, $wb_win->{'html'}->begin)
} else {
&load_wb_url($wb_win->{'html'}, $full_url, $wb_win->{'html'}->begin)
}
$wb_win->{'progress'}->set_activity_mode(0);
return 1;
}
sub download_url {
my ($widget, $url) = @_;
if (!$url && !($url = $wb_win->{'mouse_url'})) { return 1; }
my ($filename, $fs_window);
$url =~ /\/([-\w\.]+)$/ and $filename = $1;
if (!$filename) { $filename=""; }
print ("File before: $filename\n");
$fs_window = new Gtk::FileSelection "Download File";
$fs_window->position(-mouse);
$fs_window->signal_connect("destroy", sub {$fs_window->destroy;});
$fs_window->signal_connect("delete_event" => \&Gtk::false);
$fs_window->ok_button->signal_connect("clicked", \&begin_dl, $fs_window, $url);
$fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;});
$fs_window->set_filename($filename);
$fs_window->show;
return 1;
}
sub begin_dl {
my ($widget, $fs_window, $url) = @_;
my ($fh, $status_dialog, $sd_vbox, $sd_label, $sd_pbar, $sd_button, $path, $port, $host, $socket, $status, $st_num, $length, $count, $d);
my ($answer, $header) = ("","");
my $filename = $fs_window->get_filename();
print ("Filename: $filename\n");
$fs_window->destroy;
if ($url =~ /^file:(.+)/) {
my $from = $1;
copy($from, $filename);
return 1;
}
$status_dialog = new Gtk::Dialog;
$status_dialog->signal_connect("destroy" => sub { $status_dialog->destroy; });
$status_dialog->signal_connect("delete_event" => sub { $status_dialog->destroy; });
$status_dialog->set_title("Downloading File...");
$status_dialog->border_width(0);
$sd_vbox=new Gtk::VBox(0,5);
$sd_vbox->border_width(10);
$status_dialog->vbox->pack_start($sd_vbox,1,1,0);
$sd_vbox->show;
$sd_label=new Gtk::Label "Downloading $filename...";
$sd_label->set_alignment(0.0,0.5);
$sd_vbox->pack_start($sd_label,0,1,0);
$sd_label->show;
$sd_pbar=new Gtk::ProgressBar;
$sd_pbar->set_usize(200,20);
$sd_vbox->pack_start($sd_pbar,1,1,0);
$sd_pbar->show;
$sd_pbar->set_show_text(1);
$sd_pbar->set_text_alignment(0.5,0.5);
$sd_pbar->set_format_string("%v of %u - %p %%");
$sd_button=new Gtk::Button "Cancel Transfer";
$sd_button->can_default(1);
$status_dialog->action_area->pack_start($sd_button,1,1,0);
$sd_button->grab_default;
$sd_button->show;
$status_dialog->show;
$sd_button->signal_connect("clicked", sub { $status_dialog->destroy; $fh->close; $socket->close; return 1; });
# $url =~ s/%(\w\w)/chr(hex($1))/eg;
# $url =~ s/ //g;
$url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/;
if (!$3) { $path = "/"; } else { $path = $3; }
if (!$2) { $port = 80; } else { $port = $2; }
if (!$1) { return 1; } else { $host = $1; }
print ("Host: $host\nPath: $path\nPort: $port\n");
if ($prefs{'Proxy'}) {
$socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM);
print $socket "GET $url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
} else {
$socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM);
print $socket "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
}
CONTINUE: $status = <$socket>;
$status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1;
while (defined $answer and $answer ne "\n") {
$answer = <$socket>;
if ($answer) {
$answer =~ s/\r//g;
$header.= $answer;
}
}
if ($st_num == 301 || $st_num ==302) {
$header =~ /\nLocation: ?(.+)/i and $url = $1;
&begin_dl($widget, $fs_window, $url);
return 1;
} elsif ($st_num == 100) {
goto CONTINUE;
} elsif ($st_num != 200) {
&err_dialog("$status");
return 1;
}
print ("$header\n");
$header =~ /Content-Length: ?(\d+)/i and $length = $1;
$sd_pbar->configure(0,0,$length);
if ($fh = new IO::File ">$filename") {
if (defined $length && $length > 8192) {
my $numfullpackets = int($length/8192);
my $lastpacket = $length - ($numfullpackets * 8192);
for (my $i = 1; $i <= $numfullpackets; $i++) {
$count+=8192;
$sd_pbar->set_value($count);
while (Gtk->events_pending) {
Gtk->main_iteration;
}
$socket->read($d, 8192);
print $fh $d;
}
$socket->read($d, $lastpacket);
} else {
$socket->read($d, 8192);
}
print $fh $d;
}
$status_dialog->destroy;
return 1;
}
sub thread_lwu {
my ($html, $url, $handle) = @_;
my $t = new Thread \&thread_start_lwu, $html, $url, $handle;
$t->detach;
return 1;
}
sub thread_start_lwu {
my ($html, $url, $handle) = @_;
Gtk::Gdk->threads_enter();
&load_wb_url($html, $url, $handle);
Gtk::Gdk->threads_leave();
POSIX::_exit();
}
sub load_wb_url {
my ($html, $url, $handle) = @_;
my ($full_url, $socket, $answer, $length, $header, $host, $path, $port, $d, $xferencode, $status, $st_num);
$header="";
$answer = "";
$full_url = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1);
if ($full_url->as_string =~ /^file:(.+)/) {
my $path = $1;
$path =~ s/%(\w\w)/chr(hex($1))/eg;
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size)=stat $path;
$socket = IO::File->new($path) or return 1;
$socket->read($d, $size);
$html->write($handle, $d);
$html->end($handle, 'ok');
return 1;
}
$full_url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/;
if (!$3) { $path = "/"; } else { $path = $3; }
if (!$2) { $port = 80; } else { $port = $2; }
if ($1) { $host = $1; } else { return 1; }
if ($prefs{'Proxy'}) {
$socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1;
} else {
$socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1;
}
if (!$wb_win->{'message'}) {
if ($prefs{'Proxy'}) {
print $socket "GET $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
} else {
print $socket "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n";
}
} else {
if ($prefs{'Proxy'}) {
print $socket "POST $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\nContent-type: application/x-www-form-urlencode\r\nContent-length: $wb_win->{'length'}\r\n\r\n$wb_win->{'message'}\r\n";
} else {
print $socket "POST $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\nContent-type: application/x-www-form-urlencode\r\nContent-length: $wb_win->{'length'}\r\n\r\n$wb_win->{'message'}\r\n";
}
undef $wb_win->{'message'};
undef $wb_win->{'length'};
}
CONTINUE: $status = <$socket>;
$status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1;
while (defined $answer and $answer ne "\n") {
$answer = <$socket>;
if ($answer) {
$answer =~ s/\r//g;
$header.= $answer;
}
}
if ($st_num == 301 || $st_num ==302) {
$url = "";
$header =~ /Location: ?(.+)/i and $url = $1;
unless ($url eq "") {
&load_wb_url($html, $url, $handle);
return 1;
}
} elsif ($st_num == 100) {
$answer = "";
goto CONTINUE;
} elsif ($st_num != 200) {
&err_dialog("$status");
return 1;
}
$header =~ /Content-Length: ?(\d+)/i and $length = $1;
$header =~ /\nTransfer-Encoding: ?(.+)/i and $xferencode = $1;
if (defined $xferencode && $xferencode =~ /chunked/) {
$wb_win->{'progress'}->set_activity_mode(1);
my ($body, $line);
$/ = "\r\n";
$line = <$socket>;
$/ = "\n";
$line =~ /^(\w+)/ and $length = $1;
while (hex($length) > 0) {
$socket->read($d, hex($length));
$body.=$d;
$/ = "\r\n";
$line = <$socket>;
$line = <$socket>;
$length = 0;
$line =~ /^(\w+)/ and $length = $1;
$/ = "\n";
}
$html->write($handle, $body);
$wb_win->{'progress'}->set_activity_mode(0);
} else {
if (defined $length && $length > 8192) {
$wb_win->{'progress'}->configure(0,0,$length);
my $numfullpackets = int($length/8192);
my $lastpacket = $length - ($numfullpackets * 8192);
for (my $i = 1; $i <= $numfullpackets; $i++) {
$socket->read($d, 8192);
$wb_win->{'progress'}->set_value($i * 8192);
$html->write($handle, $d);
}
$wb_win->{'progress'}->set_value($length);
$socket->read($d, $lastpacket);
} else {
$socket->read($d, 65535);
}
$html->write($handle, $d);
}
$html->end($handle, 'ok');
$wb_win->{'progress'}->set_value(0);
return 1;
}
sub new_pixmap {
my ($filename, $window, $background) = @_;
my ($pixmap, $mask) = create_from_xpm Gtk::Gdk::Pixmap($window, $background, $filename);
return new Gtk::Pixmap($pixmap, $mask);
}
sub load_new {
my ($widget, $url) = @_;
if (!$url && !($url = $wb_win->{'mouse_url'})) { return 1; }
my $child;
unless ($child = fork) {
die "cannot fork: $~" unless defined $child;
exec("prontobrowser $url");
}
}
sub new_window {
my $child;
unless ($child = fork) {
die "cannot fork: $~" unless defined $child;
exec("prontobrowser");
}
}
main Gtk;
syntax highlighted by Code2HTML, v. 0.9.1