【问题】
模拟登陆:
(用户名:72qt
密码:hx123456)
对应的核心部分是:
然后用代码:
public void emualeLoginAndAdd()
{
crifanLib crl = new crifanLib();
Dictionary<string, string> headerDict;
Dictionary<string, string> postDict;
//step1: http://new.guguyu.com/add.php
string addPhpUrl = "http://new.guguyu.com/add.php";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addPhpUrl);
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");
//step2: http://new.guguyu.com/add.php?nk=1
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addPhpUrl);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
postDict = new Dictionary<string, string>();
//uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
postDict.Add("uname", txtUserName.Text);
postDict.Add("pwd", txtPassword.Text);
postDict.Add("Submit.x", "44");
postDict.Add("Submit.y", "21");
string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>
//step3: http://new.guguyu.com/add/
string addUrl = "http://new.guguyu.com/add/";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addNk1Url);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("allowautoredirect", "false");
headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html
//step4: http://new.guguyu.com/add/?nk=1
string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addUrl);
headerDict.Add("allowautoredirect", "false");
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
}去调试,结果始终后面的结果不对:
step3去访问:
但是得到的,不是正常的html,而是之前的那个:
<script>location.href='/add/'</script>
对应的,step4,获得也不是正常的html,也是上面的那个值。
【解决过程】
1.调试了N个小时,最终找到根本原因了:
C#代码:
resp = (HttpWebResponse)req.GetResponse();
updateLocalCookies(resp.Cookies, ref curCookies);中的resp.Cookies,其实是
C#的http库,针对:
{Vary: Accept-Encoding Content-Length: 53 Content-Type: text/html Date: Thu, 01 Aug 2013 16:05:12 GMT Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT Server: Apache/2.2.9 (APMServ) PHP/5.2.6 X-Powered-By: PHP/5.2.6 } |
中的:
| Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT |
解析后的cookie,但是,由于C#的解析Set-Cookie有bug,导致解析出来的cookie,虽然其他值都对,包括name是UNAME,但是path的值却出错了:
| path="add.php" |
而实际上,应该是:
| path="" |
对应的,抓包出来的是正常的,path是空的:
2.知道原因后,结果就可以去修改代码了:
主要就是:
要么手动去把cookie的path值清空;
要么去删除错误的cookie,重新自己写代码解析Set-Cookie,以此获得正确的path为空的cookie;
此处用后者,代码为:
public void emualeLoginAndAdd()
{
crifanLib crl = new crifanLib();
Dictionary<string, string> headerDict;
Dictionary<string, string> postDict;
//step1: http://new.guguyu.com/add.php
string addPhpUrl = "http://new.guguyu.com/add.php";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addPhpUrl);
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");
//step2: http://new.guguyu.com/add.php?nk=1
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addPhpUrl);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
postDict = new Dictionary<string, string>();
//uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
postDict.Add("uname", txtUserName.Text);
postDict.Add("pwd", txtPassword.Text);
postDict.Add("Submit.x", "44");
postDict.Add("Submit.y", "21");
string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
//string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>
//!!! here, above step, will got a uncorrect cookie
//which abnormally, pass:
//Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT
//into cookie name is "UNAME",but path="/add" -> correct one should be path=""
//so following, use manually process cookie
HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script>
String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com
CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain);
CookieCollection curCookies = crl.getCurCookies();
crl.updateLocalCookies(parsedCookies, ref curCookies);
crl.setCurCookies(curCookies);
//step3: http://new.guguyu.com/add/
string addUrl = "http://new.guguyu.com/add/";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addNk1Url);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("allowautoredirect", "false");
headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html
//step4: http://new.guguyu.com/add/?nk=1
string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
headerDict = new Dictionary<string, string>();
headerDict.Add("Referer", addUrl);
headerDict.Add("allowautoredirect", "false");
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
headerDict.Add("DNT", "1");
headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
// here can get real html, which conains
/*
<td colspan='2' align='center'>
<input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/>
<input name='check' type='hidden' value='6283' />
<a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a> <a href='?nk=5'><font size='3'>【批量发布新服】</font></a> 全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td>
*/
}
解析后的cookie,path是空的:
3.经过继续的验证,发现很多参数,是可以去掉的:
public void emualeLoginAndAdd()
{
crifanLib crl = new crifanLib();
Dictionary<string, string> headerDict;
Dictionary<string, string> postDict;
//step1: http://new.guguyu.com/add.php
string addPhpUrl = "http://new.guguyu.com/add.php";
headerDict = new Dictionary<string, string>();
//headerDict.Add("Referer", addPhpUrl);
//headerDict.Add("DNT", "1");
//headerDict.Add("Accept-Language", "zh-CN");
string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");
//step2: http://new.guguyu.com/add.php?nk=1
headerDict = new Dictionary<string, string>();
//headerDict.Add("Referer", addPhpUrl);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
//headerDict.Add("DNT", "1");
//headerDict.Add("Accept-Language", "zh-CN");
postDict = new Dictionary<string, string>();
//uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
postDict.Add("uname", txtUserName.Text);
postDict.Add("pwd", txtPassword.Text);
//postDict.Add("Submit.x", "44");
//postDict.Add("Submit.y", "21");
string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
//string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>
//!!! here, above step, will got a uncorrect cookie
//which abnormally, pass:
//Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT
//into cookie name is "UNAME",but path="/add" -> correct one should be path=""
//so following, use manually process cookie
HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script>
String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com
CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain);
CookieCollection curCookies = crl.getCurCookies();
crl.updateLocalCookies(parsedCookies, ref curCookies);
crl.setCurCookies(curCookies);
//step3: http://new.guguyu.com/add/
string addUrl = "http://new.guguyu.com/add/";
headerDict = new Dictionary<string, string>();
//headerDict.Add("Referer", addNk1Url);
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
//headerDict.Add("DNT", "1");
//headerDict.Add("allowautoredirect", "false");
//headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html
//step4: http://new.guguyu.com/add/?nk=1
string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
headerDict = new Dictionary<string, string>();
//headerDict.Add("Referer", addUrl);
//headerDict.Add("allowautoredirect", "false");
//headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
//headerDict.Add("DNT", "1");
//headerDict.Add("Accept-Language", "zh-CN");
string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
// here can get real html, which conains
/*
<td colspan='2' align='center'>
<input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/>
<input name='check' type='hidden' value='6283' />
<a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a> <a href='?nk=5'><font size='3'>【批量发布新服】</font></a> 全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td>
*/
}4.其中,用到的crifanLib.cs,详见:
http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
【总结】
加上之前遇到的一个bug:
【已解决】C#中得到的Http的response中的Set-Cookie的内容的格式不对/错误/不正确 –> 已实现把Set-Cookie部分的字符串解析为CookieCollection
【经验记录】C#中,库函数有bug,会将http所返回的response响应中的headers头信息中的Set-Cookie值,解析错误,丢失部分cookie
算下来,C#的http的库,在解析cookie方面(解析返回的Set-Cookie)方面,真的是,bug奇多,害人不浅啊。
转载请注明:在路上 » 【已解决】又发现一个C#中解析Set-Cookie的一个bug:无故地添加cookie的path域