void send_file(per_request *reqInfo, struct stat *fi, char allow_options) { FILE *f; #ifdef BLACKOUT_CODE int isblack = FALSE; #endif /* BLACKOUT_CODE */ if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) { sprintf(error_msg,"%s to non-script",methods[reqInfo->method]); die(reqInfo,SC_NOT_IMPLEMENTED,error_msg); } set_content_type(reqInfo,reqInfo->filename); if((allow_options & OPT_INCLUDES) && (!reqInfo->outh_content_encoding[0])) { #ifdef XBITHACK if((fi->st_mode & S_IXUSR) || (!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE))) { #else if(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE)) { #endif /* XBITHACK */ reqInfo->bytes_sent = 0; send_parsed_file(reqInfo, allow_options & OPT_INCNOEXEC); log_transaction(reqInfo); return; } } if (reqInfo->path_info[0]) { strcat(reqInfo->filename,reqInfo->path_info); strcat(reqInfo->url,reqInfo->path_info); sprintf(error_msg,"No file matching URL: %s",reqInfo->url); log_reason(reqInfo, error_msg, reqInfo->filename); die(reqInfo,SC_NOT_FOUND,reqInfo->url); } if(!(f=FOpen(reqInfo->filename,"r"))) { if (errno == EACCES) { log_reason(reqInfo,"(1) file permissions deny server access", reqInfo->filename); /* we've already established that it exists */ die(reqInfo,SC_FORBIDDEN,reqInfo->url); } else { /* We know an error occured, of an unexpected variety. * This could be due to no more file descriptors. We have this * child exit after this stage so that errors of state are * swept under the carpet. */ standalone = 0; sprintf(error_msg,"File Open error, errno=%d",errno); log_reason(reqInfo,error_msg,reqInfo->filename); die(reqInfo,SC_SERVER_ERROR,error_msg); } } reqInfo->bytes_sent = 0; #ifdef BLACKOUT_CODE if (!strcmp(reqInfo->outh_content_type,BLACKOUT_MAGIC_TYPE)) { isblack = TRUE; strcpy(reqInfo->outh_content_type,"text/html"); } #endif /* BLACKOUT_CODE */ if(reqInfo->http_version != P_HTTP_0_9) { /* No length dependent headers since black is parsed */ #ifdef BLACKOUT_CODE if (isblack == FALSE) { #endif /* BLACKOUT_CODE */ #ifdef CONTENT_MD5 reqInfo->outh_content_md5 = (unsigned char *)md5digest(f); #endif /* CONTENT_MD5 */ set_content_length(reqInfo,fi->st_size); if (set_last_modified(reqInfo,fi->st_mtime)) { FClose(f); return; } } if (reqInfo->http_version != P_HTTP_0_9) { send_http_header(reqInfo); } #ifdef BLACKOUT_CODE } #endif /* BLACKOUT_CODE */ if(reqInfo->method != M_HEAD) { #ifdef BLACKOUT_CODE if (isblack == TRUE) send_fp_black(reqInfo,f,NULL); else #endif /* BLACKOUT_CODE */ send_fp(reqInfo,f,NULL); } log_transaction(reqInfo); FClose(f); } void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options) { char *name_ptr, *end_ptr; char *ifile, *temp_name; ifile = newString(HUGE_STRING_LEN,STR_TMP); temp_name = newString(HUGE_STRING_LEN,STR_TMP); /* Path Alias (pa) array should now have the trailing slash */ /* if (pa[0] != '/') { */ if ((reqInfo->filename[strlen(reqInfo->filename) - 1] != '/') && (reqInfo->path_info[0] != '/')) { strcpy_dir(ifile,reqInfo->url); construct_url(temp_name,reqInfo->hostInfo,ifile); escape_url(temp_name); die(reqInfo,SC_REDIRECT_PERM,temp_name); } /* Don't allow PATH_INFO to directory indexes as a compromise for error messages for files which don't exist */ if ((reqInfo->path_info[0] != '\0') || (strlen(reqInfo->path_info) > 1)) { strcat(reqInfo->filename,reqInfo->path_info); strcat(reqInfo->url,reqInfo->path_info); sprintf(error_msg,"No file matching URL: %s",reqInfo->url); log_reason(reqInfo, error_msg, reqInfo->filename); freeString(temp_name); freeString(ifile); die(reqInfo,SC_NOT_FOUND,reqInfo->url); } strncpy(temp_name, reqInfo->hostInfo->index_names, HUGE_STRING_LEN-1); end_ptr = name_ptr = temp_name; while (*name_ptr) { while (*name_ptr && isspace (*name_ptr)) ++name_ptr; end_ptr = name_ptr; if (strchr(end_ptr, ' ') ) { end_ptr = strchr(name_ptr, ' '); *end_ptr = '\0'; end_ptr++; } else end_ptr += strlen(end_ptr); make_full_path(reqInfo->filename,name_ptr,ifile); if(stat(ifile,finfo) == -1) { if(! *end_ptr && (allow_options & OPT_INDEXES)) { if (reqInfo->path_info[0]) { strcat(reqInfo->filename,reqInfo->path_info); strcat(reqInfo->url,reqInfo->path_info); log_reason(reqInfo,"file does not exist",reqInfo->filename); freeString(ifile); freeString(temp_name); die(reqInfo,SC_NOT_FOUND,reqInfo->url); } if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) { sprintf(error_msg,"%s to non-script",methods[reqInfo->method]); freeString(ifile); freeString(temp_name); die(reqInfo,SC_NOT_IMPLEMENTED,error_msg); } index_directory(reqInfo); freeString(ifile); freeString(temp_name); return; } else if (! *end_ptr) { log_reason(reqInfo,"(2) file permissions deny server access", reqInfo->filename); freeString(ifile); freeString(temp_name); die(reqInfo,SC_FORBIDDEN,reqInfo->url); } } else { strcpy(reqInfo->filename,ifile); probe_content_type(reqInfo,reqInfo->filename); if(!strcmp(reqInfo->outh_content_type,CGI_MAGIC_TYPE)) send_cgi(reqInfo,finfo,allow_options); else send_file(reqInfo,finfo,allow_options); freeString(ifile); freeString(temp_name); return; } name_ptr = end_ptr; } }
/* * When we come here, we've already matched either a location block or an extension */ static int run(request_rec *r) { EjsDirConfig *dir; EjsServerConfig *server; cchar *ext; MaRequest *req; MaResponse *resp; MaConn *conn; MaAlias *alias; MaLocation *location; EjsWeb *web; cchar *sep, *prefix; char *urlBase, *dir, *app, *url, *cp; int flags, locFlags; if (!r->handler || strcasecmp(r->handler, "ejs") != 0) { return DECLINED; } dir = getDir(r) server = getServer(r->XXX); // EjsAlias should probably be creating a directory block. These flags should probably be in a directory if (loc->flags & (MA_LOC_APP | MA_LOC_APP_DIR)) { /* * Send non-ejs content under web to another handler, typically the file handler. */ if (strncmp(&req->url[loc->prefixLen], "web/", 4) == 0) { if (!(ext && strcmp(ext, "ejs") == 0)) { return DECLINED; } } else { if (ext && strcmp(ext, "ejs") == 0) { maFormatBody(conn, "Bad Request", "Can't serve *.ejs files outside web directory"); maFailRequest(conn, MPR_HTTP_CODE_BAD_REQUEST, "Can't server *.ejs files outside web directory"); return HTTP_XXX; } } } flags = 0; url = 0; locFlags = location->flags; if (locFlags & MA_LOC_APP) { app = mprStrTrim(mprStrdup(q, prefix), "/"); url = &req->url[alias->prefixLen]; dir = mprStrdup(resp, alias->filename); if (*url != '/') { url--; } urlBase = mprStrdup(resp, prefix); } else if (locFlags & MA_LOC_APP_DIR) { url = &req->url[alias->prefixLen]; app = mprStrdup(resp, url); if ((cp = strchr(app, '/')) != 0) { url = mprStrdup(resp, cp); *cp = '\0'; } sep = prefix[strlen(prefix) - 1] == '/' ? "" : "/"; dir = mprStrcat(resp, &dir, alias->filename, sep, app, NULL); urlBase = mprStrcat(resp, prefix, sep, app, NULL); } else { app = 0; dir = mprStrdup(resp, alias->filename); url = &req->url[alias->prefixLen]; flags |= EJS_WEB_FLAG_SOLO; if (*url != '/') { url--; } urlBase = mprStrdup(resp, prefix); } mprStrTrim(urlBase, "/"); mprStrTrim(dir, "/"); if (location->flags & MA_LOC_BROWSER) { flags |= EJS_WEB_FLAG_BROWSER_ERRORS; } if (location->flags & MA_LOC_AUTO_SESSION) { flags |= EJS_WEB_FLAG_SESSION; } /* * Var Stand-Alone App AppDir * app 0 carmen carmen * dir /Users/mob/.... /Users/mob/hg/carmen /Users/mob/hg/carmen * urlBase /xg/carmen /carmen * url stock stock */ web = ejsCreateWebRequest(req, q->stage->stageData, conn, app, dir, urlBase, url, req->cookie, flags); if (web == 0) { maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't create Ejs web object for %s", req->url); return; } q->queueData = web; maSetHeader(conn, 0, "Last-Modified", req->host->currentDate); maDontCacheResponse(conn); if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } if (ejsProcessWebRequest((EjsWeb*) r, &msg) < 0) { if (web->flags & EJS_WEB_FLAG_BROWSER_ERRORS) { maFormatBody(conn, "Request Failed", "%s", msg); } maFailRequest(conn, MPR_HTTP_CODE_BAD_GATEWAY, msg); mprFree(msg); } ap_set_content_type(r, "text/html"); ap_rputs("<html><title>Hello World!</title><body><p>Hello World</p></body></html>\r\n", r); #if 0 if ((err = set_content_length(r, r->finfo.st_stize)) || (err = set_last_modified(r, r->finfo.st_mtime))) return err; if (r->finof.st_mode == 0) return NOT_FOUND; fopen(r->filename, "r"); if (!r->main) { /* Not internal redirect */ apr_table_set(r->headers_out, "X-ejs", "Under construction"); } register_timeout("send", r); send_http_header(r); if (!r->header_only) send_fd(f, r); pfclose(r->pool, f); #endif return OK; }