mod_auth_form.c revision 72616b8c71552364179298938efc55e0611aaec3
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes/* Licensed to the Apache Software Foundation (ASF) under one or more
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * contributor license agreements. See the NOTICE file distributed with
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * this work for additional information regarding copyright ownership.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * The ASF licenses this file to You under the Apache License, Version 2.0
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * (the "License"); you may not use this file except in compliance with
70953fb44a7140fe206c3a5f011e24209c8c5c6abnicholes * the License. You may obtain a copy of the License at
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Unless required by applicable law or agreed to in writing, software
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * distributed under the License is distributed on an "AS IS" BASIS,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * See the License for the specific language governing permissions and
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * limitations under the License.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "apr_md5.h" /* for apr_password_validate */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "apr_base64.h" /* for apr_base64_decode et al */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#define FORM_REDIRECT_HANDLER "form-redirect-handler"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int (*ap_session_load_fn) (request_rec * r, session_rec ** z) = NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void (*ap_session_get_fn) (request_rec * r, session_rec * z,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void (*ap_session_set_fn) (request_rec * r, session_rec * z,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int (*ap_parse_request_form_fn) (request_rec * r, ap_filter_t *f,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void (*ap_request_insert_filter_fn) (request_rec * r) = NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void (*ap_request_remove_filter_fn) (request_rec * r) = NULL;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholestypedef struct {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *site;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *method;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *body;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *logout;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void *create_auth_form_dir_config(apr_pool_t * p, char *d)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Any failures are fatal. */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* form size defaults to 8k */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* default form field names */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic void *merge_auth_form_dir_config(apr_pool_t * p, void *basev, void *addv)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *new = (auth_form_config_rec *) apr_pcalloc(p, sizeof(auth_form_config_rec));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *add = (auth_form_config_rec *) addv;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *base = (auth_form_config_rec *) basev;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->providers = !add->providers ? base->providers : add->providers;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->authoritative = (add->authoritative_set == 0) ? base->authoritative : add->authoritative;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->authoritative_set = add->authoritative_set || base->authoritative_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->site = (add->site_set == 0) ? base->site : add->site;
0a39e7683f6611d66c55712f50bb240428d832a1bnicholes new->username = (add->username_set == 0) ? base->username : add->username;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->username_set = add->username_set || base->username_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->password = (add->password_set == 0) ? base->password : add->password;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->password_set = add->password_set || base->password_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->location = (add->location_set == 0) ? base->location : add->location;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->location_set = add->location_set || base->location_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->form_size = (add->form_size_set == 0) ? base->form_size : add->form_size;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->form_size_set = add->form_size_set || base->form_size_set;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->fakebasicauth = (add->fakebasicauth_set == 0) ? base->fakebasicauth : add->fakebasicauth;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->fakebasicauth_set = add->fakebasicauth_set || base->fakebasicauth_set;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->method = (add->method_set == 0) ? base->method : add->method;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->method_set = add->method_set || base->method_set;
036436f4f4cdcd76186c0058891216545967043bbnicholes new->mimetype = (add->mimetype_set == 0) ? base->mimetype : add->mimetype;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->mimetype_set = add->mimetype_set || base->mimetype_set;
41022996c916eb4ab2ec3204eb491b64779eb100bnicholes new->body = (add->body_set == 0) ? base->body : add->body;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->disable_no_store = (add->disable_no_store_set == 0) ? base->disable_no_store : add->disable_no_store;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->disable_no_store_set = add->disable_no_store_set || base->disable_no_store_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->loginsuccess = (add->loginsuccess_set == 0) ? base->loginsuccess : add->loginsuccess;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->loginsuccess_set = add->loginsuccess_set || base->loginsuccess_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->loginrequired = (add->loginrequired_set == 0) ? base->loginrequired : add->loginrequired;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->loginrequired_set = add->loginrequired_set || base->loginrequired_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->logout = (add->logout_set == 0) ? base->logout : add->logout;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes new->logout_set = add->logout_set || base->logout_set;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *add_authn_provider(cmd_parms * cmd, void *config,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *arg)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes newp->provider_name = apr_pstrdup(cmd->pool, arg);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* lookup and cache the actual provider now */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * by the time they use it, the provider should be loaded and
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * registered with us.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "Unknown Authn provider: %s",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* if it doesn't provide the appropriate function, reject it */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "The '%s' Authn provider doesn't support "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return "You must load mod_session to enable the mod_auth_form "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "functions";
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!ap_parse_request_form_fn || !ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_parse_request_form_fn = APR_RETRIEVE_OPTIONAL_FN(ap_parse_request_form);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_request_insert_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_insert_filter);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ap_request_remove_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_remove_filter);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!ap_parse_request_form_fn || !ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return "You must load mod_request to enable the mod_auth_form "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "functions";
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Add it to the list now. */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Sanity check a given string that it exists, is not empty,
e961abd49ab1b184b356f63591d37083a5651451bnicholes * and does not contain special characters.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *check_string(cmd_parms * cmd, const char *string)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return apr_pstrcat(cmd->pool, cmd->directive->directive,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes " cannot be empty, or contain '=' or '&'.",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_location(cmd_parms * cmd, void *config, const char *location)
6f2fa094a76c27135a9825ca9492f9db0a1a3bc9bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_username(cmd_parms * cmd, void *config, const char *username)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
9558e9fdb620dd6f42ca93beac6c3ab734086706bnicholesstatic const char *set_cookie_form_password(cmd_parms * cmd, void *config, const char *password)
9558e9fdb620dd6f42ca93beac6c3ab734086706bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_method(cmd_parms * cmd, void *config, const char *method)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_mimetype(cmd_parms * cmd, void *config, const char *mimetype)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_body(cmd_parms * cmd, void *config, const char *body)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_cookie_form_size(cmd_parms * cmd, void *config,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *arg)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (APR_SUCCESS != apr_strtoff(&size, arg, NULL, 0)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return "AuthCookieFormSize must be a size in bytes, or zero.";
9558e9fdb620dd6f42ca93beac6c3ab734086706bnicholesstatic const char *set_login_required_location(cmd_parms * cmd, void *config, const char *loginrequired)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_login_success_location(cmd_parms * cmd, void *config, const char *loginsuccess)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_logout_location(cmd_parms * cmd, void *config, const char *logout)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_site_passphrase(cmd_parms * cmd, void *config, const char *site)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
e76fdcdfb8994ad70776526f50fa013b3e9a6033bnicholesstatic const char *set_fake_basic_auth(cmd_parms * cmd, void *config, int flag)
e76fdcdfb8994ad70776526f50fa013b3e9a6033bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
509d30fddc88d129f9ba0f6000b802afa021fe52bnicholesstatic const char *set_disable_no_store(cmd_parms * cmd, void *config, int flag)
509d30fddc88d129f9ba0f6000b802afa021fe52bnicholes auth_form_config_rec *conf = (auth_form_config_rec *) config;
2e3a086879b1ac9681ea9ccf458096236f500dccbnicholes AP_INIT_ITERATE("AuthFormProvider", add_authn_provider, NULL, OR_AUTHCFG,
0f7cc4b1d3c42262bcdced99f682778963e83ea7bnicholes "specify the auth providers for a directory or location"),
5a1101aa8bb19d6bafb6c7808a56f49a95b0b769bnicholes AP_INIT_TAKE1("AuthFormUsername", set_cookie_form_username, NULL, OR_AUTHCFG,
5a1101aa8bb19d6bafb6c7808a56f49a95b0b769bnicholes "The field of the login form carrying the username"),
5a1101aa8bb19d6bafb6c7808a56f49a95b0b769bnicholes AP_INIT_TAKE1("AuthFormPassword", set_cookie_form_password, NULL, OR_AUTHCFG,
5a1101aa8bb19d6bafb6c7808a56f49a95b0b769bnicholes "The field of the login form carrying the password"),
5a1101aa8bb19d6bafb6c7808a56f49a95b0b769bnicholes AP_INIT_TAKE1("AuthFormLocation", set_cookie_form_location, NULL, OR_AUTHCFG,
0f7cc4b1d3c42262bcdced99f682778963e83ea7bnicholes "The field of the login form carrying the URL to redirect on "
233e163ab76ff3d9434939a65c6527f6e80be965bnicholes "successful login."),
0f7cc4b1d3c42262bcdced99f682778963e83ea7bnicholes AP_INIT_TAKE1("AuthFormMethod", set_cookie_form_method, NULL, OR_AUTHCFG,
0f7cc4b1d3c42262bcdced99f682778963e83ea7bnicholes "The field of the login form carrying the original request method."),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_TAKE1("AuthFormMimetype", set_cookie_form_mimetype, NULL, OR_AUTHCFG,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "The field of the login form carrying the original request mimetype."),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_TAKE1("AuthFormBody", set_cookie_form_body, NULL, OR_AUTHCFG,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "The field of the login form carrying the urlencoded original request "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_TAKE1("AuthFormSize", set_cookie_form_size, NULL, ACCESS_CONF,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "Maximum size of body parsed by the form parser"),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_TAKE1("AuthFormLoginRequiredLocation", set_login_required_location,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "If set, redirect the browser to this URL rather than "
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "return 401 Not Authorized."),
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes AP_INIT_TAKE1("AuthFormLoginSuccessLocation", set_login_success_location,
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "If set, redirect the browser to this URL when a login "
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "processed by the login handler is successful."),
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes AP_INIT_TAKE1("AuthFormLogoutLocation", set_logout_location,
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "The URL of the logout successful page. An attempt to access an "
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "URL handled by the handler " FORM_LOGOUT_HANDLER " will result "
273e1eccdc9e5b94f1e3e13e3ffca7360b6f461fbnicholes "in an redirect to this page after logout."),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_TAKE1("AuthFormSitePassphrase", set_site_passphrase,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "If set, use this passphrase to determine whether the user should "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "be authenticated. Bypasses the user authentication check on "
8410c53aaf5e0372a19d5f4d2bc696b9c609ce3cbnicholes "every website hit, and is useful for high traffic sites."),
8410c53aaf5e0372a19d5f4d2bc696b9c609ce3cbnicholes AP_INIT_FLAG("AuthFormAuthoritative", set_authoritative,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "Set to 'Off' to allow access control to be passed along to "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "lower modules if the UserID is not known to this module"),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_FLAG("AuthFormFakeBasicAuth", set_fake_basic_auth,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "Set to 'On' to pass through authentication to the rest of the "
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "server as a basic authentication header."),
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes AP_INIT_FLAG("AuthFormDisableNoStore", set_disable_no_store,
{NULL}
const char *authname;
while (r->main) {
r = r->main;
while (r->prev) {
r = r->prev;
if (user) {
if (pw) {
if (method) {
if (mimetype) {
const char *authname;
while (r->main) {
r = r->main;
while (r->prev) {
r = r->prev;
if (user) {
if (pw) {
if (method) {
if (mimetype) {
if (site) {
ap_session_load_fn(r, &z);
return APR_SUCCESS;
ap_session_load_fn(r, &z);
if (user) {
if (pw) {
if (hash) {
return APR_SUCCESS;
const char *username,
const char *password,
const char *location,
const char *method,
const char *mimetype,
const char *body,
const char **sent_user,
const char **sent_pw,
const char **sent_loc,
const char **sent_method,
const char **sent_mimetype,
int res;
char *buffer;
return OK;
return res;
if (*sent_user) {
return HTTP_UNAUTHORIZED;
return OK;
static int check_site(request_rec * r, const char *site, const char *sent_user, const char *sent_hash)
return OK;
return AUTH_USER_NOT_FOUND;
return DECLINED;
if (!current_provider) {
} while (current_provider);
int return_code;
return DECLINED;
switch (auth_result) {
case AUTH_DENIED:
case AUTH_USER_NOT_FOUND:
case AUTH_GENERAL_ERROR:
return return_code;
return OK;
return DECLINED;
return HTTP_INTERNAL_SERVER_ERROR;
if (!ap_auth_name(r)) {
return HTTP_INTERNAL_SERVER_ERROR;
return OK;
return OK;
if (sent_loc) {
return HTTP_MOVED_PERMANENTLY;
return HTTP_MOVED_PERMANENTLY;
return HTTP_MOVED_PERMANENTLY;
if (sent_loc) {
return rv;
int rv;
return DECLINED;
r->uri);
return HTTP_METHOD_NOT_ALLOWED;
if (sent_loc) {
return HTTP_MOVED_PERMANENTLY;
return HTTP_MOVED_PERMANENTLY;
return HTTP_OK;
return HTTP_MOVED_PERMANENTLY;
return rv;
return DECLINED;
return HTTP_TEMPORARY_REDIRECT;
return HTTP_OK;
return DECLINED;
return HTTP_INTERNAL_SERVER_ERROR;