qt5集成libcurl实现tftp和ftp的方法之三:搭建FTP时,当ftpServer端默认登录的目录不是根目录/时,有一个bug会产生的解决办法
来源:互联网 发布:php ext文件夹 编辑:程序博客网 时间:2024/05/17 06:41
最近在使用curl时遇到一个问题,老出现下面的错误提示:
< 550 Failed to change directory.* Server denied you to change to the given directory* Connection #0 to host 192.168.2.223 left intact* Access denied to remote resource在网上找了很长时间,发现真正有价值的博客非常少,只有两个:
http://blog.dou.li/curl-9-server-denied-you-to-change-to-the-given-directory.html和
http://blog.csdn.net/langeldep/article/details/6166218,不过少比没有好,第二个博客的方法确实能解决问题,所以,我将解决该问题的方法稍作整理。
解决该问题的方法有三种:
第一种是上面链接1,通过严格地设置文件的路径,但是我测试发现不好使。
第二种方法是上面链接2,通过修改代码实现。测试发现确实能解决问题。
第三种方法,没必要修改源码,这不是BUG,只要添加下面的语句设置好参数就行了,不过这种方法我没测试,不知道好不好用。
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
第二种方法的详细解释和操作过程为:
CURL 库在使用FTP传输文件时, 正常情况下, ftp的server端都会默认进入根目录 /, 但是当ftp的server端设置了一个子目录,比如 ftp的server设置了 /data/movies 为第一次默认进入的目录, 则curl的FTP将会无法传输文件, 错误的原因是 :
ftp的下载地址为 ftp://root:123456@192.168.2.223/data/movies/vbr.ts
而第一次进入的目录为 /data/movies , 而curl库的FTP解析ftp地址得出 要进入 data 和movies 目录后才能找到下载的文件,
就会去执行 CWD data 和 CWD movies , 而在 /data/movies 这个目录去进入 data 目录, 目录肯定是不存在的,
所以出错。
* About to connect() to 192.168.2.223 port 21 (#0)* Trying 192.168.2.223... Leave Lock = Resume Download File* connected* Connected to 192.168.2.223 (192.168.2.223) port 21 (#0)< 220 (vsFTPd 2.0.5)> USER root< 331 Please specify the password.> PASS 123456< 230 Login successful.> PWD< 257 "/data/movies"* Entry path is '/data/movies'> CWD data< 550 Failed to change directory.* Server denied you to change to the given directory* Connection #0 to host 192.168.2.223 left intact* Access denied to remote resource> QUIT< 221 Goodbye.* Closing connection #0修改方法是 修改 curl库目录下面 lib文件夹下面的 ftp.c 文件,在函数 static CURLcode ftp_parse_url_path(struct connectdata *conn) 中 添加如下代码
if (ftpc->dirdepth == 0)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>ftpc->dirs[0] = strdup("/");<span style="white-space:pre"></span>ftpc->dirdepth++;<span style="white-space:pre"></span>}意思就是 让ftp客户端从 根目录开始一级一级的进入到文件所在的目录。添加的位置如下 :
default: /* allow pretty much anything */ case FTPFILE_MULTICWD: ftpc->dirdepth = 0; ftpc->diralloc = 5; /* default dir depth to allocate */ ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0])); if(!ftpc->dirs) return CURLE_OUT_OF_MEMORY; /* we have a special case for listing the root dir only */ if(strequal(path_to_use, "/")) { cur_pos++; /* make it point to the zero byte */ ftpc->dirs[0] = strdup("/"); ftpc->dirdepth++; } else { /* parse the URL path into separate path components */ while((slash_pos = strchr(cur_pos, '/')) != NULL) { /* 1 or 0 pointer offset to indicate absolute directory */ ssize_t absolute_dir = ((cur_pos - data->state.path > 0) && (ftpc->dirdepth == 0))?1:0;<span style="color:#ff0000;">if (ftpc->dirdepth == 0){ftpc->dirs[0] = strdup("/");ftpc->dirdepth++;}</span> /* seek out the next path component */ if(slash_pos-cur_pos) { /* we skip empty path components, like "x//y" since the FTP command CWD requires a parameter and a non-existant parameter a) doesn't work on many servers and b) has no effect on the others. */ int len = (int)(slash_pos - cur_pos + absolute_dir); ftpc->dirs[ftpc->dirdepth] = curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL); if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */ failf(data, "no memory"); freedirs(ftpc); return CURLE_OUT_OF_MEMORY; } if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) { free(ftpc->dirs[ftpc->dirdepth]); freedirs(ftpc); return CURLE_URL_MALFORMAT; } } else { cur_pos = slash_pos + 1; /* jump to the rest of the string */ continue; } cur_pos = slash_pos + 1; /* jump to the rest of the string */ if(++ftpc->dirdepth >= ftpc->diralloc) { /* enlarge array */ char *bigger; ftpc->diralloc *= 2; /* double the size each time */ bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0])); if(!bigger) { freedirs(ftpc); return CURLE_OUT_OF_MEMORY; } ftpc->dirs = (char **)bigger; } } } filename = cur_pos; /* the rest is the file name */ break; } /* switch */
然后按照前一篇博客http://blog.csdn.net/xueyushenzhou/article/details/51702672的说明,重新编译出共享库,再将原来的都替换掉就行啦。
- qt5集成libcurl实现tftp和ftp的方法之三:搭建FTP时,当ftpServer端默认登录的目录不是根目录/时,有一个bug会产生的解决办法
- CURL库FTP传输文件,当ftpServer端默认登录的目录不是根目录/时,有一个bug会产生
- qt5集成libcurl实现tftp和ftp的方法一:搭建环境
- qt5集成libcurl实现tftp和ftp的方法之四:实现ftp文件上传和下载
- qt5集成libcurl实现tftp和ftp的方法之二:实现tftp文件上传和下载
- qt5实现tftp和ftp的方法之五:使用Qtftp实现ftp的方法
- 使用apache的ftpserver搭建ftp服务器
- TFTP和FTP的区别
- FTP和TFTP的区别
- 【ftp】ftp服务器无法登录的解决办法
- ftp和ssh登录缓慢的解决办法
- 设置LINUX 服务器中FTP 用户登录的默认目录
- libcurl使用ftp的一个例子
- Ubuntu ftp tftp 服务器的搭建
- BusyBox中的FTP和TFTP的使用
- Linux下FTP服务器默认目录的更改方法
- Linux下FTP服务器默认目录的更改方法
- Apache FTPServer搭建FTP
- 表的查询(三)
- Hibernate框架基础知识第一天
- poj2186【利用强连通分量】
- C/C++笔记(C语言重要问题重讲,数据篇)
- ORACLE和MYSQL查询表字段信息的sql
- qt5集成libcurl实现tftp和ftp的方法之三:搭建FTP时,当ftpServer端默认登录的目录不是根目录/时,有一个bug会产生的解决办法
- 身份验证中Cookies与 Tokens比较
- Lwip学习笔记之UDP
- CMUSphinx语音识别工具包的概述
- HDU 1018 Big Number
- 设计模式-单例模式
- 指针与野指针
- Dialog的回退按钮的点击事件
- Spring开发环境配置以及入门案例