diff --git a/inc/actions.php b/inc/actions.php
index e0ad908b74c39472ca274f3ec8f23f317fcae760..da3414eb203dd9c939029bd5592bb831ae1385d4 100644
--- a/inc/actions.php
+++ b/inc/actions.php
@@ -172,7 +172,7 @@ function act_dispatch(){
     $evt->advise_after();
     // Make sure plugs can handle 'denied'
     if($conf['send404'] && $ACT == 'denied') {
-        header('HTTP/1.0 403 Forbidden');
+        http_status(403);
     }
     unset($evt);
 
@@ -658,7 +658,7 @@ function act_sitemap($act) {
     global $conf;
 
     if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
-        header("HTTP/1.0 404 Not Found");
+        http_status(404);
         print "Sitemap generation is disabled.";
         exit;
     }
@@ -690,7 +690,7 @@ function act_sitemap($act) {
         exit;
     }
 
-    header("HTTP/1.0 500 Internal Server Error");
+    http_status(500);
     print "Could not read the sitemap file - bad permissions?";
     exit;
 }
diff --git a/inc/auth.php b/inc/auth.php
index 7f427bd8d14f5390b245344608a79c59f96f0b82..9566a26157e71ddd07948555bdb1c76587e72fe5 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -267,7 +267,7 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
 function auth_validateToken($token) {
     if(!$token || $token != $_SESSION[DOKU_COOKIE]['auth']['token']) {
         // bad token
-        header("HTTP/1.0 401 Unauthorized");
+        http_status(401);
         print 'Invalid auth token - maybe the session timed out';
         unset($_SESSION[DOKU_COOKIE]['auth']['token']); // no second chance
         exit;
diff --git a/inc/httputils.php b/inc/httputils.php
index 4ba287eb50d513764cdfd6f20e87e6da061e21df..d3f3cdde279e731d7e570679167f8f0baa6e225e 100644
--- a/inc/httputils.php
+++ b/inc/httputils.php
@@ -250,6 +250,11 @@ function http_cached_finish($file, $content) {
     }
 }
 
+/**
+ * Fetches raw, unparsed POST data
+ *
+ * @return string
+ */
 function http_get_raw_post_data() {
     static $postData = null;
     if ($postData === null) {
@@ -257,3 +262,69 @@ function http_get_raw_post_data() {
     }
     return $postData;
 }
+
+/**
+ * Set the HTTP response status and takes care of the used PHP SAPI
+ *
+ * Inspired by CodeIgniter's set_status_header function
+ *
+ * @param int    $code
+ * @param string $text
+ */
+function http_status($code = 200, $text = '') {
+    static $stati = array(
+        200 => 'OK',
+        201 => 'Created',
+        202 => 'Accepted',
+        203 => 'Non-Authoritative Information',
+        204 => 'No Content',
+        205 => 'Reset Content',
+        206 => 'Partial Content',
+
+        300 => 'Multiple Choices',
+        301 => 'Moved Permanently',
+        302 => 'Found',
+        304 => 'Not Modified',
+        305 => 'Use Proxy',
+        307 => 'Temporary Redirect',
+
+        400 => 'Bad Request',
+        401 => 'Unauthorized',
+        403 => 'Forbidden',
+        404 => 'Not Found',
+        405 => 'Method Not Allowed',
+        406 => 'Not Acceptable',
+        407 => 'Proxy Authentication Required',
+        408 => 'Request Timeout',
+        409 => 'Conflict',
+        410 => 'Gone',
+        411 => 'Length Required',
+        412 => 'Precondition Failed',
+        413 => 'Request Entity Too Large',
+        414 => 'Request-URI Too Long',
+        415 => 'Unsupported Media Type',
+        416 => 'Requested Range Not Satisfiable',
+        417 => 'Expectation Failed',
+
+        500 => 'Internal Server Error',
+        501 => 'Not Implemented',
+        502 => 'Bad Gateway',
+        503 => 'Service Unavailable',
+        504 => 'Gateway Timeout',
+        505 => 'HTTP Version Not Supported'
+    );
+
+    if($text == '' && isset($stati[$code])) {
+        $text = $stati[$code];
+    }
+
+    $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : false;
+
+    if(substr(php_sapi_name(), 0, 3) == 'cgi') {
+        header("Status: {$code} {$text}", true);
+    } elseif($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') {
+        header($server_protocol." {$code} {$text}", true, $code);
+    } else {
+        header("HTTP/1.1 {$code} {$text}", true, $code);
+    }
+}
diff --git a/inc/parser/code.php b/inc/parser/code.php
index 21fb0dc3c25d1423330bc0f162f97a866a14a6a9..43d8d703fe90b76e40a18883cff884b94e8efc4b 100644
--- a/inc/parser/code.php
+++ b/inc/parser/code.php
@@ -43,7 +43,7 @@ class Doku_Renderer_code extends Doku_Renderer {
      * This should never be reached, if it is send a 404
      */
     function document_end() {
-        header("HTTP/1.0 404 Not Found");
+        http_status(404);
         echo '404 - Not found';
         exit;
     }
diff --git a/lib/exe/detail.php b/lib/exe/detail.php
index e597db3a29911ae8aba0aae5f8e0c1f823c4336c..db635c016180bbb8f31d997f57967b190197db18 100644
--- a/lib/exe/detail.php
+++ b/lib/exe/detail.php
@@ -31,7 +31,7 @@ if($AUTH >= AUTH_READ){
     $SRC = mediaFN($IMG);
     if(!@file_exists($SRC)){
         //doesn't exist!
-        header("HTTP/1.0 404 File not Found");
+        http_status(404);
         $ERROR = 'File not found';
     }
 }else{
diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php
index 73e74af406a73c7e8436279c2a177e0c071af1f5..9bac4d272abd26b6dcff454457f10095681a929a 100644
--- a/lib/exe/fetch.php
+++ b/lib/exe/fetch.php
@@ -58,7 +58,7 @@ if(!defined('SIMPLE_TEST')) {
         }
         // send any non 200 status
         if($data['status'] != 200) {
-            header('HTTP/1.0 '.$data['status'].' '.$data['statusmessage']);
+            http_status($data['status'], $data['statusmessage']);
         }
         // die on errors
         if($data['status'] > 203) {
@@ -137,7 +137,7 @@ function sendFile($file, $mime, $dl, $cache) {
     if($fp) {
         http_rangeRequest($fp, filesize($file), $mime);
     } else {
-        header("HTTP/1.0 500 Internal Server Error");
+        http_status(500);
         print "Could not read $file - bad permissions?";
     }
 }
diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
index 04dd178cc82a81ac2c242bf102d53d34f0896424..e0a90a291218e63ccb68a3918bab81b4d4d49ecb 100644
--- a/lib/exe/mediamanager.php
+++ b/lib/exe/mediamanager.php
@@ -36,7 +36,7 @@
 
     // do not display the manager if user does not have read access
     if($AUTH < AUTH_READ && !$fullscreen) {
-        header('HTTP/1.0 403 Forbidden');
+        http_status(403);
         die($lang['accessdenied']);
     }
 
@@ -48,7 +48,7 @@
         $_FILES['upload'] =& $_FILES['Filedata'];
         $JUMPTO = media_upload($NS,$AUTH);
         if($JUMPTO == false){
-            header("HTTP/1.0 400 Bad Request");
+            http_status(400);
             echo 'Upload failed';
         }
         echo 'ok';
diff --git a/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php
index 5e6c197d03769b15723733b133251dffe6c71379..c09daa17c00d76c8e65a4f5c515e30167f48934d 100644
--- a/lib/exe/xmlrpc.php
+++ b/lib/exe/xmlrpc.php
@@ -29,10 +29,10 @@ class dokuwiki_xmlrpc_server extends IXR_Server {
             return $result;
         } catch (RemoteAccessDeniedException $e) {
             if (!isset($_SERVER['REMOTE_USER'])) {
-                header('HTTP/1.1 401 Unauthorized');
+                http_status(401);
                 return new IXR_Error(-32603, "server error. not authorized to call method $methodname");
             } else {
-                header('HTTP/1.1 403 Forbidden');
+                http_status(403);
                 return new IXR_Error(-32604, "server error. forbidden to call the method $methodname");
             }
         } catch (RemoteException $e) {