| #!/usr/bin/perl | |
| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| require 5.001; | |
| use strict; | |
| use sigtrap; | |
| use Socket; | |
| require "do_tcp.pl"; | |
| require "url_manip.pl"; | |
| #forward declaration | |
| sub spawn_http_request($$$); | |
| sub make_proxy_request($$$$$); | |
| sub make_doc_filename($); | |
| sub make_doc_http_filename($); | |
| ########################################################### | |
| # | |
| # global configuration parameters | |
| # | |
| ########################################################### | |
| glob($number_of_users) = 1; | |
| glob($save_http_doc) = 0; #if false (0) don't save a copy | |
| #of the doc and header files. | |
| glob($method) = "GET"; #method to use in http requests | |
| ########################################################### | |
| # | |
| # subroutine: compare_files | |
| # | |
| # return 0 if files are identical | |
| ########################################################### | |
| sub compare_files($$$) | |
| { | |
| my ($dfile, $pfile, $log_file) = @_; | |
| @args = ("diff", $dfile, $pfile, ">>", $log_file); | |
| #diff returns 0 if files are identical | |
| $is_diff = system(@args); | |
| return ($is_diff); | |
| } | |
| ########################################################### | |
| # | |
| # connect, send request and process response | |
| # | |
| ########################################################### | |
| ########################################################### | |
| # | |
| # subroutine: spawn_task | |
| # | |
| ########################################################### | |
| sub spawn_task($$$$) | |
| { | |
| my ($hostname, $hostport, $request, $run_task) = @_; | |
| my ($pid); | |
| if (!defined($pid = fork)) { | |
| print "fork failed", "\n"; | |
| exit; | |
| } elsif ($pid) { # parent | |
| return; | |
| } | |
| # else, I am the child | |
| run_task($hostname, $hostport, $request); | |
| exit; | |
| } | |
| ########################################################### | |
| # | |
| # subroutine: run_proxy_keep_alive | |
| # | |
| ########################################################### | |
| sub run_proxy_keep_alive | |
| { | |
| my ( | |
| $proxy_host_name, $proxy_port,; | |
| } | |
| @@@@@@@@@@ | |
| ########################################################### | |
| # | |
| # subroutine: do_http_request hostname request | |
| # | |
| ########################################################### | |
| sub do_http_request($$$) | |
| { | |
| my ($hostname, $hostport, $request) = @_; | |
| my ($line); | |
| my ($iaddr, $paddr, $proto); | |
| $hostname =~ s/\s//g; | |
| $iaddr = inet_aton($hostname) or die "no host: $hostname", "\n"; | |
| $paddr = sockaddr_in($hostport, $iaddr); | |
| $proto = getprotobyname('tcp'); | |
| unless (socket(Host, PF_INET, SOCK_STREAM, $proto)) { | |
| print "socket: $!", "\n"; | |
| exit; | |
| } | |
| unless (connect(Host, $paddr)) { | |
| print "connect: $!", "\n"; | |
| exit; | |
| } | |
| syswrite Host, $request, length($request); | |
| #process response | |
| process_http_response($request, $Host, 1, 1); | |
| print "request is done\n"; | |
| close(Host); | |
| return; | |
| } | |
| ########################################################### | |
| # | |
| # subroutine: process_http_response | |
| # request, | |
| # host_socket, | |
| # save_doc_flag, | |
| # save_http_flag | |
| # | |
| # options for save doc | |
| # - save http response header in doc.http | |
| # - save http doc in a unique file | |
| ########################################################### | |
| sub process_http_response($$$$) | |
| { | |
| my ($request, $Host, $save_doc_flag, $save_http_flag) = @_; | |
| my ($doc_filename, $http_filename); | |
| my ($doc_filename) = make_doc_filename($request); | |
| my ($doc_http_filename) = make_doc_http_filename($request); | |
| print $doc_filename, ' ', $doc_http_filename, "\n"; | |
| my ($doc_file, $doc_http_file); | |
| ######################## | |
| # open files for write # | |
| ######################## | |
| if ($save_doc_flag) { | |
| unless (open doc_file, ">$doc_filename") { | |
| print "cannot open $doc_filename for write", "\n"; | |
| return; | |
| } | |
| } | |
| if ($save_http_flag) { | |
| unless (open doc_http_file, ">$doc_http_filename") { | |
| print "cannot open $doc_http_filename for write", "\n"; | |
| return; | |
| } | |
| } | |
| ############################## | |
| # write http header and body # | |
| ############################## | |
| my ($http_header) = 1; | |
| my ($doc_body) = 0; | |
| my ($line); | |
| while ($line = <Host>) { | |
| if ($http_header) { | |
| if ($save_http_flag) { | |
| print doc_http_file $line; | |
| } | |
| if (length($line) <= 2 && $line == "\n") { | |
| close doc_http_file; | |
| $http_header = 0; | |
| $doc_body = 1; | |
| } | |
| } elsif ($save_doc_flag) { | |
| print doc_file $line; | |
| } | |
| } | |
| return; | |
| } | |
| ########################################################### | |
| # | |
| # subroutine: make_proxy_request | |
| # request | |
| # host_name | |
| # host_port | |
| # proxy_name | |
| # proxy_port | |
| # | |
| ########################################################### | |
| sub make_proxy_request($$$$$) | |
| { | |
| my ($request, $host_name, $host_port, $proxy_name, $proxy_port) = @_; | |
| my ($proxy_request) = $request; | |
| my ($url_prefix) = "http:\/\/$host_name\/"; | |
| $url_prefix =~ s/\s//g; | |
| if ($host_port != 80) { | |
| $url_prefix .= ":$host_port\/"; | |
| } | |
| $url_prefix =~ s/\s//g; | |
| $proxy_request =~ s/\//$url_prefix/; | |
| return ($proxy_request); | |
| } | |
| ########################################################### | |
| # | |
| # subroutine: make_doc_filename request | |
| # | |
| # file name is: <host_name><doc_name> | |
| ########################################################### | |
| sub make_doc_filename($) | |
| { | |
| my ($request) = @_; | |
| my ($doc_filename); | |
| my ($host_name); | |
| ($_, $host_name) = split(/host:/i, $request, 2); | |
| ($host_name, $_) = split(/ /, $host_name); | |
| #replace every . with _ | |
| $host_name =~ s/\./_/g; | |
| print $request, "\n"; | |
| print $host_name, "\n"; | |
| ($_, $doc_filename) = split(/ /, $request, 2); | |
| #remove scheme://host_name if this is a proxy request | |
| # if ($doc_filename =~ m/:\/\//) | |
| # { | |
| # | |
| # } | |
| # | |
| # @@@@@@@@ | |
| ($_, $doc_filename) = split(/\//, $doc_filename, 2); | |
| $doc_filename =~ s/\//_/g; | |
| #remove any white spaces | |
| $doc_filename =~ s/\s//g; | |
| print "doc name is: ", $doc_filename, "\n"; | |
| if (length($doc_filename) <= 1) { | |
| $doc_filename = 'default.html'; | |
| } | |
| $doc_filename = $host_name . '_' . $doc_filename; | |
| #remove any white spaces | |
| $doc_filename =~ s/\s//g; | |
| return ($doc_filename); | |
| } | |
| ########################################################### | |
| # | |
| # subroutine: make_doc_filename request | |
| # | |
| ########################################################### | |
| sub make_doc_http_filename($) | |
| { | |
| my ($request) = @_; | |
| my ($doc_http_filename); | |
| $doc_http_filename = make_doc_filename($request); | |
| $doc_http_filename .= '.http'; | |
| return ($doc_http_filename); | |
| } | |
| ########################################################### | |
| # | |
| # main entry point | |
| # | |
| ########################################################### | |
| if ($#ARGV != 1 and $#ARGV != 3) { | |
| print 'no proxy : test_http_client <input file> <number of users>', "\n"; | |
| print 'use proxy: test_http_client <input file> <number of users> '; | |
| print '<proxy host> <proxy port>', "\n"; | |
| exit; | |
| } | |
| if ($#ARGV == 1) { | |
| my ($infile, $nusers) = @ARGV; | |
| process_input_http_requests_file($infile, "", ""); | |
| } elsif ($#ARGV == 3) { | |
| my ($infile, $nusers, $proxy_name, $proxy_port) = @ARGV; | |
| process_input_http_requests_file($infile, $proxy_name, $proxy_port); | |
| } | |
| print "\n"; | |
| exit; | |