⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (http_readFile(web, &buf, &size, url, lp_swat_directory(esp->web->task->lp_ctx)) != 0) {		http_error_unix(web, url);		return;	}#if HAVE_SETJMP_H	if (setjmp(ejs_exception_buf) != 0) {		http_error(web, 500, exception_reason);		return;	}#endif	res = espProcessRequest(esp->req, url, buf, &emsg);	if (res != 0 && emsg) {		http_writeBlock(web, "<pre>", 5);		http_writeBlock(web, emsg, strlen(emsg));		http_writeBlock(web, "</pre>", 6);	}	talloc_free(buf);}/*  perform pre-authentication on every page if /scripting/preauth.esp  exists.  If this script generates any non-whitepace output at all,  then we don't run the requested URL.  note that the preauth is run even for static pages such as images*/static bool http_preauth(struct esp_state *esp){	const char *path = http_local_path(esp->web,                                           HTTP_PREAUTH_URI,                                           lp_swat_directory(esp->web->task->lp_ctx));	int i;	if (path == NULL) {		http_error(esp->web, 500, "Internal server error");		return false;	}	if (!file_exist(path)) {		/* if the preath script is not installed then allow access */		return true;	}	esp_request(esp, HTTP_PREAUTH_URI);	for (i=0;i<esp->web->output.content.length;i++) {		if (!isspace(esp->web->output.content.data[i])) {			/* if the preauth has generated content, then force it			   to be html, so that we can show the login page for			   failed access to images */			http_setHeader(esp->web, "Content-Type: text/html", 0);			return false;		}	}	data_blob_free(&esp->web->output.content);	return true;}/*    handling of + and % escapes in http variables */static const char *http_unescape(TALLOC_CTX *mem_ctx, const char *p){	char *s0 = talloc_strdup(mem_ctx, p);	char *s = s0;	if (s == NULL) return NULL;	while (*s) {		unsigned v;		if (*s == '+') *s = ' ';		if (*s == '%' && sscanf(s+1, "%02x", &v) == 1) {			*s = (char)v;			memmove(s+1, s+3, strlen(s+3)+1);		}		s++;	}	return s0;}/*  set a form or GET variable*/static void esp_putvar(struct esp_state *esp, const char *var, const char *value){	if (strcasecmp(var, SAMBA_SESSION_KEY) == 0) {		/* special case support for browsers without cookie		 support */		esp->web->input.session_key = talloc_strdup(esp, value);	} else {		mprSetPropertyValue(&esp->variables[ESP_FORM_OBJ], 				    http_unescape(esp, var),				    mprCreateStringVar(http_unescape(esp, value), 0));	}}/*  parse the variables in a POST style request*/static NTSTATUS http_parse_post(struct esp_state *esp){	DATA_BLOB b = esp->web->input.partial;	while (b.length) {		char *p, *line;		size_t len;		p = memchr(b.data, '&', b.length);		if (p == NULL) {			len = b.length;		} else {			len = p - (char *)b.data;		}		line = talloc_strndup(esp, (char *)b.data, len);		NT_STATUS_HAVE_NO_MEMORY(line);				     		p = strchr(line,'=');		if (p) {			*p = 0;			esp_putvar(esp, line, p+1);		}		talloc_free(line);		b.length -= len;		b.data += len;		if (b.length > 0) {			b.length--;			b.data++;		}	}	return NT_STATUS_OK;}/*  parse the variables in a GET style request*/static NTSTATUS http_parse_get(struct esp_state *esp){	struct websrv_context *web = esp->web;	char *p, *s, *tok;	char *pp;	p = strchr(web->input.url, '?');	web->input.query_string = p+1;	*p = 0;	s = talloc_strdup(esp, esp->web->input.query_string);	NT_STATUS_HAVE_NO_MEMORY(s);	for (tok=strtok_r(s,"&;", &pp);tok;tok=strtok_r(NULL,"&;", &pp)) {		p = strchr(tok,'=');		if (p) {			*p = 0;			esp_putvar(esp, tok, p+1);		}	}	return NT_STATUS_OK;}/*  called when a session times out*/static void session_timeout(struct event_context *ev, struct timed_event *te, 			    struct timeval t, void *private){	struct session_data *s = talloc_get_type(private, struct session_data);	talloc_free(s);}/*  destroy a session */static int session_destructor(struct session_data *s){	DLIST_REMOVE(s->edata->sessions, s);	return 0;}/*  setup the session for this request*/static void http_setup_session(struct esp_state *esp){	const char *session_key = SAMBA_SESSION_KEY;	char *p;	const char *cookie = esp->web->input.cookie;	const char *key = NULL;	struct esp_data *edata = talloc_get_type(esp->web->task->private, struct esp_data);	struct session_data *s;	bool generated_key = false;	/* look for our session key */	if (cookie && (p = strstr(cookie, session_key)) && 	    p[strlen(session_key)] == '=') {		p += strlen(session_key)+1;		key = talloc_strndup(esp, p, strcspn(p, ";"));	}	if (key == NULL && esp->web->input.session_key) {		key = esp->web->input.session_key;	} else if (key == NULL) {		key = generate_random_str_list(esp, 16, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");		generated_key = true;	}	/* try to find this session in the existing session list */	for (s=edata->sessions;s;s=s->next) {		if (strcmp(key, s->id) == 0) {			break;		}	}	if (s == NULL) {		/* create a new session */		s = talloc_zero(edata, struct session_data);		s->id = talloc_steal(s, key);		s->data = NULL;		s->te = NULL;		s->edata = edata;		s->lifetime = lp_parm_int(esp->web->task->lp_ctx, NULL, "web", "sessiontimeout", 900);		DLIST_ADD(edata->sessions, s);		talloc_set_destructor(s, session_destructor);		if (!generated_key) {			mprSetPropertyValue(&esp->variables[ESP_REQUEST_OBJ], 					    "SESSION_EXPIRED", mprCreateStringVar("true", 0));		}	}	http_setCookie(esp->web, session_key, key, s->lifetime, "/", 0);	if (s->data) {		mprCopyVar(&esp->variables[ESP_SESSION_OBJ], s->data, MPR_DEEP_COPY);	}	esp->web->session = s;}/* callbacks for esp processing */static const struct Esp esp_control = {	.maxScriptSize   = 60000,	.writeBlock      = http_writeBlock,	.setHeader       = http_setHeader,	.redirect        = http_redirect,	.setResponseCode = http_setResponseCode,	.readFile        = http_readFileFromSwatDir,	.mapToStorage    = http_mapToStorage,	.setCookie       = http_setCookie,	.createSession   = http_createSession,	.destroySession  = http_destroySession,	.getSessionId    = http_getSessionId};/*  process a complete http request*/void http_process_input(struct websrv_context *web){	NTSTATUS status;	struct esp_state *esp = NULL;	struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data);	struct smbcalls_context *smbcalls_ctx;	char *p;	void *save_mpr_ctx = mprMemCtx();	void *ejs_save = ejs_save_state();	int i;	const char *file_type = NULL;        enum page_type {                page_type_simple,                page_type_esp        };        enum page_type page_type;	const struct {		const char *extension;		const char *mime_type;                enum page_type page_type;	} mime_types[] = {		{"gif",  "image/gif"},		{"png",  "image/png"},		{"jpg",  "image/jpeg"},		{"txt",  "text/plain"},		{"ico",  "image/x-icon"},		{"css",  "text/css"},		{"esp",  "text/html", true}	};	/*	 * give the smbcalls a chance to find the event context	 * and messaging context 	 */	smbcalls_ctx = talloc(web, struct smbcalls_context);	if (smbcalls_ctx == NULL) goto internal_error;	smbcalls_ctx->event_ctx = web->conn->event.ctx;	smbcalls_ctx->msg_ctx = web->conn->msg_ctx;	esp = talloc_zero(smbcalls_ctx, struct esp_state);	if (esp == NULL) goto internal_error;	esp->web = web;	mprSetCtx(esp);	if (espOpen(&esp_control) != 0) goto internal_error;	for (i=0;i<ARRAY_SIZE(esp->variables);i++) {		esp->variables[i] = mprCreateUndefinedVar();	}	esp->variables[ESP_HEADERS_OBJ]     = mprCreateObjVar("headers", ESP_HASH_SIZE);	esp->variables[ESP_FORM_OBJ]        = mprCreateObjVar("form", ESP_HASH_SIZE);	esp->variables[ESP_APPLICATION_OBJ] = mprCreateObjVar("application", ESP_HASH_SIZE);	esp->variables[ESP_COOKIES_OBJ]     = mprCreateObjVar("cookies", ESP_HASH_SIZE);	esp->variables[ESP_FILES_OBJ]       = mprCreateObjVar("files", ESP_HASH_SIZE);	esp->variables[ESP_REQUEST_OBJ]     = mprCreateObjVar("request", ESP_HASH_SIZE);	esp->variables[ESP_SERVER_OBJ]      = mprCreateObjVar("server", ESP_HASH_SIZE);	esp->variables[ESP_SESSION_OBJ]     = mprCreateObjVar("session", ESP_HASH_SIZE);	if (edata->application_data) {		mprCopyVar(&esp->variables[ESP_APPLICATION_OBJ], 			   edata->application_data, MPR_DEEP_COPY);	}	smb_setup_ejs_functions(web_server_ejs_exception);	if (web->input.url == NULL) {		http_error(web, 400, "You must specify a GET or POST request");		mprSetCtx(save_mpr_ctx);		ejs_restore_state(ejs_save);		return;	}		/* parse any form or get variables */	if (web->input.post_request) {		status = http_parse_post(esp);		if (!NT_STATUS_IS_OK(status)) {			http_error(web, 400, "Malformed POST data");			mprSetCtx(save_mpr_ctx);			ejs_restore_state(ejs_save);			return;		}	} 	if (strchr(web->input.url, '?')) {		status = http_parse_get(esp);		if (!NT_STATUS_IS_OK(status)) {			http_error(web, 400, "Malformed GET data");			mprSetCtx(save_mpr_ctx);			ejs_restore_state(ejs_save);			return;		}	}	http_setup_session(esp);	esp->req = espCreateRequest(web, web->input.url, esp->variables);	if (esp->req == NULL) goto internal_error;	p = strrchr(web->input.url, '.');	if (p == NULL) {		page_type = page_type_esp;		file_type = "text/html";	}	for (i=0;p && i<ARRAY_SIZE(mime_types);i++) {		if (strcmp(mime_types[i].extension, p+1) == 0) {			page_type = mime_types[i].page_type;			file_type = mime_types[i].mime_type;		}	}	if (file_type == NULL) {                page_type = page_type_simple;		file_type = "text/html";	}	/* setup basic headers */	http_setResponseCode(web, 200);	http_setHeader(web, talloc_asprintf(esp, "Date: %s", 					    http_timestring(esp, time(NULL))), 0);	http_setHeader(web, "Server: Samba", 0);	http_setHeader(web, "Connection: close", 0);	http_setHeader(web, talloc_asprintf(esp, "Content-Type: %s", file_type), 0);	http_setup_arrays(esp);	/*         * Do pre-authentication.  If pre-authentication succeeds, do         * page-type-specific processing.         */        switch(page_type)        {        case page_type_simple:                if (http_preauth(esp)) {                        http_simple_request(web);                }                break;        case page_type_esp:                if (http_preauth(esp)) {                        esp_request(esp, web->input.url);                }                break;        }	if (web->conn == NULL) {		/* the connection has been terminated above us, probably		   via a timeout */		goto internal_error;	}	if (!web->output.output_pending) {		http_output_headers(web);		EVENT_FD_WRITEABLE(web->conn->event.fde);		web->output.output_pending = true;	}	/* copy any application data to long term storage in edata */	talloc_free(edata->application_data);	edata->application_data = talloc_zero(edata, struct MprVar);	mprSetCtx(edata->application_data);	mprCopyVar(edata->application_data, &esp->variables[ESP_APPLICATION_OBJ], 		   MPR_DEEP_COPY);	mprSetCtx(esp);	/* copy any session data */	if (web->session) {		talloc_free(web->session->data);		web->session->data = talloc_zero(web->session, struct MprVar);		if (esp->variables[ESP_SESSION_OBJ].properties == NULL ||		    esp->variables[ESP_SESSION_OBJ].properties[0].numItems == 0) {			talloc_free(web->session);			web->session = NULL;		} else {			mprSetCtx(web->session->data);			mprCopyVar(web->session->data, &esp->variables[ESP_SESSION_OBJ], 				   MPR_DEEP_COPY);			/* setup the timeout for the session data */			mprSetCtx(esp);			talloc_free(web->session->te);			web->session->te = event_add_timed(web->conn->event.ctx, web->session, 							   timeval_current_ofs(web->session->lifetime, 0), 							   session_timeout, web->session);		}	}	talloc_free(esp);	mprSetCtx(save_mpr_ctx);	ejs_restore_state(ejs_save);	return;	internal_error:	mprSetCtx(esp);	talloc_free(esp);	if (web->conn != NULL) {		http_error(web, 500, "Internal server error");	}	mprSetCtx(save_mpr_ctx);	ejs_restore_state(ejs_save);}/*  parse one line of header input*/NTSTATUS http_parse_header(struct websrv_context *web, const char *line){	if (line[0] == 0) {		web->input.end_of_headers = true;	} else if (strncasecmp(line,"GET ", 4)==0) {		web->input.url = talloc_strndup(web, &line[4], strcspn(&line[4], " \t"));	} else if (strncasecmp(line,"POST ", 5)==0) {		web->input.post_request = true;		web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t"));	} else if (strchr(line, ':') == NULL) {		http_error(web, 400, "This server only accepts GET and POST requests");		return NT_STATUS_INVALID_PARAMETER;	} else if (strncasecmp(line,"Content-Length: ", 16)==0) {		web->input.content_length = strtoul(&line[16], NULL, 10);	} else {#define PULL_HEADER(v, s) do { \	if (strncmp(line, s, strlen(s)) == 0) { \		web->input.v = talloc_strdup(web, &line[strlen(s)]); \		return NT_STATUS_OK; \	} \} while (0)		PULL_HEADER(content_type, "Content-Type: ");		PULL_HEADER(user_agent, "User-Agent: ");		PULL_HEADER(referer, "Referer: ");		PULL_HEADER(host, "Host: ");		PULL_HEADER(accept_encoding, "Accept-Encoding: ");		PULL_HEADER(accept_language, "Accept-Language: ");		PULL_HEADER(accept_charset, "Accept-Charset: ");		PULL_HEADER(cookie, "Cookie: ");	}	/* ignore all other headers for now */	return NT_STATUS_OK;}/*  setup the esp processor - called at task initialisation*/NTSTATUS http_setup_esp(struct task_server *task){	struct esp_data *edata;	edata = talloc_zero(task, struct esp_data);	NT_STATUS_HAVE_NO_MEMORY(edata);	task->private = edata;	edata->tls_params = tls_initialise(edata, task->lp_ctx);	NT_STATUS_HAVE_NO_MEMORY(edata->tls_params);	return NT_STATUS_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -