/// <summary> /// Frees the resources held by the response. /// </summary> public override void Close() { if (stream != null) { stream.Close(); stream = null; } if (f != null) { GetStatus(); f.Close(); } }
internal FtpWebResponse(FtpWebRequest request) { bool success = false; this.request = request; IntPtr hFile = IntPtr.Zero; NetworkCredential credentials = null; if (request.Credentials != null) { credentials = (NetworkCredential)request.Credentials; } else { //parse user info in the uri string userInfo = request.RequestUri.UserInfo; if (!string.IsNullOrEmpty(userInfo)) { //username and password if (userInfo.IndexOf(':') > -1) { string[] userParts = userInfo.Split(':'); credentials = new NetworkCredential(userParts[0], userParts[1]); } else { //username only credentials = new NetworkCredential(userInfo, string.Empty); } request.Credentials = credentials; } } f = new Ftp(request.RequestUri, credentials, request.UsePassive); GetStatus(); /*// Set timeout if not default * if (request.Timeout != System.Threading.Timeout.Infinite) * { * int timeout = request.Timeout; * bool timeoutSet = NativeMethods.InternetSetOption(f.Handle, NativeMethods.INTERNET_OPTION_CONNECT_TIMEOUT, ref timeout, 4); * }*/ //set default response uri if (request.RequestUri.UserInfo != string.Empty) { StringBuilder cleanUri = new StringBuilder(); cleanUri.Append(request.RequestUri.Scheme); for (int i = 2; i < request.RequestUri.Segments.Length; i++) { cleanUri.Append(request.RequestUri.Segments[i]); } responseUri = new Uri(cleanUri.ToString()); } else { responseUri = request.RequestUri; } switch (request.Method) { case WebRequestMethods.Ftp.DeleteFile: success = NativeMethods.pFtpDeleteFile(f.Handle, request.RequestUri.LocalPath); break; case WebRequestMethods.Ftp.DownloadFile: //resolved issue with caching hFile = NativeMethods.pFtpOpenFile(f.Handle, request.RequestUri.LocalPath, NativeMethods.GENERIC_READ, (request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII) | NativeMethods.INTERNET_FLAG_RELOAD, this.GetHashCode()); GetStatus(); if (hFile == IntPtr.Zero) { NativeMethods.ThrowException(this); } stream = new InternetFileStream(hFile, this, false); contentLength = -1; success = true; break; case WebRequestMethods.Ftp.PrintWorkingDirectory: StringBuilder workingDirectoryBuffer = new StringBuilder(260); int len = workingDirectoryBuffer.Capacity; success = NativeMethods.pFtpGetCurrentDirectory(f.Handle, workingDirectoryBuffer, ref len); this.responseUri = new Uri(new Uri(this.request.RequestUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped)), workingDirectoryBuffer.ToString()); break; case WebRequestMethods.Ftp.MakeDirectory: success = NativeMethods.pFtpCreateDirectory(f.Handle, request.RequestUri.LocalPath); break; case WebRequestMethods.Ftp.Rename: success = NativeMethods.pFtpRenameFile(f.Handle, request.RequestUri.LocalPath, request.RenameTo); break; case WebRequestMethods.Ftp.UploadFile: hFile = NativeMethods.pFtpOpenFile(f.Handle, request.RequestUri.LocalPath, NativeMethods.GENERIC_WRITE, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, this.GetHashCode()); GetStatus(); if (hFile == IntPtr.Zero) { NativeMethods.ThrowException(this); } InternetFileStream uploadStream = new InternetFileStream(hFile, this, true); byte[] uploadBuffer = ((MemoryStream)request.GetRequestStream()).ToArray(); uploadStream.Write(uploadBuffer, 0, uploadBuffer.Length); uploadStream.Close(); success = true; break; case WebRequestMethods.Ftp.ListDirectory: case WebRequestMethods.Ftp.ListDirectoryDetails: success = NativeMethods.pFtpCommand(f.Handle, true, /*request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY :*/ NativeMethods.FTP_TRANSFER_TYPE_ASCII, request.Method + " " + request.RequestUri.LocalPath + "\r\n" /*command.ToString()*/, 0, out hFile); GetStatus(); if (!success) { NativeMethods.ThrowException(this); } stream = new InternetFileStream(hFile, this, false); contentLength = stream.Length; break; default: //separate path and file name string[] bits = SplitLocalPath(request.RequestUri.LocalPath); //create command string StringBuilder command = new StringBuilder(); command.Append(request.Method); if (!string.IsNullOrEmpty(bits[1])) { command.Append(" "); //if have a filename send it (separated with a space) command.Append(bits[1]); } //add return command.Append("\r\n"); if (!string.IsNullOrEmpty(bits[0])) { //only change folder if not the root if (bits[0] != "\\") { //change path if required success = NativeMethods.pFtpSetCurrentDirectory(f.Handle, bits[0]); //success = NativeMethods.FtpCommand(f.Handle, false, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, "CWD " + bits[0] + "\r\n", 0, out hFile); } } //switch on the remaining methods switch (request.Method) { case WebRequestMethods.Ftp.AppendFile: success = NativeMethods.pFtpCommand(f.Handle, true, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, command.ToString(), 0, out hFile); GetStatus(); if (!success) { NativeMethods.ThrowException(this); } InternetFileStream appendStream = new InternetFileStream(hFile, this, true); byte[] appendBuffer = ((MemoryStream)request.GetRequestStream()).ToArray(); appendStream.Write(appendBuffer, 0, appendBuffer.Length); appendStream.Close(); break; case WebRequestMethods.Ftp.GetDateTimestamp: success = NativeMethods.pFtpCommand(f.Handle, false, /*request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY :*/ NativeMethods.FTP_TRANSFER_TYPE_ASCII, command.ToString(), 0, out hFile); GetStatus(); int timeSpaceIndex = this.statusDescription.LastIndexOf(' '); if (timeSpaceIndex > -1) { string timestamp = this.statusDescription.Substring(timeSpaceIndex + 1, (this.statusDescription.Length - timeSpaceIndex) - 1); try { this.lastModified = DateTime.ParseExact(timestamp, "yyyyMMddHHmmss", null); this.lastModified = DateTime.SpecifyKind(this.lastModified, DateTimeKind.Utc); } catch { success = false; } } break; case WebRequestMethods.Ftp.GetFileSize: success = NativeMethods.pFtpCommand(f.Handle, false, /*request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY :*/ NativeMethods.FTP_TRANSFER_TYPE_ASCII, command.ToString(), 0, out hFile); GetStatus(); int sizeSpaceIndex = this.statusDescription.LastIndexOf(' '); if (sizeSpaceIndex > -1) { string size = this.statusDescription.Substring(sizeSpaceIndex + 1, (this.statusDescription.Length - sizeSpaceIndex) - 1); try { this.contentLength = long.Parse(size); } catch { success = false; } } break; case WebRequestMethods.Ftp.UploadFileWithUniqueName: success = NativeMethods.pFtpCommand(f.Handle, false, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, command.ToString(), this.GetHashCode(), out hFile); GetStatus(); try { if (!success) { NativeMethods.ThrowException(this); } } finally { f.Close(); } f = new Ftp(request.RequestUri, credentials, request.UsePassive); //get unique filename from response int spaceIndex = this.statusDescription.LastIndexOf(' '); if (spaceIndex > -1) { string filename = this.statusDescription.Substring(spaceIndex + 1, (statusDescription.Length - spaceIndex) - 1); filename = filename.TrimEnd('.'); responseUri = new Uri("ftp://" + request.RequestUri.Host + "/" + bits[0] + filename); } //open file hFile = NativeMethods.pFtpOpenFile(f.Handle, responseUri.LocalPath, NativeMethods.GENERIC_WRITE, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, 0); GetStatus(); if (hFile == IntPtr.Zero) { NativeMethods.ThrowException(this); } InternetFileStream uniqueStream = new InternetFileStream(hFile, this, true); byte[] uniqueBuffer = ((MemoryStream)request.GetRequestStream()).ToArray(); uniqueStream.Write(uniqueBuffer, 0, uniqueBuffer.Length); uniqueStream.Close(); success = true; break; default: success = NativeMethods.pFtpCommand(f.Handle, false, request.UseBinary ? NativeMethods.FTP_TRANSFER_TYPE_BINARY : NativeMethods.FTP_TRANSFER_TYPE_ASCII, request.Method + "\r\n", 0, out hFile); break; } break; } GetStatus(); if (!success) { NativeMethods.ThrowException(this); } }