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

📄 ftp.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 2 页
字号:
	    }	    my $mess = $ftp->message;	    LWP::Debug::debug($mess);	    if ($mess =~ /\((\d+)\s+bytes\)/) {		$response->header('Content-Length', "$1");	    }	    if ($method ne 'HEAD') {		# Read data from server		$response = $self->collect($arg, $response, sub {		    my $content = '';		    my $result = $data->read($content, $size);                    # Stop early if we need to.                    if (defined $max_size)                    {                      # We need an interface to Net::FTP::dataconn for getting                      # the number of bytes already read                      my $bytes_received = $data->bytes_read();                      # We were already over the limit. (Should only happen                      # once at the end.)                      if ($bytes_received - length($content) > $max_size)                      {                        $content = '';                      }                      # We just went over the limit                      elsif ($bytes_received  > $max_size)                      {                        # Trim content                        $content = substr($content, 0,                          $max_size - ($bytes_received - length($content)) );                      }                      # We're under the limit                      else                      {                      }                    }		    return \$content;		} );	    }	    # abort is needed for HEAD, it's == close if the transfer has	    # already completed.	    unless ($data->abort) {		# Something did not work too well.  Note that we treat		# responses to abort() with code 0 in case of HEAD as ok		# (at least wu-ftpd 2.6.1(1) does that).		if ($method ne 'HEAD' || $ftp->code != 0) {		    $response->code(&HTTP::Status::RC_INTERNAL_SERVER_ERROR);		    $response->message("FTP close response: " . $ftp->code .				       " " . $ftp->message);		}	    }	}	elsif (!length($remote_file) || ( $ftp->code >= 400 && $ftp->code < 600 )) {	    # not a plain file, try to list instead	    if (length($remote_file) && !$ftp->cwd($remote_file)) {		LWP::Debug::debug("chdir before listing failed");		return HTTP::Response->new(&HTTP::Status::RC_NOT_FOUND,					   "File '$remote_file' not found");	    }	    # It should now be safe to try to list the directory	    LWP::Debug::debug("dir");	    my @lsl = $ftp->dir;	    # Try to figure out if the user want us to convert the	    # directory listing to HTML.	    my @variants =	      (	       ['html',  0.60, 'text/html'            ],	       ['dir',   1.00, 'text/ftp-dir-listing' ]	      );	    #$HTTP::Negotiate::DEBUG=1;	    my $prefer = HTTP::Negotiate::choose(\@variants, $request);	    my $content = '';	    if (!defined($prefer)) {		return HTTP::Response->new(&HTTP::Status::RC_NOT_ACCEPTABLE,			       "Neither HTML nor directory listing wanted");	    }	    elsif ($prefer eq 'html') {		$response->header('Content-Type' => 'text/html');		$content = "<HEAD><TITLE>File Listing</TITLE>\n";		my $base = $request->url->clone;		my $path = $base->path;		$base->path("$path/") unless $path =~ m|/$|;		$content .= qq(<BASE HREF="$base">\n</HEAD>\n);		$content .= "<BODY>\n<UL>\n";		for (File::Listing::parse_dir(\@lsl, 'GMT')) {		    my($name, $type, $size, $mtime, $mode) = @$_;		    $content .= qq(  <LI> <a href="$name">$name</a>);		    $content .= " $size bytes" if $type eq 'f';		    $content .= "\n";		}		$content .= "</UL></body>\n";	    }	    else {		$response->header('Content-Type', 'text/ftp-dir-listing');		$content = join("\n", @lsl, '');	    }	    $response->header('Content-Length', length($content));	    if ($method ne 'HEAD') {		$response = $self->collect_once($arg, $response, $content);	    }	}	else {	    my $res = HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,			  "FTP return code " . $ftp->code);	    $res->content_type("text/plain");	    $res->content($ftp->message);	    return $res;	}    }    elsif ($method eq 'PUT') {	# method must be PUT	unless (length($remote_file)) {	    return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,				       "Must have a file name to PUT to");	}	my $data;	if ($data = $ftp->stor($remote_file)) {	    LWP::Debug::debug($ftp->message);	    LWP::Debug::debug("$data");	    my $content = $request->content;	    my $bytes = 0;	    if (defined $content) {		if (ref($content) eq 'SCALAR') {		    $bytes = $data->write($$content, length($$content));		}		elsif (ref($content) eq 'CODE') {		    my($buf, $n);		    while (length($buf = &$content)) {			$n = $data->write($buf, length($buf));			last unless $n;			$bytes += $n;		    }		}		elsif (!ref($content)) {		    if (defined $content && length($content)) {			$bytes = $data->write($content, length($content));		    }		}		else {		    die "Bad content";		}	    }	    $data->close;	    LWP::Debug::debug($ftp->message);	    $response->code(&HTTP::Status::RC_CREATED);	    $response->header('Content-Type', 'text/plain');	    $response->content("$bytes bytes stored as $remote_file on $host\n")	}	else {	    my $res = HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,					  "FTP return code " . $ftp->code);	    $res->content_type("text/plain");	    $res->content($ftp->message);	    return $res;	}    }    else {	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,				   "Illegal method $method");    }    $response;}1;__END__# This is what RFC 1738 has to say about FTP access:# --------------------------------------------------## 3.2. FTP##    The FTP URL scheme is used to designate files and directories on#    Internet hosts accessible using the FTP protocol (RFC959).##    A FTP URL follow the syntax described in Section 3.1.  If :<port> is#    omitted, the port defaults to 21.## 3.2.1. FTP Name and Password##    A user name and password may be supplied; they are used in the ftp#    "USER" and "PASS" commands after first making the connection to the#    FTP server.  If no user name or password is supplied and one is#    requested by the FTP server, the conventions for "anonymous" FTP are#    to be used, as follows:##         The user name "anonymous" is supplied.##         The password is supplied as the Internet e-mail address#         of the end user accessing the resource.##    If the URL supplies a user name but no password, and the remote#    server requests a password, the program interpreting the FTP URL#    should request one from the user.## 3.2.2. FTP url-path##    The url-path of a FTP URL has the following syntax:##         <cwd1>/<cwd2>/.../<cwdN>/<name>;type=<typecode>##    Where <cwd1> through <cwdN> and <name> are (possibly encoded) strings#    and <typecode> is one of the characters "a", "i", or "d".  The part#    ";type=<typecode>" may be omitted. The <cwdx> and <name> parts may be#    empty. The whole url-path may be omitted, including the "/"#    delimiting it from the prefix containing user, password, host, and#    port.##    The url-path is interpreted as a series of FTP commands as follows:##       Each of the <cwd> elements is to be supplied, sequentially, as the#       argument to a CWD (change working directory) command.##       If the typecode is "d", perform a NLST (name list) command with#       <name> as the argument, and interpret the results as a file#       directory listing.##       Otherwise, perform a TYPE command with <typecode> as the argument,#       and then access the file whose name is <name> (for example, using#       the RETR command.)##    Within a name or CWD component, the characters "/" and ";" are#    reserved and must be encoded. The components are decoded prior to#    their use in the FTP protocol.  In particular, if the appropriate FTP#    sequence to access a particular file requires supplying a string#    containing a "/" as an argument to a CWD or RETR command, it is#    necessary to encode each "/".##    For example, the URL <URL:ftp://myname@host.dom/%2Fetc/motd> is#    interpreted by FTP-ing to "host.dom", logging in as "myname"#    (prompting for a password if it is asked for), and then executing#    "CWD /etc" and then "RETR motd". This has a different meaning from#    <URL:ftp://myname@host.dom/etc/motd> which would "CWD etc" and then#    "RETR motd"; the initial "CWD" might be executed relative to the#    default directory for "myname". On the other hand,#    <URL:ftp://myname@host.dom//etc/motd>, would "CWD " with a null#    argument, then "CWD etc", and then "RETR motd".##    FTP URLs may also be used for other operations; for example, it is#    possible to update a file on a remote file server, or infer#    information about it from the directory listings. The mechanism for#    doing so is not spelled out here.## 3.2.3. FTP Typecode is Optional##    The entire ;type=<typecode> part of a FTP URL is optional. If it is#    omitted, the client program interpreting the URL must guess the#    appropriate mode to use. In general, the data content type of a file#    can only be guessed from the name, e.g., from the suffix of the name;#    the appropriate type code to be used for transfer of the file can#    then be deduced from the data content of the file.## 3.2.4 Hierarchy##    For some file systems, the "/" used to denote the hierarchical#    structure of the URL corresponds to the delimiter used to construct a#    file name hierarchy, and thus, the filename will look similar to the#    URL path. This does NOT mean that the URL is a Unix filename.## 3.2.5. Optimization##    Clients accessing resources via FTP may employ additional heuristics#    to optimize the interaction. For some FTP servers, for example, it#    may be reasonable to keep the control connection open while accessing#    multiple URLs from the same server. However, there is no common#    hierarchical model to the FTP protocol, so if a directory change#    command has been given, it is impossible in general to deduce what#    sequence should be given to navigate to another directory for a#    second retrieval, if the paths are different.  The only reliable#    algorithm is to disconnect and reestablish the control connection.

⌨️ 快捷键说明

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