We have a web application. The backend is an Apache Web Server (Version 2.2).
As described in the following document
https://httpd.apache.org/docs/2.4/custom-error.html
we have configured an ErrorDocument for 404 which redirects to a cgi program.
ErrorDocument 404 /cgi-bin/log_false_request.pl
In the program "log_false_request" we write the ip address, the user-agent and
the original URL (request uri) of the request to a log file.
When an http error 500 happens and the request is a post, it would also be
interesting to have the post body.
Does apache also redirect the response body in case of a post request?
Thanks alot in advance.
Why can't I see why Apache returns 403?!
If I look in the access log the only information I get is
193.162.142.166 - - [29/Jan/2014:18:34:26 +0100] "POST /api_test/callback.php HTTP/1.1" 403 2293
How can I get more information about why the request is forbidden/rejected?
The call is made from a payment gateway...
If the callback URL is a http request there are no problems and returns 200 OK
If the callback URL is a https my server returns 403.. I need to know why?
The server has SSL and openSSL installed and it works!
Have tried to do the https request from http://web-sniffer.net/ and then there are no problems..
I don't get it.. There must be something in the request headers from the payment gateway which results in 403
update
error log
[Wed Jan 29 20:45:55 2014] [error] No hostname was provided via SNI for a name based virtual host
solution
Ok it looks like the client doesn't support SNI
http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
Use the LogLevel directive to adjust how verbose the error logs are and increase until you can see what you want.
httpd 2.4 has better messages in a lot of respect and expensive list of LogLevel settings than 2.2. So if you're using 2.2 it may be a bit harder to figure this out.
When my script respond with status 204 No Content response, Apache adds Content-Type header automatically, even there is no content, just HTTP headers.
Is there a way to force Apache to not include Content-Type header with status 204 in httpd.conf or .htaccess configuration files, or even by any other way?
This has been discussed all through Stackoverflow but I have not been able to find the solution for getting this to work. I even tried following alot of what was discussed in this post (Issues with CORS. Flask <-> AngularJS) since it was closly related to my setup, but I am still pretty much lost.
I have a python flask api server running locally. I have named this domain bac-api. Here is what this vhost looks like.
<VirtualHost *:80>
ServerName bac-api
WSGIDaemonProcess bacapi python-path=/home/lumberjacked/workspace/bas/development/lib/python2.7/site-packages
WSGIScriptAlias / /home/lumberjacked/workspace/bas/development/bac-api/bacapi.wsgi
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, application/json"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS"
<Directory /home/lumberjacked/workspace/bas/development/bac-api>
WSGIProcessGroup bacapi
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
#SSLEngine on
#SSLCertificateFile /etc/apache2/ssl/bac_api_ssl.crt
#SSLCertificateKeyFile /etc/apache2/ssl/bac_api_ssl.key
</VirtualHost>
I have an angularjs site running as my front-end on a separate domain called manage.bac. I am writing an authentication service that connects to the bac-api and posts an api key and/or user credentials asking the server if the user is authenticated or not.
I can curl over to the server and this works and returns a response.
curl -X POST -H "Content-Type: application/json" -d '{ "api": "7f3d6d7338b921ae4ca95cecc452ef1790005ec10c2343fabe5a59ea" }' http://bac-api/authenticated/
response -- {"authenticated": false}
Also going to manage.bac and placing my login creditials email#email.com and password I get the same response but also I have configured it to return a 401 if you are not authenticated with a stored session.
POST http://bac-api/authenticated/ 401 (UNAUTHORIZED) bac-api/authenticated/:1
The problems start when I switch over to ssl certs and port 443. So If on both domains I switch the vhost to port 443 and uncomment the ssl certs. After restarting apache there are no errors and the domains work as far as not showing any kind of 500 error or anything like that. I can curl over to the bac-api server using https and get a response.
curl -k -X POST -H "Content-Type: application/json" -d '{ "api": "7f3d6d7338b921ae4ca95cecc452ef1790005ec10c2343fabe5a59ea" }' https://bac-api/authenticated/
response -- {"authenticated": false}
But as soon as I go to https://manage.bac and redirect to the login page, all the trouble seems to start.
As soon as I click inside the login fields that console throws this error and I do not know if it is related or not.
Blocked a frame with origin "https://manage.bac" from accessing a frame with origin "chrome-extension://hdokiejnpimakedhajhdlcegeplioahd". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "chrome-extension". Protocols must match.
Here is my angularjs authentication code with the console.log methods outputting some stuff.
$http.post('https://bac-api/login/', user)
.success( function( user ) {
console.log('success');
console.log(user);
})
.error( function( error ) {
console.log('error');
console.log(error);
});
Object {email: "email#email.com", password: "password"} authentication-service.js:36
error authentication-service.js:50
authentication-service.js:51
When this error comes back there isn't anything in the response at all. I can see inside the network tab of chrome tools that this request is getting pre-flighted because it is sending an OPTIONS over to the server.
OPTIONS /login/ HTTP/1.1
Host: bac-api
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: https://manage.bac
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Also I can see in the Network tab it is showing up as an OPTIONS and it has been cancelled. Which I do not know what that means.
I have configured inside angularjs with these options but it doesn't seem to make a difference on anything.
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
Also inside my flask application tried implementing the decorator mentioned here http://flask.pocoo.org/snippets/56/ and also mentioned in other stackoverflow posts. This doesn't seem to do anything either. Also I assumed that because I put inside my vhost the access headers for the api server that I really didn't need to do the same thing in the app. Though I could be totally wrong because I dont have a clue on what I'm doing.
Any help is really appreciated. I am sorry if this seems like a duplicate issue but so far I cannot get this to work and I have tried every post on stackoverflow that I can to solve this issue.
--- Edit with updated information
This morning as an experiment I switched both vhosts back over to port 80 and commented out all Allow access headers. Restarted and tried logging in again, here are my results.
Failed to load resource: Origin http://manage.bac is not allowed by Access-Control-Allow-Origin. http://bac-api/authenticated/
XMLHttpRequest cannot load http://bac-api/authenticated/. Origin http://manage.bac is not allowed by Access-Control-Allow-Origin. manage.bac/:1
So after this error I went inside my bac-api vhost and un-commented Header set Access-Control-Allow-Origin "*" and re-started again and tried logging in. Here are the new errors that display.
OPTIONS http://bac-api/authenticated/ Request header field Content-Type is not allowed by Access-Control-Allow-Headers. angular.js:9312
(anonymous function) angular.js:9312
sendReq angular.js:9146
$http angular.js:8937
Authenticator.isLoggedIn authentication-service.js:13
RouteConfig.login.resolve.Auth state-service-provider.js:16
invoke angular.js:2902
(anonymous function) angular-ui-router.js:801
forEach angular.js:137
resolve angular-ui-router.js:797
resolveState angular-ui-router.js:813
transitionTo angular-ui-router.js:704
(anonymous function) angular-ui-router.js:615
invoke angular.js:2902
handleIfMatch angular-ui-router.js:433
rule angular-ui-router.js:452
update angular-ui-router.js:487
Scope.$broadcast angular.js:8307
afterLocationChange angular.js:5649
(anonymous function) angular.js:5637
Scope.$eval angular.js:8057
Scope.$digest angular.js:7922
Scope.$apply angular.js:8143
(anonymous function) angular.js:981
invoke angular.js:2895
resumeBootstrapInternal angular.js:979
bootstrap angular.js:993
angularInit angular.js:954
(anonymous function) angular.js:14843
c jquery-1.10.1.min.js:4
p.fireWith jquery-1.10.1.min.js:4
x.extend.ready jquery-1.10.1.min.js:4
q jquery-1.10.1.min.js:4
XMLHttpRequest cannot load http://bac-api/authenticated/. Request header field Content- Type is not allowed by Access-Control-Allow-Headers. manage.bac/:1
So to resolve this error and allow the Content-Type through I go back to my bac-api vhost and I add back Header set Access-Control-Allow-Headers "Content-Type". After restarting browsing to manage.bac on page load here are those results.
POST http://bac-api/authenticated/ 401 (UNAUTHORIZED) bac-api/authenticated/:1
Which this is good because it means I received an {"authenticated": false} response and it sent back a 401 unauthorized. If I continue and try to log in I get these results.
Object {email: "email#email.com", password: "password"} authentication-service.js:36
success authentication-service.js:40
Object {login: false} authentication-service.js:41
This also is working. Here is the angularjs code that is producing this output.
$http.post('http://bac-api/login/', user)
.success( function( user ) {
console.log('success');
console.log(user);
})
.error( function( error ) {
console.log('error');
console.log(error);
});
Now my thoughts were awesome if its working on port 80 I can switch it over to port 443 now and keep rolling. So I switch the vhosts to port 443 and browse to manage.bac again to log in. On page load before even trying to log in I get these results.
And again when I try to log in and submit the form I get these results also.
Object {email: "email#email.com", password: "password"} authentication-service.js:36
error authentication-service.js:50
authentication-service.js:51
And also on the Network tab
This was just to try and give every body more information in helping me find the reason for this problem.
----- Edit again with more information
Tonight I started trying to test this with curl and see what headers were coming back with an OPTIONS request
Here is the curl request I copied it directly out of the Network tab assuming this was the same OPTIONS request that angularjs is sending over. First Ill put the OPTIONS request from the network tab and then my curl request.
OPTIONS https://bac-api/login/ HTTP/1.1
Access-Control-Request-Method: POST
Origin: https://manage.bac
Referer: https://manage.bac/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-requested-with, content-type
curl -i -k -X OPTIONS -H "Access-Control-Request-Method: POST" -H "Origin: https://manage.bac" -H "Referer: https://manage.bac/" -H "Access-Control-Request-Headers: accept, origin, content-type" https://bac-api/login/
Here is the response from curl
HTTP/1.1 200 OK
Date: Tue, 01 Oct 2013 02:51:17 GMT
Server: Apache/2.2.22 (Ubuntu)
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Max-Age: 21600
Content-Length: 0
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
This seems to indicate that the server is configured correctly and responding to OPTIONS requests with the correct headers. But as I have posted in the pictures above when I run this in the browser still on the Network tab it is getting cancelled and nothing comes back in the error response.
I was able to solve this problem and it was the stupidest thing. I will dig up the other stackoverflow posts that helped lead me to the solution. But basically during testing I generated self signed certificates to use locally. Apparently both firefox and chrome will automatically cancel your requests if it does not trust the certificates when doing cross domain posts. I had to go into both chrome and firefox to add the certificates and mark them as trusted before they stopped cancelling the request. Now everything works perfectly.
Also in this investigation I found out that you do not need to add into Flask the requests helper to add headers to your responses and in your Apache configuration. If you put them in both it will add headers both times. In my configuration I chose to add it to my Apache configuration because it made my python code alot cleaner.
I'm running Magento Enterprise 1.9 with APC caching on Apache (Debian).
If I browse to a non-existent URL on my site, I receive a 404 response from the server and am presented with my 404 page as expected. However, if I then visit that same URL again, this time (and all subsequent times) I receive a "200 OK" status from the server, despite the URL still being invalid and the 404 page still being presented.
Examples:
$ curl -I http://www.example.com/some-nonexistent-URL
$ HTTP/1.1 404 Not Found
$ curl -I http://www.example.com/some-nonexistent-URL
$ HTTP/1.1 200 OK
I am assuming that this is because the resposne to that URL is being cached somehow so the server sends out a "200 OK" cached version of the 404 page (!).
How can I prevent this?
This was Magento's Full Page Cache fault.
I discovered Magento checks for the presence of a cookie called NO_CACHE, so I just put $_COOKE["NO_CACHE"] = true; at the point before the 404 action is called (in my case, /app/code/core/Mage/Cms/controllers/IndexController.php).
I also added a cache-control: no-cache, must revalidate header, and the same cookie as above into the 404 page template itself for good measure.