예제 #1
0
파일: reqs.c 프로젝트: Yinzcn/Cutehttpd
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);
    }
}
예제 #2
0
파일: reqs.c 프로젝트: Yinzcn/Cutehttpd
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;
}
예제 #3
0
/*
 * 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);
}
예제 #4
0
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;
  }	 
}
예제 #5
0
/*
 *  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;
}