`

Google Doc API研究之一:模拟页面上传任意类型文件

阅读更多

浏览帖子时,发现一段读取cookie的代码,感觉不错,对自己启发挺大,转过来学习一下

Google Doc API研究之一:模拟页面上传任意类型文件

一直以来想要做个程序,将google doc用作网盘,程序做 的差不多了才发现不是所有的人都可以上传任意类型的文件,只有商业用户才可以。商业用户是要交钱的的,这与我们倡导的免费精神相关太远。怎么办,我的心血 不能白费,google还算厚道没有把门关死,可以通过form的形式上传,我们可以模拟form的动作,就能上传了。好了费话少话,说实在的。

Google在上传时要进行身份验证。取得身份验证后,提出上传要求,这时返回一个上传地址,然后上传文件。下面一步步来。

第一步,通过网页访问DOC,其身份认证是通过cookie进行的,取得cookie的过程是

1、先访问http://docs.google.com,它通过自动跳转将你带到一个登录页面。按登录页面中的头部的set- cookie设置httpwebrequest的cookie,cookie中最重要的是HSID,然后设置url为 https://www.google.com/accounts/ServiceLoginAuth?service=writely 。然后设置提交数据ltmpl=homepage&continue=http://docs.google.com/& followup=http://docs.google.com/&service=writely&nui=1& rm=false&dsh={0}&ltmpl=homepage&ltmpl=homepage&GALX={1}& amp;Email={2}&Passwd={3}&rmShown=1&signIn=登录&asts=

其中Email填google帐户名,passwd填密码,GALX可以从cookie中找到,dsh可从页面的数据中得到。

2、再访问网址:https://www.google.com/accounts /CheckCookie?continue=http%3A%2F%2Fdocs.google.com%2F&followup=http %3A%2F%2Fdocs.google.com%2F&service=writely&ltmpl=homepage& chtml=LoginDoneHtml,取得下一步的访问地址,

3、再访问网 址:http://docs.google.com/?auth=.......,根据回应设置cookie,这时的cookie就是可以访问相当于 doc api中的token了。cookie中包含三条记录HSI,SID,writelySID。

下面是原程序:

private CookieContainer  GetAuthenticationCookie(string User,string Passwd)
        {

            string GALX;
            string dsh;
            string resText = "";
            CookieContainer Auth = new CookieContainer();

            //第一步
            HttpWebRequest req = CreatRequest("http://docs.google.com/");
            req.Method = "POST";
            req.ContentLength = 0;
            HttpWebResponse res = (HttpWebResponse)req.GetResponse();

            //第二步
            resText = getResponseText(res);

            GALX = resText.Substring(resText.IndexOf("GALX") + 26, 11);
            if ((resText.Substring(resText.IndexOf("dsh") + 32, 1)) == "-")
                dsh = resText.Substring(resText.IndexOf("dsh") + 32, 20);
            else
                dsh = resText.Substring(resText.IndexOf("dsh") + 32, 19);
            string postData = string.Format(
                "ltmpl=homepage&continue=http://docs.google.com/&followup=http: //docs.google.com/&service=writely&nui=1&rm=false&dsh= {0}&ltmpl=homepage&ltmpl=homepage&GALX={1}&Email={2}& amp; amp;Passwd={3}&rmShown=1&signIn=登录&asts="
                , dsh, GALX, User, Passwd);


            req = CreatRequest("https://www.google.com/accounts/ServiceLoginAuth?service=writely ");
            req.AllowAutoRedirect = false;
            req.Method = "POST";

            //设置cookie及提交数据

            Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            setPostData(req, postData);
            res = (HttpWebResponse)req.GetResponse();

            //第三步

            req = CreatRequest(res.Headers["Location"]);
            Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            res = (HttpWebResponse)req.GetResponse();

            //第四步
            resText = getResponseText(res);
            string url = resText.Substring(resText.IndexOf("url=")).Split('\"')[0];
            url = HttpUtility.HtmlDecode(url);
            url = url.Substring(5, url.Length - 6);
            req = CreatRequest(url);
            req.Method = "GET";
            req.AllowAutoRedirect = false;
            Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            res = (HttpWebResponse)req.GetResponse();
            Auth.Add(setCookie(res, "www.google.com"));

            return Auth;
        }


        private string getResponseText(HttpWebResponse res)
        {
            if (res.StatusCode != HttpStatusCode.OK)
                return null;
            Stream dataStream = res.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string str = reader.ReadToEnd();
            reader.Close();
            return str;
        }


        /// <summary>
        ///设置传送的数据
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="postData">The post data.</param>
        private void setPostData(HttpWebRequest req, string postData)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(postData);
            req.ContentLength = bytes.Length;

            using (Stream dataStream = req.GetRequestStream())
            {
                dataStream.Write(bytes, 0, bytes.Length);
                dataStream.Close();
            }

        }

        /// <summary>
        /// 根据response中头部的set-cookie对request中的cookie进行设置
        /// </summary>
        /// <param name="setCookie">The set cookie.</param>
        /// <param name="defaultDomain">The default domain.</param>
        /// <returns></returns>
        private CookieCollection setCookie(HttpWebResponse res, string defaultDomain)
        {
            string[] setCookie = res.Headers.GetValues("Set-Cookie");

            // there is bug in it,the datetime in "set-cookie" will be sepreated in two pieces.
            List<string> a = new List<string>(setCookie);
            for (int i = setCookie.Length - 1; i > 0; i--)
            {
                if (a[i].Substring(a[i].Length - 3) == "GMT")
                {
                    a[i - 1] = a[i - 1] + ", " + a[i];
                    a.RemoveAt(i);
                    i--;
                }
            }
            setCookie = a.ToArray<string>();
            CookieCollection cookies = new CookieCollection();
            foreach (string str in setCookie)
            {
                NameValueCollection hs = new NameValueCollection();
                foreach (string i in str.Split(';'))
                {
                    int index = i.IndexOf("=");
                    if (index > 0)
                        hs.Add(i.Substring(0, index), i.Substring(index + 1));
                    else
                        switch (i)
                        {
                            case "HttpOnly":
                                hs.Add("HttpOnly", "True");
                                break;
                            case "Secure":
                                hs.Add("Secure", "True");
                                break;
                        }
                }
                Cookie ck = new Cookie();
                foreach (string Key in hs.AllKeys)
                {
                    switch (Key)
                    {
                        case "Path":
                            ck.Path = hs[Key];
                            break;
                        case "Expires":
                            ck.Expires = DateTime.Parse(hs[Key]);
                            break;
                        case "Domain":
                            ck.Domain = hs[Key];
                            break;
                        case "HttpOnly":
                            ck.HttpOnly = true;
                            break;
                        case "Secure":
                            ck.Secure = true;
                            break;
                        default:
                            ck.Name = Key;
                            ck.Value = hs[Key];
                            break;
                    }
                }
                if (ck.Domain == "") ck.Domain = defaultDomain;
                if (ck.Name != "") cookies.Add(ck);
            }
            return cookies;
        }

        /// <summary>
        /// 对request进行基本的设置
        /// </summary>
        /// <param name="URL">The URL.</param>
        /// <returns></returns>
        private HttpWebRequest CreatRequest(string URL)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
            req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2";
            req.ServicePoint.Expect100Continue = false;
            req.ContentType = "application/x-www-form-urlencoded";

            return req;
        }

 整个过程很简单,但调试花了我很长时间,主要是在https下调试走了很多弯路,一 开始使用httpanalyzer,结果有bug显示的传送数据总是重复。后来还是使用fiddler才解决。但使用fiddler时在https下会出 现证书与网站 不符的错误。
解决办法是:
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

        public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
第 一个函数在设置httpwebquest时调用就不会出现错误了。这时就可以用fiddler捕获https包了。今天就写到这里。
这里有几点猜 想未证实,授权cookie中的writelySID及SID可能与google 的client的LSID和SID相同,但HSID不知从何而来。
cookie 可以反复使用,不用每次对话都要取得cookie。
代码写得很笨拙,大家不吝赐教。

 

转载:http://www.cnblogs.com/zcmky/archive/2010/04/02/1703397.html

分享到:
评论

相关推荐

    spire.doc API文档

    spire.doc API文档 spire.doc API文档spire.doc API文档

    Spire.Doc API 帮助文档

    Spire.Doc API 是一个强大的C#库,专为处理Microsoft Word文档设计,提供了全面的类、接口和属性集合,使得在.NET环境中创建、编辑、转换和操作Word文档变得轻而易举。这个API帮助文档详细地介绍了每个类的功能、...

    Google地图API教程.doc

    * 地图交互的重要性:地图交互是使用Google地图API的基本功能之一。 八、信息窗口 * 什么是信息窗口:信息窗口是一个浮动的信息框,用于显示地图上的信息。 * 信息窗口的用法:信息窗口可以用于显示地图上的信息,...

    spire.doc.free jar文件

    "Spire.Doc.Free.jar" 文件是一个与文档处理相关的Java库,主要用于在Java应用程序中创建、编辑和处理Microsoft Word文档。这个库提供了丰富的API,使得开发者能够方便地在Java环境中实现对DOC、DOCX格式文件的操作...

    doc2docx 文件类型转换 java后台

    在IT行业中,文件类型的转换是一项常见的任务,尤其是在文档处理领域。本项目专注于“doc2docx 文件类型转换”,使用Java后台技术实现。Eclipse作为流行的Java集成开发环境,被选为开发工具,使得开发者能够方便地...

    doc文件阅读器

    这个名为"doc文件阅读器"的工具专门用于查看doc文件,无需安装完整的Word应用程序,简化了用户对这种文件类型的访问流程。对于那些不经常处理doc文件或计算机配置较低的用户来说,这是一个非常实用的解决方案。 **...

    在页面用js调用后台方法,打开doc文件到浏览器

    在网页中实现通过JavaScript调用后台方法来打开.doc文件并在浏览器中查看,是Web开发中的一个常见需求。这种功能主要用于在线文档预览,方便用户无需下载文件就能直接在浏览器窗口内阅读内容。以下将详细解释这个...

    java 自己的doc文件生成 api说明文档工具2017

    而“java 自己的doc文件生成 api说明文档工具2017”可能是基于javadoc的一个定制化版本,旨在简化API文档的生成过程,并可能增加了特定的功能,比如转换为CHM(Compiled Help Manual)格式。 CHM是一种微软的帮助...

    模拟实现单级目录的FAT文件系统.doc

    - 使用二进制文件模拟磁盘空间。 - 使用文件块操作模拟磁盘块操作。 - 数据结构设计: - FAT表:用于跟踪每个簇的状态。 - 目录表:记录文件的基本属性(文件名、大小、创建日期等)。 - 文件控制块:用于管理...

    模拟电子技术:模拟电子3卷.doc

    模拟电子技术:模拟电子3卷.doc

    模拟电子技术:模拟电子4卷.doc

    模拟电子技术:模拟电子4卷.doc

    .doc文件内部结构解析 + 二进制流查看工具

    总结来说,理解.doc文件的内部结构是IT专业人员必备的技能之一。通过使用二进制流查看工具,我们可以揭示看似复杂无序的二进制数据背后的秩序,进一步增强对文档处理的掌控能力。对于那些对底层数据有兴趣或需求的...

    Free Spire.Doc for Java版本: 3.9.0

    "Free Spire.Doc for Java" 是一款用于Java平台的文档处理工具,主要专注于处理Microsoft Word文档,例如DOC、DOCX格式。版本3.9.0是该软件的一个特定发行版,可能包含了一些新功能、性能优化或错误修复。在这款库的...

    《操作系统》实验五:页面置换算法模拟.doc

    根据提供的文档信息,本次实验的主要目的是让学生理解和模拟操作系统中的页面置换算法,特别是最近最久未使用算法(LRU)。下面将详细介绍实验的目的、内容、要求以及实现方式。 ### 实验目的 1. **理解虚拟存储...

    java文件上传下载.doc

    2. **Servlet API**:在Java Web开发中,Servlet API提供了处理文件上传的方法。`HttpServletRequest`对象有`getParts()`方法,可以获取上传的文件Part对象。 3. **Commons FileUpload库**:Apache Commons ...

    易语言DOT文件转换为DOC文件

    标题提到的"易语言DOT文件转换为DOC文件"是指使用易语言编程实现的一种功能,即把DOT模板文件转换成DOC文档。这一过程涉及到对Microsoft Word文件格式的理解以及编程接口的使用。 首先,我们来了解一下DOT和DOC文件...

    Java多方式实现文件上传.doc

    在实际开发中,首先需要创建一个文件上传页面,例如`FileUpload.jsp`。在这个页面中,我们需要设置表单的提交方式为`POST`,并指定`enctype`属性为`multipart/form-data`,这是为了确保文件数据能被正确传输。接着,...

    Delphi提取docx,doc,xls,xlsx,ppt,ppts,pdf,eml,html,等文件内容文本

    支持文件类型: A: pdf文件 B: office word文件 ".doc", ".odt", ".docx", ".dotm", ".docm" C: wps文档 ".wps" D: office excel文件 ".xls", ".xlsx", ".xlsm", ".xltm" E: wps表格 ".et" F: office powerPoint文件...

    Java API 文档 jdk-17.0.2-doc-all

    11. **Stream API**:同样在Java 8中引入,Stream API提供了一种新的处理数据的方式,适用于大量数据的并行处理和聚合操作。 12. **日期和时间API**:Java 8改进了日期和时间处理,`java.time`包中的`LocalDate`、`...

    httpclient 4.5.3 API doc

    httpclient 4.5.3 API doc httpclient4.5.3.chm 纯网站镜像

Global site tag (gtag.js) - Google Analytics