void reqs_throw_status(struct reqs_t *reqs, int status_code, char *msg) { if (status_code > 199 && status_code != 204 && status_code != 304) { int len = strlen(msg); if (!len) { msg = http_status_lines_get(status_code); len = strlen(msg); } set_http_status (reqs, status_code); set_http_header (reqs, "Content-Type", "text/html"); set_http_header_x(reqs, "Content-Length", "%d", len); send_http_header (reqs); reqs_conn_send (reqs, msg, len); } else { set_http_status (reqs, status_code); set_http_header (reqs, "Content-Type", ""); set_http_header (reqs, "Content-Length", ""); send_http_header (reqs); } }
int reqs_cont_send(struct reqs_t *reqs) { if (!reqs->rp_status_line) { set_http_status(reqs, 200); /* "200 OK" */ } if (strlen(get_http_header(reqs, "Content-Type")) == 0) { set_http_header(reqs, "Content-Type", "text/html"); } set_http_header_x(reqs, "Content-Length", "%d", bufx_get_used(reqs->contbufx)); send_http_header (reqs); bufx_get_each (reqs->contbufx, conn_send, reqs->conn); return 1; }
/* * php3_header() flushes the header info built up using calls to * the Header() function. If type is 1, a redirect to str is done. * Otherwise type should be 0 and str NULL. * * The function returns non-zero if output is allowed after the * call, and zero otherwise. Any call to php3_header() must check * the return status and if false, no output must be sent. This * is in order to correctly handle HEAD requests. */ PHPAPI int php3_header(void) { #if APACHE CookieList *cookie; int len = 0; time_t t; char *dt, *cookievalue = NULL; #endif #if APACHE || defined(USE_SAPI) || FHTTPD char *tempstr; #endif TLS_VARS; if (GLOBAL(header_is_being_sent)) { return 0; } else { GLOBAL(header_is_being_sent) = 1; } #if APACHE if (!GLOBAL(php3_rqst)) { /* we're not in a request, allow output */ GLOBAL(header_is_being_sent) = 0; return 1; } if ((GLOBAL(php3_PrintHeader) && !GLOBAL(php3_HeaderPrinted)) || (GLOBAL(php3_PrintHeader) && GLOBAL(php3_HeaderPrinted) == 2)) { if (!(GLOBAL(initialized) & INIT_ENVIRONMENT) && GLOBAL(request_info).request_method) { if(!strcasecmp(GLOBAL(request_info).request_method, "post")) php3_treat_data(PARSE_POST, NULL); /* POST Data */ else { if(!strcasecmp(GLOBAL(request_info).request_method, "put")) php3_treat_data(PARSE_PUT, NULL); /* PUT Data */ } } cookie = php3_PopCookieList(); while (cookie) { if (cookie->name) len += strlen(cookie->name); if (cookie->value) { cookievalue = _php3_urlencode(cookie->value, strlen (cookie->value)); len += strlen(cookievalue); } if (cookie->path) len += strlen(cookie->path); if (cookie->domain) len += strlen(cookie->domain); tempstr = emalloc(len + 100); if (!cookie->value || (cookie->value && !*cookie->value)) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date 1 year and 1 second in the past */ sprintf(tempstr, "%s=deleted", cookie->name); t = time(NULL) - 31536001; strcat(tempstr, "; expires="); dt = php3_std_date(t); strcat(tempstr, dt); efree(dt); } else { /* FIXME: XXX: this is not binary data safe */ sprintf(tempstr, "%s=%s", cookie->name, cookie->value ? cookievalue : ""); if (cookie->name) efree(cookie->name); if (cookie->value) efree(cookie->value); if (cookievalue) efree(cookievalue); cookie->name=NULL; cookie->value=NULL; cookievalue=NULL; if (cookie->expires > 0) { strcat(tempstr, "; expires="); dt = php3_std_date(cookie->expires); strcat(tempstr, dt); efree(dt); } } if (cookie->path && strlen(cookie->path)) { strcat(tempstr, "; path="); strcat(tempstr, cookie->path); efree(cookie->path); cookie->path=NULL; } if (cookie->domain && strlen(cookie->domain)) { strcat(tempstr, "; domain="); strcat(tempstr, cookie->domain); efree(cookie->domain); cookie->domain=NULL; } if (cookie->secure) { strcat(tempstr, "; secure"); } table_add(GLOBAL(php3_rqst)->headers_out, "Set-Cookie", tempstr); if (cookie->domain) efree(cookie->domain); if (cookie->path) efree(cookie->path); if (cookie->name) efree(cookie->name); if (cookie->value) efree(cookie->value); if (cookievalue) efree(cookievalue); efree(cookie); cookie = php3_PopCookieList(); efree(tempstr); } GLOBAL(php3_HeaderPrinted) = 1; GLOBAL(header_called) = 1; send_http_header(GLOBAL(php3_rqst)); if (GLOBAL(php3_rqst)->header_only) { GLOBAL(shutdown_requested) = NORMAL_SHUTDOWN; GLOBAL(header_is_being_sent) = 0; return(0); } } #else if (GLOBAL(php3_PrintHeader) && !GLOBAL(php3_HeaderPrinted)) { if (!(GLOBAL(initialized) & INIT_ENVIRONMENT) && GLOBAL(request_info).request_method) { if(!strcasecmp(GLOBAL(request_info).request_method, "post")) php3_treat_data(PARSE_POST, NULL); /* POST Data */ else { if(!strcasecmp(GLOBAL(request_info).request_method, "put")) php3_treat_data(PARSE_PUT, NULL); /* PUT Data */ } } if (php3_ini.expose_php) { PUTS("X-Powered-By: PHP/" PHP_VERSION "\r\n"); } if (!GLOBAL(cont_type)) { #if USE_SAPI GLOBAL(sapi_rqst)->header(GLOBAL(sapi_rqst)->scid,"Content-type: text/html\015\012\015\012"); #else /* CGI BINARY or FHTTPD */ #if FHTTPD php3_fhttpd_puts_header("Content-type: text/html\r\n"); #else PUTS("Content-type: text/html\015\012\015\012"); #endif #endif /* endif SAPI */ } else { #if 0 /*WIN32|WINNT / *M$ does us again*/ if (!strcmp(GLOBAL(cont_type),"text/html")){ #endif #if USE_SAPI tempstr=emalloc(strlen(GLOBAL(cont_type))+18); sprintf(tempstr,"Content-type: %s\015\012\015\012",GLOBAL(cont_type)); GLOBAL(sapi_rqst)->header(GLOBAL(sapi_rqst)->scid,tempstr); efree(tempstr); #else /* CGI_BINARY or FHTTPD */ #if FHTTPD tempstr = emalloc(strlen(GLOBAL(cont_type)) + sizeof("Content-type:") + 2); if(tempstr) { strcpy(tempstr, "Content-type:"); strcpy(tempstr + sizeof("Content-type:") - 1, GLOBAL(cont_type)); strcat(tempstr, "\r\n"); php3_fhttpd_puts_header(tempstr); efree(tempstr); } #else PUTS("Content-type:"); PUTS(GLOBAL(cont_type)); PUTS("\015\012\015\012"); #endif #endif /* endif SAPI */ efree(GLOBAL(cont_type)); #if 0 /*WIN32|WINNT / *M$ does us again*/ } else { PUTS("\015\012"); }/*end excluding output of text/html*/ #endif } #if USE_SAPI GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid); #else fflush(stdout); #endif GLOBAL(php3_HeaderPrinted) = 1; GLOBAL(header_called) = 1; } #endif GLOBAL(header_is_being_sent) = 0; return(1); }
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; }