・ログイン後のCookie処理不具合を修正
・処理開始毎にCookieContainerをクリアするようにした。
@@ -32,5 +32,5 @@ | ||
32 | 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を |
33 | 33 | // 既定値にすることができます: |
34 | 34 | // [assembly: AssemblyVersion("1.0.*")] |
35 | -[assembly: AssemblyVersion("1.12.0.0")] | |
36 | -[assembly: AssemblyFileVersion("1.12.0.0")] | |
35 | +[assembly: AssemblyVersion("1.13.0.0")] | |
36 | +[assembly: AssemblyFileVersion("1.13.0.0")] |
@@ -359,7 +359,7 @@ | ||
359 | 359 | /// |
360 | 360 | public const string URL_LOGIN = "https://twitter.com/login"; |
361 | 361 | public const string URL_SESSIONS = "https://twitter.com/sessions"; |
362 | - public const string USER_AGENT = "Mozilla/5.0 (compatible; MSIE 11.0; Windows NT 6.0; Trident/5.0)"; //適当 | |
362 | + public const string USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36"; //適当 | |
363 | 363 | public const string REFERER = "https://twitter.com/"; |
364 | 364 | |
365 | 365 | private const string RE_MEDIA_URL = @"https://pbs\.twimg\.com/media/([\w\-]+\.\w{3,4})(:large)?"; |
@@ -387,6 +387,7 @@ | ||
387 | 387 | /// <returns>TwitterDownloadオブジェクト、失敗したら null を返す</returns> |
388 | 388 | public static Task Begin(TwitterDownloadParams settings,Action endDownloadCallbck,Action<Exception> processException,out TwitterDownload instance) |
389 | 389 | { |
390 | + TwitterWebClient.ClearCookieContainer(); | |
390 | 391 | TwitterDownload twitter = instance = new TwitterDownload(settings); |
391 | 392 | Task t = null; |
392 | 393 |
@@ -813,6 +814,11 @@ | ||
813 | 814 | } |
814 | 815 | } |
815 | 816 | |
817 | + internal static void ClearCookieContainer() | |
818 | + { | |
819 | + cookieContainer = null; | |
820 | + } | |
821 | + | |
816 | 822 | private bool isAutoRedirectEnabled = false; |
817 | 823 | |
818 | 824 | /// <summary> |
@@ -850,10 +856,114 @@ | ||
850 | 856 | } |
851 | 857 | |
852 | 858 | /// <summary> |
853 | - /// WebClient.GetWebRequestメソッドをオーバーライド | |
859 | + /// WebClient.GetWebResponseメソッドをオーバーライド | |
854 | 860 | /// </summary> |
855 | - protected override WebRequest GetWebRequest(Uri address) | |
861 | + protected override WebResponse GetWebResponse(WebRequest request) | |
856 | 862 | { |
863 | + WebResponse response = base.GetWebResponse(request); | |
864 | + if(response is HttpWebResponse) | |
865 | + { | |
866 | + var httpWebResponse = response as HttpWebResponse; | |
867 | + fixCookies(httpWebResponse); | |
868 | + | |
869 | + cookieContainer.Add(httpWebResponse.Cookies); | |
870 | + } | |
871 | + return response; | |
872 | + } | |
873 | + | |
874 | + private void fixCookies(HttpWebResponse response) | |
875 | + { | |
876 | + foreach( string header in response.Headers) | |
877 | + { | |
878 | + string name = header; | |
879 | + if(name != "Set-Cookie") | |
880 | + continue; | |
881 | + | |
882 | + string cookies = response.Headers[name]; | |
883 | + | |
884 | + cookies = Regex.Replace(cookies, | |
885 | + @"Expires=(.+?);", | |
886 | + (m) => { | |
887 | + return string.Format("Expires={0};",m.Groups[1].Value.Replace(',','-')); | |
888 | + }, | |
889 | + RegexOptions.IgnoreCase); | |
890 | + | |
891 | + var cc = new CookieCollection(); | |
892 | + | |
893 | + foreach(var singleCookie in cookies.Split(',')) | |
894 | + { | |
895 | + string domain=null,path=null,expires=null,n=null,v=null; | |
896 | + bool httponly = false,secure = false; | |
897 | + | |
898 | + foreach(string el in Regex.Split(singleCookie, @"\s*;\s*")) | |
899 | + { | |
900 | + string[] kv = el.Split(new char[] {'='},2); | |
901 | + string key=null,val=null; | |
902 | + if(kv.Length == 2) | |
903 | + { | |
904 | + key = kv[0]; | |
905 | + val = kv[1]; | |
906 | + } | |
907 | + else if(kv.Length == 1) | |
908 | + { | |
909 | + key = kv[0]; | |
910 | + } | |
911 | + | |
912 | + switch(key.ToLower()) | |
913 | + { | |
914 | + case "domain": | |
915 | + domain = val; | |
916 | + break; | |
917 | + | |
918 | + case "expires": | |
919 | + expires = val.Replace('-',','); | |
920 | + expires = expires.Replace(" UTC","Z"); | |
921 | + break; | |
922 | + | |
923 | + case "path": | |
924 | + path = val; | |
925 | + break; | |
926 | + | |
927 | + case "httponly": | |
928 | + httponly = true; | |
929 | + break; | |
930 | + | |
931 | + case "secure": | |
932 | + secure = true; | |
933 | + break; | |
934 | + | |
935 | + default: | |
936 | + n = key; | |
937 | + v = val; | |
938 | + break; | |
939 | + } | |
940 | + } | |
941 | + var cookie = new Cookie(n,v); | |
942 | + if(!string.IsNullOrEmpty(path)) | |
943 | + cookie.Path = path; | |
944 | + | |
945 | + cookie.Domain = string.IsNullOrEmpty(domain) ? ".twitter.com" : domain; | |
946 | + | |
947 | + if(!string.IsNullOrEmpty(expires)) | |
948 | + { | |
949 | + DateTime dt; | |
950 | + if(DateTime.TryParse(expires,out dt)) | |
951 | + cookie.Expires = dt; | |
952 | + } | |
953 | + | |
954 | + cookie.HttpOnly = httponly; | |
955 | + cookie.Secure = secure; | |
956 | + | |
957 | + response.Cookies.Add(cookie); | |
958 | + } | |
959 | + } | |
960 | + } | |
961 | + | |
962 | + /// <summary> | |
963 | + /// WebClient.GetWebRequestメソッドをオーバーライド | |
964 | + /// </summary> | |
965 | + protected override WebRequest GetWebRequest(Uri address) | |
966 | + { | |
857 | 967 | WebRequest request = base.GetWebRequest(address); |
858 | 968 | |
859 | 969 | if(request is HttpWebRequest) |
@@ -861,7 +971,7 @@ | ||
861 | 971 | var httpWebRequest = request as HttpWebRequest; |
862 | 972 | if(httpWebRequest != null) |
863 | 973 | { |
864 | - httpWebRequest.CookieContainer = TwitterWebClient.cookieContainer; | |
974 | + httpWebRequest.CookieContainer = cookieContainer; | |
865 | 975 | httpWebRequest.AllowAutoRedirect = isAutoRedirectEnabled; |
866 | 976 | } |
867 | 977 | } |