📄 alias.c
字号:
memcpy(buffer, document_root, l1);
if (virtualhost) {
buffer[l1] = '/';
memcpy(buffer + l1 + 1, req->local_ip_addr, l3);
memcpy(buffer + l1 + 1 + l3, req->request_uri, l2 + 1);
} else
memcpy(buffer + l1, req->request_uri, l2 + 1);
} else {
/* not aliased. not userdir. not part of document_root. BAIL */
send_r_not_found(req);
return 0;
}
/* if here,
* o it may be aliased but it's not a redirect or a script...
* o it may be a homedir
* o it may be a document_root resource (with or without virtual host)
*/
req->pathname = strdup(buffer);
if (!req->pathname) {
WARN("Could not strdup buffer for req->pathname!");
send_r_error(req);
return 0;
}
/* below we support cgis outside of a ScriptAlias */
if (strcmp(CGI_MIME_TYPE, get_mime_type(buffer)) == 0) { /* cgi */
#ifdef FASCIST_LOGGING
log_error_time();
fprintf(stderr, "%s:%d - buffer is: \"%s\"\n",
__FILE__, __LINE__, buffer);
#endif
/* FIXME */
/* script_name could end up as /cgi-bin/bob/extra_path */
req->script_name = strdup(req->request_uri);
if (!req->script_name) {
WARN("Could not strdup req->request_uri for req->script_name");
send_r_error(req);
return 0;
}
if (req->simple)
req->is_cgi = NPH;
else
req->is_cgi = CGI;
return 1;
} else if (req->method == M_POST) { /* POST to non-script */
/* it's not a cgi, but we try to POST??? */
send_r_bad_request(req);
return 0;
} else /* we are done!! */
return 1;
}
/*
* Name: init_script_alias
*
* Description: Performs full parsing on a ScriptAlias request
* Sets path_info and script_name
*
* Return values:
*
* 0: failure, shut down
* 1: success, continue
*/
int init_script_alias(request * req, alias * current1, int uri_len)
{
static char pathname[MAX_HEADER_LENGTH + 1];
struct stat statbuf;
static char buffer[MAX_HEADER_LENGTH + 1];
int index = 0;
char c;
int err;
/* copies the "real" path + the non-alias portion of the
uri to pathname.
*/
if (uri_len - current1->fake_len + current1->real_len >
MAX_HEADER_LENGTH) {
log_error_doc(req);
fputs("uri too long!\n", stderr);
send_r_bad_request(req);
return 0;
}
memcpy(pathname, current1->realname, current1->real_len);
memcpy(pathname + current1->real_len,
&req->request_uri[current1->fake_len],
uri_len - current1->fake_len + 1); /* the +1 copies the NUL */
#ifdef FASCIST_LOGGING
log_error_time();
fprintf(stderr,
"%s:%d - pathname in init_script_alias is: \"%s\" (\"%s\")\n",
__FILE__, __LINE__, pathname, pathname + current1->real_len);
#endif
if (strncmp("nph-", pathname + current1->real_len, 4) == 0
|| req->simple) req->is_cgi = NPH;
else
req->is_cgi = CGI;
/* start at the beginning of the actual uri...
(in /cgi-bin/bob, start at the 'b' in bob */
index = current1->real_len;
/* go to first and successive '/' and keep checking
* if it is a full pathname
* on success (stat (not lstat) of file is a *regular file*)
*/
do {
c = pathname[++index];
if (c == '/') {
pathname[index] = '\0';
err = stat(pathname, &statbuf);
pathname[index] = '/';
if (err == -1) {
send_r_not_found(req);
return 0;
}
/* is it a dir? */
if (!S_ISDIR(statbuf.st_mode)) {
/* check access */
if (!(statbuf.st_mode &
(S_IFREG | /* regular file */
(S_IRUSR | S_IXUSR) | /* u+rx */
(S_IRGRP | S_IXGRP) | /* g+rx */
(S_IROTH | S_IXOTH)))) { /* o+rx */
send_r_forbidden(req);
return 0;
}
/* stop here */
break;
}
}
} while (c != '\0');
req->script_name = strdup(req->request_uri);
if (!req->script_name) {
send_r_error(req);
WARN("unable to strdup req->request_uri for req->script_name");
return 0;
}
if (c == '\0') {
err = stat(pathname, &statbuf);
if (err == -1) {
send_r_not_found(req);
return 0;
}
/* is it a dir? */
if (!S_ISDIR(statbuf.st_mode)) {
/* check access */
if (!(statbuf.st_mode &
(S_IFREG | /* regular file */
(S_IRUSR | S_IXUSR) | /* u+rx */
(S_IRGRP | S_IXGRP) | /* g+rx */
(S_IROTH | S_IXOTH)))) { /* o+rx */
send_r_forbidden(req);
return 0;
}
/* stop here */
} else {
send_r_forbidden(req);
return 0;
}
}
/* we have path_info if c == '/'... still have to check for query */
else if (c == '/') {
int hash;
alias *current;
int path_len;
req->path_info = strdup(pathname + index);
if (!req->path_info) {
send_r_error(req);
WARN("unable to strdup pathname + index for req->path_info");
return 0;
}
pathname[index] = '\0'; /* strip path_info from path */
path_len = strlen(req->path_info);
/* we need to fix script_name here */
/* index points into pathname, which is
* realname/cginame/foo
* and index points to the '/foo' part
*/
req->script_name[strlen(req->script_name) - path_len] = '\0'; /* zap off the /foo part */
/* now, we have to re-alias the extra path info....
this sucks.
*/
hash = get_alias_hash_value(req->path_info);
current = alias_hashtable[hash];
while (current && !req->path_translated) {
if (!strncmp(req->path_info, current->fakename,
current->fake_len)) {
if (current->real_len +
path_len - current->fake_len > MAX_HEADER_LENGTH) {
log_error_doc(req);
fputs("uri too long!\n", stderr);
send_r_bad_request(req);
return 0;
}
memcpy(buffer, current->realname, current->real_len);
strcpy(buffer + current->real_len,
&req->path_info[current->fake_len]);
req->path_translated = strdup(buffer);
if (!req->path_translated) {
send_r_error(req);
WARN("unable to strdup buffer for req->path_translated");
return 0;
}
}
current = current->next;
}
/* no alias... try userdir */
if (!req->path_translated && user_dir && req->path_info[1] == '~') {
char *user_homedir;
char *p;
p = strchr(pathname + index + 1, '/');
if (p)
*p = '\0';
user_homedir = get_home_dir(pathname + index + 2);
if (p)
*p = '/';
if (!user_homedir) { /* no such user */
send_r_not_found(req);
return 0;
}
{
int l1 = strlen(user_homedir);
int l2 = strlen(user_dir);
int l3;
if (p)
l3 = strlen(p);
else
l3 = 0;
req->path_translated = malloc(l1 + l2 + l3 + 2);
if (req->path_translated == NULL) {
send_r_error(req);
WARN("unable to malloc memory for req->path_translated");
return 0;
}
memcpy(req->path_translated, user_homedir, l1);
req->path_translated[l1] = '/';
memcpy(req->path_translated + l1 + 1, user_dir, l2 + 1);
if (p)
memcpy(req->path_translated + l1 + 1 + l2, p, l3 + 1);
}
}
if (!req->path_translated && document_root) {
/* no userdir, no aliasing... try document root */
int l1, l2;
l1 = strlen(document_root);
l2 = path_len;
req->path_translated = malloc(l1 + l2 + 1);
if (req->path_translated == NULL) {
send_r_error(req);
WARN("unable to malloc memory for req->path_translated");
return 0;
}
memcpy(req->path_translated, document_root, l1);
memcpy(req->path_translated + l1, req->path_info, l2 + 1);
}
}
req->pathname = strdup(pathname);
if (!req->pathname) {
send_r_error(req);
WARN("unable to strdup pathname for req->pathname");
return 0;
}
return 1;
}
/*
* Empties the alias hashtable, deallocating any allocated memory.
*/
void dump_alias(void)
{
int i;
alias *temp;
for (i = 0; i < ALIAS_HASHTABLE_SIZE; ++i) { /* these limits OK? */
if (alias_hashtable[i]) {
temp = alias_hashtable[i];
while (temp) {
alias *temp_next;
if (temp->fakename)
free(temp->fakename);
if (temp->realname)
free(temp->realname);
temp_next = temp->next;
free(temp);
temp = temp_next;
}
alias_hashtable[i] = NULL;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -