Serving a yesod application as a (Fast)CGI - apache

I'm trying to serve a yesod application as a CGI (or FastCGI) program but Apache shows me a 500 error:
[Mon Sep 21 17:35:41.425565 2020] [http:error] [pid 2758] [client 10.0.2.2:43872] AH02429: Response header name '21/Sep/2020' contains invalid characters, aborting request
Starting with a new template with stack new project yesodweb/sqlite, I've tried to convert it to a CGI program by changing src/Application.hs.
I've imported the Wai CGI library with
import Network.Wai.Handler.CGI (run)
and changed the last line of appMain to run app:
-- | The #main# function for an executable running this site.
appMain :: IO ()
appMain = do
-- Get the settings from all relevant sources
settings <- loadYamlSettingsArgs
-- fall back to compile-time values, set to [] to require values at runtime
[configSettingsYmlValue]
-- allow environment variables to override
useEnv
-- Generate the foundation from the settings
foundation <- makeFoundation settings
-- Generate a WAI Application from the foundation
app <- makeApplication foundation
-- Run the application with Warp
--runSettings (warpSettings foundation) app
run app
I thought this was the minimal change to serve it as a CGI program but apparently is not working.
I've already looked into yesod's book chapter on deploying your Webapp which has been handy to write the apropriate Apache configuration so the server could ran the app. It says nothing about the nedded changes to the app code which I presume is where the problem is.
I've also checked this stackoverflow question but it's from almost 8 years ago so it's outdated now.

The problem is that the default makeFoundation logs to standard output, which is also where the CGI program is supposed to send its response, so you're getting intermingling of response headers with log output, and Apache tries to parse log lines as HTTP headers, etc.
If you replace newStdoutLoggerSet with newStderrLoggerSet, it should work, and the log output will end up in Apache's "error.log" or equivalent.

Related

Downloading SetupTools in Maximo/Jython fails with HTTP error 403 SSL is required

Appendix A of The Definitive Guide to Jython describes downloading SetupTools for use with Jython.
https://jython.readthedocs.io/en/latest/appendixA/
This indicates to me that it should be possible to download and use SetupTools from within a Jython automation script in Maximo (v7.6 in my case). The book points us to the following url to copy a Jython script that will do this:
http://peak.telecommunity.com/dist/ez_setup.py
I add one line to the above script to call the function "use_setuptools":
use_setuptools()
Then I create a push button on a Maximo application and associate the aforementioned script with the button press I get the following error:
System Message BMXAA7837E - An error occured that prevented the
EZ_SETUP script for the EZ_SETUP launch point from running.
urllib2.HTTPError: HTTP Error 403: SSL is required in at line
number 280
The stack trace points to the following line in the function "download_setuptools" which is called by "use_setuptools":
src = urllib2.urlopen(url)
This appears to be because the url requested, in my case:
http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c11-py2.5.egg
...is redirected a few times before arriving at the following url:
https://files.pythonhosted.org/packages/98/d3/ed3bc7e3f4b143092862dab99d984261ac4be6a40d4fb1e66d2a10e9ea99/setuptools-0.6c11-py2.5.egg
Note the url uses HTTPS not HTTP. The following indicates why this may be so:
https://sourceforge.net/p/pypi/support-requests/300/
The jython.jar included with Maximo does not include the ssl module so we could either:
Download the ssl module manually and copy it to the correct location on the server.
Download the appropriate egg file manually over HTTPS and copy it to the correct location on the server.
Bypass the problem by creating a mirror for the file we're looking for that is accessible over HTTP and use that url in the code.
Whilst these are feasible I'd prefer to modify the code to ignore the SSL certificate if possible, however all the workarounds on StackOverflow and elsewhere seem to require that you're able to "import ssl" in order to bypass it which rather seems to defeat the purpose.
Ideally I'm looking for a solution that modifies the code from the url provided above to get it to work with Maximo/Jython 2.5.2 and doesn't require downloading and adding new modules or packages and all that this entails with Maximo. Bypassing or temporarily disabling ssl is fine as the code checks the hash of the downloaded .egg file. This would be my preferred solution if possible.
In my experience, automation scripting works best if you can stay "as Java as possible" and "as Maximo as possible". So, I would use the LIB_HTTPCLIENT script from the Scripting 76 Features document (the first example code, whose name is given by inference in the second bit of code) to try to download the SetupTools.
In case that document moves again, here is the LIB_HTTPCLIENT script. Note that the url variable is expected to be passed to this library script by the calling script.
from psdi.iface.router import HTTPHandler
from java.util import HashMap
from java.util import String
handler = HTTPHandler()
map = HashMap()
map.put("URL",url)
map.put("HTTPMETHOD","GET")
responseBytes = handler.invoke(map,None)
response = String(responseBytes,"utf-8")

Centos server hanged due to postfix/sendmail spam emails

My centos server is running web applications in LAMP stack. A couple of days back, the server was not responding for about 10 mins and I got http response failure alert from my monitoring tool. When I checked the httpd error log I found a huge log entry (~12000 lines) related to sendmail.
14585 sendmail: fatal: open /etc/postfix/main.cf: Permission denied
The server ran out of memory and not responding.
14534 [Fri Aug 19 22:14:52.597047 2016] [mpm_prefork:error] [pid 26641] (12)Cannot allocate memory: AH00159: fork: Unable to fork new process
14586 /usr/sbin/sendmail: error while loading shared libraries: /lib64/librt.so.1: cannot allocate version reference table: Cannot allocate memory
We are not using sendmail in any of our application. How can I stop this attack in future?
Thank you in advance!
Sorry I have no comment facilities; it looks like one of your website pages is vulnarable for code injection, finding out where and what page may be a huge job. Focus on input (forms) variables. Always sanitize input variables before using them! P.s. php uses "sendmail", even if you use Postfix, it will use a sendmail binary to send mail and the sendmail binary will redirect it to Postfix. If your forms work well and the 12k error log lines come out of the blue, then I would think someone is trying to inject code through your website (happens all the time by the way).

Apache custom dynamic error response

I've seen hundreds of pages explaining how to create custom error pages in Apache 2 server. My question is different. I have a web application running in Apache (it is a ISAPI DLL, but it could also be a CGI executable). My application can handle internal server errors and generate a detailed error message (for instance, include a full stack trace), included in the response together with error code 500. AFAIK, Apache just let me use redirection in order to display custom error messages: http://httpd.apache.org/docs/2.2/custom-error.html
HTTP spec (RFC 2616 - section 10), not only allows but also recommend that detailed error message should be included in the BODY section of the response in case of error code > 500.
Link: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5
Seems that Apache won't let my custom error message go to the browser, and always replace it with its own internal error message and I believe that it is not the correct behavior, based on RFC 2616.
So my question is: Is there any setting in Apache server that will let my custom message go to the browser? Or, is there anything that can be done in my application that will instruct Apache to send my custom error message (something like some specific header field in the response)?
More on the subject:
When my ISAPI application returns error code 500, with other error information in the response body, Apache replaces it with its standard "500 Internal Server Error" message/HTML content, and inside Error.log file I can see the "useless" "Premature end of script headers" message. I'm deeply sure that my headers are fine, including the Content-Type field.
If I replace the 500 error code with any other server error code (e.g. 501) it works flawlessly and my response goes to the browser as is. The same header is sent to the Apache server, only the error code is different (501, instead of 500). With this test result in mind, one of these two must be true:
1- Apache requires some specific header field when status code is 500
2- Apache won't let custom error messages with status code 500 go to the browser.
I don't see any other alternative.
I think you're conflating two questions. You can generate a 500 response with a CGI script and include your custom body. Or you can override any 500 with any resource you want.
If you're failing to do the former, it's likely because of some subtle thing in the ISAPI interface between Apache and your module. Desk-checking the code says you should be able either set the pseudo
Status: 500
Header, or basically return any ISAPI error and end up with a 500 and your custom body.
Apache has two notions of a status code -- the one in the status line (r->status) and an error code returned separately from the module that handles the request (return HTTP_INTERNAL_SERVER_ERROR, return r->status).
When the former is used as the latter is when the custom error messages get lost. All of that happens in./modules/arch/win32/mod_isapi.c in Apache. Whatever is going on, it is ISAPI unique.

Request entity too large 413 apache tomcat

Request entity too large
The requested resource
/some/url/path/on/server
does not allow request data with GET requests, or the amount of data provided in the request exceeds the capacity limit.
I get a corresponding error in my mod_jk.log file which is below.
[Mon Oct 10 20:36:11 2011] [9834:0] [error] ajp_marshal_into_msgb::jk_ajp_common
.c (415): failed appending the header value
I have a web farm running tomcat5, fronted by apache1.3 using the mod_jk connector. I started getting this error today on all the servers although no code changes were made today. The error seems to popup randomly. The same request doesn't always generate the error.
Can anyone explain the cause and why it would be random? I have seen recommendations to increase max_packet_size in server.xml. I want to understand the problem and the impact of the change before making it.

Weird~Apache can not find the actually existing "bash" to execute my cgi file~

May be it's too easy for you to answer.
My problem is about cgi and apache web server.
Make it simple, I have a html "form.html" containing a form in it. To access it, typing "127.0.0.1/form.html" in browser.
After clicking "submit" in this html file, it is supposed to adress to "127.0.0.1\cgi-bin\cginame.cgi", the content of "cginame.cgi" is as below:
#!/bin/bash
if [ $REQUEST_METHOD="GET" ]
then
data=$QUERY_STRING
else
data='cat'
fi
java mortcal $data
"mortcal" is a java program calculating and return a HTML page containing results to user.
I'm using apache 2.2 and ubuntu 10.04.
The problem is when I click the "submit" button in "form.html", I got these in error log:
[Sat Sep 24 15:00:20 2011] [error] (2)No such file or directory: exec of '/usr/lib/cgi-bin/mortcgi.cgi' failed
[Sat Sep 24 15:00:20 2011] [error] [client 127.0.0.1] Premature end of script headers: mortcgi.cgi
I know it's because apache can not find "/bin/bash" to execute the cgi file. But I do have "/bin/bash".
It's so weird. Please help me out. Thank you in advance.
To execute CGI scripts, you need to configure Apache to allow this, and your script has to follow the HTTP protocol by sending back data in the right format, and right permissions, and on and on and on.
Here's a great tutorial with an example: http://httpd.apache.org/docs/2.2/howto/cgi.html
... however, I need to say: running a java program from within a shell script via Apache is a bad idea, in general. Each request loads the java runtime engine (JRE), runs the program, then unloads it. There are issues with environment, file ownership and so on -- all of this is why there are application servers like tomcat for java. So if you're just trying something, that's fine. If you're thinking this is a good way to get something done in a professional production environment, I would reconsider.
As noted, this seems like a poor way to do things, but:
Do the script file permissions allow execution for the web server user?
Are you using any security framework such as selinux which would apply additional restrictions?
I checked my configuration files. They are ok. So I kept searching on the web and finally I saw this:
"If you've copied over the script from a Windows machine, you may be being tripped up by ^M at end of line. You can use cat -v /usr/lib/cgi-bin/printenv.pl | head -1 to verify that there isn't a ^M at the end of the line. "
I did copy my cgi file from windows! I forgot to mention it because I did not think it's a big deal.
Now I have removed the ^M by typing this" :%s/^V^M//g in vi. This problem is resolved. Thanks very much for your answer, Mr.Harrison and Dark Falcon, Thank you all.