I am learning SOAP and have created a very small CGI script which runs on Apache that will offer a small set of functions.
#!/usr/bin/perl
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
-> dispatch_to('Demo')
-> handle;
package Demo;
sub hi {
return "hello, world";
}
sub bye {
return "goodbye, cruel world";
}
sub languages {
return ("Perl", "C", "sh");
}
My client is
#!perl -w
use SOAP::Lite;
print SOAP::Lite
-> uri('http://localhost:80/cgi-bin/Demo')
-> proxy('http://localhost:80/cgi-bin/hibye.cgi')
-> hi()
-> result;
Everything compiles and there are no errors when I run the scripts. The problem is that when I run the client it finishes, but it doesn't get a response. I think that the URI might be wrong, but I am not sure. The proxy is fine.
Edit: I wasn't getting errors when running the scripts in the console, however I was getting errors in the apache log (which for some reason I did not check).
The error was
script not found or unable to stat: /usr/lib/cgi-bin/hibye.cgis
It was a permission problem. I fixed it and now I when running the script no problem appears neither in the console, neither in the error log.
In the access log I get the following:
"POST /cgi-bin/hibye.cgi HTTP/1.1" 500 780 "-" "SOAP::Lite/Perl/0.714"
After some experimenting, I found out the problem - it was in the uri binding. In this case it must be changed from:
http://localhost:80/cgi-bin/Demo
to:
http://localhost:80/Demo
and the script will work like it is supposed to.
Related
I am trying to understand some example Kotlin code that connects to http://127.0.0.1 using sockets, and I have IIS enabled and running it on 127.0.0.1. However, when I run the code, I get:
"C:\Program Files\Microsoft\jdk-11.0.12.7-hotspot\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52769,suspend=y,server=n -javaagent:C:/Users/ivlat/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.5.0/d8cebccdcddd029022aa8646a5a953ff88b13ac8/kotlinx-coroutines-core-jvm-1.5.0.jar -javaagent:C:\Users\ivlat\AppData\Local\JetBrains\IdeaIC2022.2\captureAgent\debugger-agent.jar=file:/C:/Users/ivlat/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:\Dev\KotlinProjects\7_08_Echo\client\build\classes\kotlin\main;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk8\1.5.21\6b3de2a43405a65502728047db37a98a0c7e72f0\kotlin-stdlib-jdk8-1.5.21.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.2.3\7c4f3c474fb2c041d8028740440937705ebb473a\logback-classic-1.2.3.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.2.3\864344400c3d4d92dfeb0a305dc87d953677c03c\logback-core-1.2.3.jar;C:\Dev\KotlinProjects\7_08_Echo\shared\build\classes\kotlin\main;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-coroutines-core-jvm\1.5.0\d8cebccdcddd029022aa8646a5a953ff88b13ac8\kotlinx-coroutines-core-jvm-1.5.0.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk7\1.5.21\f059658740a4b3a3461aba9681457615332bae1c\kotlin-stdlib-jdk7-1.5.21.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.5.21\2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e\kotlin-stdlib-1.5.21.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.25\da76ca59f6a57ee3102f8f9bd9cee742973efa8a\slf4j-api-1.7.25.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-common\1.5.21\cc8bf3586fd2ebcf234058b9440bb406e62dfacb\kotlin-stdlib-common-1.5.21.jar;C:\Users\ivlat\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\13.0\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\annotations-13.0.jar;C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2022.2.3\lib\idea_rt.jar" com.knowledgespike.client.ApplicationKt
Connected to the target VM, address: '127.0.0.1:52769', transport: 'socket'
Exception in thread "main" java.io.IOException: The remote computer refused the network connection.
at java.base/sun.nio.ch.Iocp.translateErrorToIOException(Iocp.java:299)
at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:389)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Disconnected from the target VM, address: '127.0.0.1:52769', transport: 'socket'
Process finished with exit code 1
Apparently, my IIS isn't really set up for the port 9999, as I am getting the error below when I type localhost/127.0.0.1:9999
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
The connection string that the Kotlin code is also using is localhost/127.0.0.1:9999
How would I go about getting the IIS recognize this request/let it through? It really doesn't even have to be IIS. I just want to understand this sample code better, and any sort of sandbox/test web server that allows for this request would more than suffice at this point.
This is the Kotlin code that's throwing the exception when trying to connect:
fun main() = runBlocking {
val client: AsynchronousSocketChannel = AsynchronousSocketChannel.open()
val hostAddress = InetSocketAddress("localhost", PORT)
val tcpSocket = TcpSocket(client)
tcpSocket.connect(hostAddress)
val br = BufferedReader(InputStreamReader(System.`in`))
var line: String
println("Main name is: \t\t\t\t\t${Thread.currentThread().name}")
println("Message to server:")
while (br.readLine().also { line = it } != null) {
val result = async {
println("while:async name is: \t\t\t${Thread.currentThread().name}")
sendMessage(tcpSocket, line)
}
println("while: name is: \t\t\t\t${Thread.currentThread().name}")
if (line == "bye") {
println("End")
break
}
val response: String = result.await()
withContext(Dispatchers.Default) {
println("withContext[Default] name is: \t${Thread.currentThread().name}")
println("response from server: $response")
println("Message to server:")
}
}
}
A webserver listens on a particular port, the default is port 80 for HTTP. Unless you go out of your way to configure it, I expect that's where IIS will be listening
I would start by taking Kotlin out of the question and establish you have a webserver listening on a particular port. Just use a regular web browser to check. Beware the browsers handle comms fails in nice friendly ways, hiding the real issues. Better to use a more technical tool like
curl
Postman
If IIS is suspect, then what IDE are you using? If you are using IntelliJ
find yourself an HTML file,
open it up, then notice in the Top Right several however icons will show up
pick the IntelliJ one, this will start an internal web server and then a web browser will launch to connect to it
try this web server for your tests
I was able to circumvent the error by going to bindings for the default web site in the IIS Manager UI and then adding the port 9999. The Kotlin code connects fine now. I'm pretty sure there are better ways of solving this IRL, but I think it's good enough, as I am just learning Kotlin at this point.
I inherited maintenance of a self-written CGI application without
documentation and have never met the original author. The application
stopped working in Debian 8, but worked in Debian 7 and CentOS 5. The
main changes were the upgrade from Apache 2.2 (used by Debian 7 &
CentOS 5) to Apache 2.4 (used by Debian 8) and the upgrade from perl
5.8 (in CentOS 5) respectively perl 5.14 (in Debian 7) to perl 5.20.
The problematic part boils down to the following script (a
302-redirect):
#!/usr/bin/perl
$|=1; # activate auto-flushing of stdout
use strict;
use warnings;
my $CRLF = "\015\012";
print STDOUT "Status: 302 Moved Temporarily$CRLF" .
"Location: /does_not_matter$CRLF" .
"URI: /does_not_matter$CRLF" .
"Connection: close$CRLF" .
"Content-type: text/html; charset=UTF-8$CRLF$CRLF";
close STDOUT;
while(1) {
sleep 1;
}
The observed behavior is that the redirect never reaches the client
as long as the script is still running when used with Apache 2.4, but
there is no error message in Apache's error.log. I changed the client
(Firefox, Chromium, wget), the Apache module (mod_cgid & mod_cgi),
sent additional headers, removed the close STDOUT, removed the
$|=1, replaced the $CRLF with \n and made the script
fork and exit the parent process (so that Apache is no longer the
parent process), all to no avail. The only things that worked: use
Apache 2.2, turn the script into an NPH-CGI-script (which has to send
complete HTTP headers that Apache will not modify in any way, even if
they contain errors), make the script exit instead of entering an
endless loop. I confirmed via tcpdump that the packages with the
redirect indeed never leave the server before the script is killed.
And from the Date-line in the response and the time of the eventual
arrival I gather that Apache receives my output immediately (&
immediately adds the Date-line to the headers), but does not send the
response to the client.
Don't bother answering, I already figured the solution out by myself
and will write an answer. I just want to make the solution available
to others who might encounter the same problem.
The problem was the missing message body. A 302 redirect may contain
a message body (see RFC 2616, section 4.3 (Message Body): "All other
responses do include a message-body, although it MAY be of zero
length"), but a Content-Length-line is optional (section 4.4 of RFC
2616 says the message body length can be determined by closing the
connection if the Content-Length-line is missing). Since Apache can
not know whether I want to send a message body or not, it has to wait
until I close the connection or actually send the message body
(Apache 2.2 apparently behaved erroneously here by not waiting for
the message body - or maybe close STDOUT; does not do in perl
5.20 what it did in older perl versions). The correct script should
therefore look like this (verified to work both in Apache 2.2 and in
Apache 2.4) - the only difference is an additional $CRLF which
terminates a zero-length message body:
#!/usr/bin/perl
$|=1; # activate auto-flushing of stdout
use strict;
use warnings;
my $CRLF = "\015\012";
print STDOUT "Status: 302 Moved Temporarily$CRLF" .
"Location: /doesNotMatter$CRLF" .
"URI: /doesNotMatter$CRLF" .
"Connection: close$CRLF" .
"Content-type: text/html; charset=UTF-8$CRLF$CRLF$CRLF";
close STDOUT;
while(1) {
sleep 1;
}
It was https://stackoverflow.com/a/8062277/2845840 that pointed me in the right direction.
I have a perl script in my cgi-bin. It first prints out the following statements
print "Status: 200 OK\nContent-Type: text/html\n\n";
It generates a html form on the terminal perfectly but when I try running it on the browser it gives the following error
Internal Server Error The server encountered an internal error or
misconfiguration and was unable to complete your request. Please
contact the server administrator at [no address given] to inform them
of the time this error occurred, and the actions you performed just
before this error.
I have enabled cgi-bin in the apache configuration, the error log prints the following error
End of script output before headers
What could be the problem and how should I resolve it
You must have the Content-Type be the first thing printed back to the screen. Also make sure the script is set as executable.
print "Status: 200 OK\nContent-Type: text/html\n\n";
Should be:
print "Content-Type: text/html\n\nStatus: 200 OK\n";
The script also needs to be executable by Apache for it to work
chmod a+x YourScript.pl
I've tested with the following script and once I fixed the permissions it works just fine. You also only need to set the status if it isn't 200 as that's the default.
#!/usr/bin/perl
use strict;
print "Status: 200\nContent-Type: text/html\n\n";
print "<p>Foo</p>";
I have the following CGI script:
#!c:\cygwin\bin\perl.exe
use CGI qw(:standard);
my $query = $CGI->new;
print header (
-type => "text/html",
-status => "404 File not found"
);
print "<b>File not found</b>";
This gives me an error:
Server error!
The server encountered an internal error and was unable to complete your request.
Error message:
End of script output before headers: test.cgi
If you think this is a server error, please contact the webmaster.
Error 500
127.0.0.1
Apache/2.4.10 (Win32) OpenSSL/1.0.1h PHP/5.4.31
I've looked at this (and other similar) question(s), but there the headers were not being printed, as opposed to mine.
I'm using the XAMPP Windows package with Cygwin Perl.
Can anyone help? Thanks.
I don't know why you are using $CGI instead of CGI
I think It should be
my $query = CGI->new;
tested on Linux working perfect.
So, as others have pointed out, your problem was using a variable ($CGI) where you actually needed a class name (CGI). But, in my mind, this raises two more questions.
1/ Why are you trying to create a CGI object in the first place? You are using the function-based interface to CGI (print header(...) for example) so there's no need for a CGI object.
2/ Why are you writing a CGI program in 2014? Perl web programming has moved on a long way this millennium and you seem to be stuck in the 1990s :-/
I have a PHP script that keeps stopping at the same place every time and my browser reports:
The connection to the server was reset
while the page was loading.
I have tested this on Firefox and IE, same thing happens. So, I am guessing this is an Apache/PHP config problem. Here are few things I have set.
PHP.ini
max_execution_time = 300000
max_input_time = 300000
memory_limit = 256M
Apache (httpd.conf)
Timeout 300000
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 0
Are the above correct? What can be causing this and what can I set?
I am running PHP (5.2.12.12) as a
module on Apache (2.2) on a Windows
Server 2003.
It is very likely this is an Apache or PHP issue as all browsers do the same thing. I think the script runs for exactly 10 mins (600 seconds).
I had a similar issue - turns out apache2 was segfaulting. Cause of the segfault was php5-xdebug for 5.3.2-1ubuntu4.14 on Ubuntu 10.04 LTS. Removing xdebug fixed the problem.
I also had this problem today, it turned out to be a stray break; statement in the PHP code (outside of any switch or any loop), in a function with a try...catch...finally block.
Looks like PHP crashes in this situation:
<?php
function a ()
{
break;
try
{
}
catch (Exception $e)
{
}
finally
{
}
}
This was with PHP version 5.5.5.
Differences between 2 PHP configs were indeed the root cause of the issue on my end. My app is based on the NuSOAP library.
On config 1 with PHP 5.2, it was running fine as PHP's SOAP extension was off.
On config 2 with PHP 5.3, it was giving "Connection Reset" errors as PHP's SOAP extension was on.
Switching the extension off allowed to get my app running on PHP 5.3 without having to rewrite everything.
I had an issue where in certain cases PHP 5.4 + eAccelerator = connection reset. There was no error output in any log files, and it only happened on certain URLs, which made it difficult to diagnose. Turns out it only happened for certain PHP code / certain PHP files, and was due to some incompatibilities with specific PHP code and eAccelerator. Easiest solution was to disable eAccelerator for that specific site, by adding the following to .htaccess file
php_flag eaccelerator.enable 0
php_flag eaccelerator.optimizer 0
(or equivalent lines in php.ini):
eaccelerator.enable="0"
eaccelerator.optimizer="0"
It's an old post, I know, but since I couldn't find the solution to my problem anywhere and I've fixed it, I'll share my experience.
The main cause of my problem was a file_exists() function call.
The file actually existed, but for some reason an extra forward slash on the file location ("//") that normally works on a regular browser, seems not to work in PHP. Maybe your problem is related to something similar. Hope this helps someone!
I'd try setting all of the error reporting options
-b on error batch abort
-V severitylevel
-m error_level
and sending all the output to the client
<?php
echo "<div>starting sql batch</div>\n<pre>"; flush();
passthru('sqlcmd -b -m -1 -V 11 -l 3 -E -S TYHSY-01 -d newtest201 -i "E:\PHP_N\M_Create_Log_SP.sql"');
echo '</pre>done.'; flush();
My PHP was segfaulting without any additional information as to the cause of it as well. It turned out to be two classes calling each other's magic __call() method because both of them didn't have the method being called. PHP just loops until it's out of memory. But it didn't report the usual "Allowed memory size of * bytes exhausted" message, probably because the methods are "magic".
I thought I would add my own experience as well.
I was getting the same error message, which in my case was caused by a PHP error in an exception.
The culprit was a custom exception class that did some logging internally, and a fatal error occurred in that logging mechanism. This caused the exception to not be triggered as expected, and no meaningful message to be displayed either.