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

📄 proxy_ftp.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
	    if (*(pstr + strlen(pstr) + 1) == '=')	        pstr += strlen(pstr) + 2;	    else	    {	        pstr = strtok(NULL, "(");  /* separate address & port params */		if (pstr != NULL)		    pstr = strtok(NULL, ")");	    }	}	else	    presult = atoi(pasv);	Explain1("FTP: returned status %d", presult);	if (presult == 227 && pstr != NULL && (sscanf(pstr,		 "%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) {	    /* pardon the parens, but it makes gcc happy */	    paddr = (((((h3 << 8) + h2) << 8) + h1) << 8) + h0;	    pport = (p1 << 8) + p0;	    Explain5("FTP: contacting host %d.%d.%d.%d:%d",		     h3, h2, h1, h0, pport);	    data_addr.sin_family = AF_INET;	    data_addr.sin_addr.s_addr = htonl(paddr);	    data_addr.sin_port = htons(pport);	    i = ap_proxy_doconnect(dsock, &data_addr, r);	    if (i == -1) {		ap_kill_timeout(r);		return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool,				"Could not connect to remote machine: ",				strerror(errno), NULL));	    }	    else {		pasvmode = 1;	    }	}	else	    ap_pclosesocket(p, dsock);	/* and try the regular way */    }    if (!pasvmode) {		/* set up data connection */	clen = sizeof(struct sockaddr_in);	if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: error getting socket address");	    ap_bclose(f);	    ap_kill_timeout(r);	    return HTTP_INTERNAL_SERVER_ERROR;	}	dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);	if (dsock == -1) {	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: error creating socket");	    ap_bclose(f);	    ap_kill_timeout(r);	    return HTTP_INTERNAL_SERVER_ERROR;	}	if (setsockopt(dsock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,		       sizeof(one)) == -1) {#ifndef _OSD_POSIX /* BS2000 has this option "always on" */	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: error setting reuseaddr option");	    ap_pclosesocket(p, dsock);	    ap_bclose(f);	    ap_kill_timeout(r);	    return HTTP_INTERNAL_SERVER_ERROR;#endif /*_OSD_POSIX*/	}	if (bind(dsock, (struct sockaddr *) &server,		 sizeof(struct sockaddr_in)) == -1) {	    char buff[22];	    ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: error binding to ftp data socket %s", buff);	    ap_bclose(f);	    ap_pclosesocket(p, dsock);	    return HTTP_INTERNAL_SERVER_ERROR;	}	listen(dsock, 2);	/* only need a short queue */    }/* set request; "path" holds last path component */    len = decodeenc(path);    /* TM - if len == 0 then it must be a directory (you can't RETR nothing) */    if (len == 0) {	parms = "d";    }    else {	ap_bvputs(f, "SIZE ", path, CRLF, NULL);	ap_bflush(f);	Explain1("FTP: SIZE %s", path);	i = ftp_getrc_msg(f, resp, sizeof resp);	Explain2("FTP: returned status %d with response %s", i, resp);	if (i != 500) {		/* Size command not recognized */	    if (i == 550) {	/* Not a regular file */		Explain0("FTP: SIZE shows this is a directory");		parms = "d";		ap_bvputs(f, "CWD ", path, CRLF, NULL);		ap_bflush(f);		Explain1("FTP: CWD %s", path);		i = ftp_getrc(f);		/* possible results: 250, 421, 500, 501, 502, 530, 550 */		/* 250 Requested file action okay, completed. */		/* 421 Service not available, closing control connection. */		/* 500 Syntax error, command unrecognized. */		/* 501 Syntax error in parameters or arguments. */		/* 502 Command not implemented. */		/* 530 Not logged in. */		/* 550 Requested action not taken. */		Explain1("FTP: returned status %d", i);		if (i == -1) {		    ap_kill_timeout(r);		    return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");		}		if (i == 550) {		    ap_kill_timeout(r);		    return HTTP_NOT_FOUND;		}		if (i != 250) {		    ap_kill_timeout(r);		    return HTTP_BAD_GATEWAY;		}		path = "";		len = 0;	    }	    else if (i == 213) { /* Size command ok */		for (j = 0; j < sizeof resp && ap_isdigit(resp[j]); j++)			;		resp[j] = '\0';		if (resp[0] != '\0')		    size = ap_pstrdup(p, resp);	    }	}    }#ifdef AUTODETECT_PWD    ap_bvputs(f, "PWD", CRLF, NULL);    ap_bflush(f);    Explain0("FTP: PWD");/* responses: 257, 500, 501, 502, 421, 550 */    /* 257 "<directory-name>" <commentary> */    /* 421 Service not available, closing control connection. */    /* 500 Syntax error, command unrecognized. */    /* 501 Syntax error in parameters or arguments. */    /* 502 Command not implemented. */    /* 550 Requested action not taken. */    i = ftp_getrc_msg(f, resp, sizeof resp);    Explain1("FTP: PWD returned status %d", i);    if (i == -1 || i == 421) {	ap_kill_timeout(r);	return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");    }    if (i == 550) {	ap_kill_timeout(r);	return HTTP_NOT_FOUND;    }    if (i == 257) {	const char *dirp = resp;	cwd = ap_getword_conf(r->pool, &dirp);    }#endif /*AUTODETECT_PWD*/    if (parms[0] == 'd') {	if (len != 0)	    ap_bvputs(f, "LIST ", path, CRLF, NULL);	else	    ap_bputs("LIST -lag" CRLF, f);	Explain1("FTP: LIST %s", (len == 0 ? "" : path));    }    else {	ap_bvputs(f, "RETR ", path, CRLF, NULL);	Explain1("FTP: RETR %s", path);    }    ap_bflush(f);/* RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, 550   NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */    /* 110 Restart marker reply. */    /* 125 Data connection already open; transfer starting. */    /* 150 File status okay; about to open data connection. */    /* 226 Closing data connection. */    /* 250 Requested file action okay, completed. */    /* 421 Service not available, closing control connection. */    /* 425 Can't open data connection. */    /* 426 Connection closed; transfer aborted. */    /* 450 Requested file action not taken. */    /* 451 Requested action aborted. Local error in processing. */    /* 500 Syntax error, command unrecognized. */    /* 501 Syntax error in parameters or arguments. */    /* 530 Not logged in. */    /* 550 Requested action not taken. */    rc = ftp_getrc(f);    Explain1("FTP: returned status %d", rc);    if (rc == -1) {	ap_kill_timeout(r);	return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");    }    if (rc == 550) {	Explain0("FTP: RETR failed, trying LIST instead");	parms = "d";	ap_bvputs(f, "CWD ", path, CRLF, NULL);	ap_bflush(f);	Explain1("FTP: CWD %s", path);	/* possible results: 250, 421, 500, 501, 502, 530, 550 */	/* 250 Requested file action okay, completed. */	/* 421 Service not available, closing control connection. */	/* 500 Syntax error, command unrecognized. */	/* 501 Syntax error in parameters or arguments. */	/* 502 Command not implemented. */	/* 530 Not logged in. */	/* 550 Requested action not taken. */	rc = ftp_getrc(f);	Explain1("FTP: returned status %d", rc);	if (rc == -1) {	    ap_kill_timeout(r);	    return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");	}	if (rc == 550) {	    ap_kill_timeout(r);	    return HTTP_NOT_FOUND;	}	if (rc != 250) {	    ap_kill_timeout(r);	    return HTTP_BAD_GATEWAY;	}#ifdef AUTODETECT_PWD	ap_bvputs(f, "PWD", CRLF, NULL);	ap_bflush(f);	Explain0("FTP: PWD");/* responses: 257, 500, 501, 502, 421, 550 */	/* 257 "<directory-name>" <commentary> */	/* 421 Service not available, closing control connection. */	/* 500 Syntax error, command unrecognized. */	/* 501 Syntax error in parameters or arguments. */	/* 502 Command not implemented. */	/* 550 Requested action not taken. */	i = ftp_getrc_msg(f, resp, sizeof resp);	Explain1("FTP: PWD returned status %d", i);	if (i == -1 || i == 421) {	    ap_kill_timeout(r);	    return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");	}	if (i == 550) {	    ap_kill_timeout(r);	    return HTTP_NOT_FOUND;	}	if (i == 257) {	    const char *dirp = resp;	    cwd = ap_getword_conf(r->pool, &dirp);	}#endif /*AUTODETECT_PWD*/	ap_bputs("LIST -lag" CRLF, f);	ap_bflush(f);	Explain0("FTP: LIST -lag");	rc = ftp_getrc(f);	Explain1("FTP: returned status %d", rc);	if (rc == -1)	    return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server");    }    ap_kill_timeout(r);    if (rc != 125 && rc != 150 && rc != 226 && rc != 250)	return HTTP_BAD_GATEWAY;    r->status = HTTP_OK;    r->status_line = "200 OK";    resp_hdrs = ap_make_table(p, 2);    c->hdrs = resp_hdrs;    if (parms[0] == 'd')	ap_table_set(resp_hdrs, "Content-Type", "text/html");    else {	if (r->content_type != NULL) {	    ap_table_set(resp_hdrs, "Content-Type", r->content_type);	    Explain1("FTP: Content-Type set to %s", r->content_type);	}	else {	    ap_table_set(resp_hdrs, "Content-Type", "text/plain");	}	if (parms[0] != 'a' && size != NULL) {	    /* We "trust" the ftp server to really serve (size) bytes... */	    ap_table_set(resp_hdrs, "Content-Length", size);	    Explain1("FTP: Content-Length set to %s", size);	}    }/* check if NoCache directive on this host */    for (i = 0; i < conf->nocaches->nelts; i++) {	if ((ncent[i].name != NULL && strstr(host, ncent[i].name) != NULL)	    || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*')	    nocache = 1;    }    i = ap_proxy_cache_update(c, resp_hdrs, 0, nocache);    if (i != DECLINED) {	ap_pclosesocket(p, dsock);	ap_bclose(f);	return i;    }    if (!pasvmode) {		/* wait for connection */	ap_hard_timeout("proxy ftp data connect", r);	clen = sizeof(struct sockaddr_in);	do	    csd = accept(dsock, (struct sockaddr *) &server, &clen);	while (csd == -1 && errno == EINTR);	if (csd == -1) {	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: failed to accept data connection");	    ap_pclosesocket(p, dsock);	    ap_bclose(f);	    ap_kill_timeout(r);	    if (c != NULL)		c = ap_proxy_cache_error(c);	    return HTTP_BAD_GATEWAY;	}	ap_note_cleanups_for_socket(p, csd);	data = ap_bcreate(p, B_RDWR | B_SOCKET);	ap_bpushfd(data, csd, -1);	ap_kill_timeout(r);    }    else {	data = ap_bcreate(p, B_RDWR | B_SOCKET);	ap_bpushfd(data, dsock, dsock);    }#ifdef CHARSET_EBCDIC/*    bsetflag(data, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);*/#endif /*CHARSET_EBCDIC*/    ap_hard_timeout("proxy receive", r);/* send response *//* write status line */    if (!r->assbackwards)	ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL);    if (c != NULL && c->fp != NULL	&& ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1)	c = ap_proxy_cache_error(c);/* send headers */    tdo.req = r;    tdo.cache = c;    ap_table_do(ap_proxy_send_hdr_line, &tdo, resp_hdrs, NULL);    if (!r->assbackwards)	ap_rputs(CRLF, r);    if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1)	c = ap_proxy_cache_error(c);    ap_bsetopt(r->connection->client, BO_BYTECT, &zero);    r->sent_bodyct = 1;/* send body */    if (!r->header_only) {	if (parms[0] != 'd') {/* we need to set this for ap_proxy_send_fb()... */	    if (c != NULL)		c->cache_completion = 0;	    ap_proxy_send_fb(data, r, c);	} else	    send_dir(data, r, c, cwd);	if (rc == 125 || rc == 150)	    rc = ftp_getrc(f);	/* XXX: we checked for 125||150||226||250 above. This is redundant. */	if (rc != 226 && rc != 250)	    c = ap_proxy_cache_error(c);    }    else {/* abort the transfer */	ap_bputs("ABOR" CRLF, f);	ap_bflush(f);	if (!pasvmode)	    ap_bclose(data);	Explain0("FTP: ABOR");/* responses: 225, 226, 421, 500, 501, 502 */    /* 225 Data connection open; no transfer in progress. */    /* 226 Closing data connection. */    /* 421 Service not available, closing control connection. */    /* 500 Syntax error, command unrecognized. */    /* 501 Syntax error in parameters or arguments. */    /* 502 Command not implemented. */	i = ftp_getrc(f);	Explain1("FTP: returned status %d", i);    }    ap_kill_timeout(r);    ap_proxy_cache_tidy(c);/* finish */    ap_bputs("QUIT" CRLF, f);    ap_bflush(f);    Explain0("FTP: QUIT");/* responses: 221, 500 */    /* 221 Service closing control connection. */    /* 500 Syntax error, command unrecognized. */    i = ftp_getrc(f);    Explain1("FTP: QUIT: status %d", i);    if (pasvmode)	ap_bclose(data);    ap_bclose(f);    ap_rflush(r);	/* flush before garbage collection */    ap_proxy_garbage_coll(r);    return OK;}

⌨️ 快捷键说明

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