root/lang/csharp/soyText/soyText/DocumentWebServer.cs @ 37215

Revision 37215, 11.0 kB (checked in by hoge1e3, 5 years ago)
RevLine 
[36503]1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Text.RegularExpressions;
6using System.Net;
[36589]7using System.Web;
[36968]8using System.Diagnostics;
[36503]9
10namespace SoyText
11{
[36968]12    public class DocumentWebServer
[36503]13    {
[36968]14        int port;
[36503]15        DocumentSet documentSet;
[36601]16        public static string detectContentType(Document d)
17        {
[36503]18            var c = d.str["Content-Type"];
[36601]19            if (c != null) return c;
20            var n = d.str["name"];
[36649]21            c = "text/plain; charset=utf-8";
22            if (n != null)
23            {
[36601]24                if (n.EndsWith(".js"))
25                {
26                    c = "text/javascript; charset=utf-8";
27                }
28                if (n.EndsWith(".html"))
29                {
30                    c = "text/html; charset=utf-8";
31                }
[36503]32            }
[36601]33            return c;
34        }
[37215]35        void feedDocumentBody(Document d,HttpListenerResponse res) {
[36601]36            res.ContentType = detectContentType(d);
[36968]37            var lastup = lastModifiedField(d);
38            res.Headers["Last-Modified"] = lastup;
39            Debug.syslog("last up :" + lastup);
[37215]40            if (d.str["file"] != null)
41            {
42                Httpd.respondByFile(res, d.str["file"]);
43            }
44            else
45            {
46                Httpd.respondByString(res, d.body);
47            }
[36503]48        }
[36968]49        string lastModifiedField(Document d)
50        {
51            return TimeFormat.toRFC2822(TimeFormat.toUtcTicks(d.lastUpdate, TimeZone.CurrentTimeZone));
52        }
[36589]53        void feedDocumentHead(Document d, HttpListenerResponse res)
54        {
55            var c = "text/plain; charset=utf-8";
56            res.ContentType = c;
[36968]57            res.Headers["Last-Modified"] = lastModifiedField(d);
[36589]58            Httpd.respondByString(res, d.head);
59        }
[36592]60        void feedDocumentHeadBody(Document d, HttpListenerResponse res)
61        {
62            var c = "text/plain; charset=utf-8";
63            res.ContentType = c;
[36968]64            res.Headers["Last-Modified"] = lastModifiedField(d);
[36592]65            Httpd.respondByString(res, d.content);
66        }
67
[36589]68        const string bodyAttr = "_body";
69        void procDocument(Document d, string query, HttpListenerRequest req, HttpListenerResponse res)
70        {
71            if (req.HttpMethod == "GET")
72            {
[36968]73                var lm = req.Headers["If-Modified-Since"];
74                if (lm != null)
75                {
76                    var oneSec = 10000000;
77                    //   10^-9 = 0.000000001(10億分の1)
78                    // 100nano = 10^-7 
79                    // 1sec/100nano sec = 1 sec / (10^-7) sec = 10^7
80                    var ifModifiedSince = TimeFormat.fromRFC2822(lm) + oneSec;
81                    var lastModified = TimeFormat.toUtcTicks(d.lastUpdate, TimeZone.CurrentTimeZone);
82                    var now = TimeFormat.utcnow();
83                    Debug.syslog(req.Url +
84                          "  lm: " + TimeFormat.toRFC2822(lastModified)+
85                          " ifm : " + TimeFormat.toRFC2822(ifModifiedSince) +
86                          "  now: " + TimeFormat.toRFC2822(now)
87                    );
88                    if (lastModified <= ifModifiedSince && ifModifiedSince<now )
89                    {
90                        res.StatusCode = 304;
91                        Debug.syslog(req.Url + " not modified");
92                        return;
93                    }
94                }
[36589]95                if (query == "meta")
96                {
97                    feedDocumentHead(d, res);
98                }
[36649]99                else if (query == "full")
100                {
101                    feedDocumentHeadBody(d, res);
102                }
[36589]103                else
104                {
[37215]105                    feedDocumentBody(d, res);
[36589]106                }
107            }
108            else if (req.HttpMethod == "POST")
109            {
[36859]110                /*var b = new byte[req.ContentLength64];
[36589]111                req.InputStream.Read(b, 0, b.Length);
112                char[] cs=System.Text.Encoding.UTF8.GetChars(b);
113                var str = new String(cs);
[36859]114                */
115                var str = getContentStr(req);
116
[36589]117                //str=HttpUtility.UrlDecode(str);
118                var keys=HttpUtility.ParseQueryString(str);
[37209]119                var debug = "";
[36589]120                foreach (var k in keys.AllKeys)
121                {
[37209]122                    debug+=(k + ": " + keys[k]+"\n");
[36589]123                    if (k == bodyAttr)
124                    {
125                        d.body = keys[k];
126                    }
127                    else
128                    {
129                        d.str[k] = keys[k];
130                    }
131
132                }
133                d.save();
[37209]134                Httpd.respondByString(res, "id: "+d.id+"\n"+debug);
[36589]135            }
136        }
[36859]137        static string getContentStr(HttpListenerRequest req)
138        {
139            var b = new byte[req.ContentLength64];
140            req.InputStream.Read(b, 0, b.Length);
141            char[] cs = System.Text.Encoding.UTF8.GetChars(b);
142            var str = new String(cs);
143            return str;
144        }
[36968]145        public void openInBrowser(Document d) {
146            if (d == null) return;
147            Process.Start("http://localhost:"+port+"/byid/" + d.id);
148        }
149        public DocumentWebServer(DocumentSet documentSet,int port)
[36503]150        {
[36968]151            this.port = port;
[36503]152            this.documentSet = documentSet;
[36968]153            new Httpd(port, (req, res) =>
[36503]154            {
155                var u = req.Url;
156                var str = u.PathAndQuery;
[36589]157                str = HttpUtility.UrlDecode(str,Encoding.UTF8);
158                var pathQuery = Regex.Split(str,@"\?");
159                str = pathQuery[0];
160                var query = "";
161                if (pathQuery.Length > 1)
162                {
163                    query = pathQuery[1];
164                }
165                Debug.syslog("Query = " + str+ "?" +query);
[36503]166                //var m=Regex.Match(str,@"byId/");
167                Debug.syslog(str);
168                var s=Regex.Split(str, @"/");
[36649]169                if (req.RemoteEndPoint.Address.ToString()!="127.0.0.1" &&
170                    req.RemoteEndPoint.Address.ToString()!="::1")
[36512]171                {
172                    res.StatusCode = 403;
173                    Httpd.respondByString(res, "isLocal "+req.IsLocal+" / "+req.RemoteEndPoint.Address);
174                    return;
175                }
[36589]176                if (s.Length>=2 && s[1].ToLower()=="byid" )
[36503]177                {
178                    var id = s[2];
179                    Debug.print("ID=" + id);
180                    Document d = documentSet.byId(id);
181                    if (d != null)
182                    {
[36589]183                        procDocument(d, query, req, res);           
[36503]184                    }
185                    else
186                    {
187                        res.StatusCode = 404;
188                        Httpd.respondByString(res,id+" Not found");
189                    }
190                }
[36592]191                else if (s.Length >= 3 && s[1].ToLower() == "asyncsearch")
192                {
193                    var se = documentSet.createLoggedDocumentSearcher(s[2]);
194                    se.timeOut = 10000000;
195                    foreach (var dd in se.search()){}
196                    var d=se.searchLog;
197                    feedDocumentHeadBody(d,  res);
[36589]198                }
[36592]199                else if (req.HttpMethod == "POST" && s.Length >= 2 && s[1].ToLower() == "new")
200                {
201                    var d = documentSet.createDocument();
202                    procDocument(d, query, req, res);
203                }
[36859]204                else if (req.HttpMethod == "POST" && s.Length >= 2 && s[1].ToLower() == "getcontents")
205                {
206                    getContents(query, req, res);
207                }
[36503]208                else
209                {
[36512]210                    //var c = new AndCondition();
211                    var cstr = "";
[36503]212                    for (var i = 1; i < s.Length - 1; i++)
213                    {
[36592]214                        if (i > 1) cstr += " ";
[36512]215                        cstr += "tag:" + s[i];
216                        // c.add(new AttributeCondition("tag",s[i]));
[36503]217                    }
[36592]218                    var name = s[s.Length - 1];
[36512]219                    if (name == "")
220                    {
221                        search(cstr, res);
[36503]222                    }
[36512]223                    else
224                    {
225                        var nc = new AttributeCondition("name", name);
226                        //c.add();
227                        //var src=documentSet.createDocumentSearcher(c);
228                        Document found = null;
229                        foreach (var d in documentSet.search(cstr, true))
230                        {
231                            if (nc.matches(d))
232                            {
233                                found = d;
234                                break;
235                            }
236                        }
237                        if (found != null)
238                        {
[36589]239                            procDocument(found, query, req, res);
[36512]240                        }
241                        else
242                        {
243                            res.StatusCode = 404;
244                            Httpd.respondByString(res, "Not found : " + str);
245                        }
[36503]246                    }
247                }
248            });
249        }
[36512]250
[36859]251        private void getContents(string query, HttpListenerRequest req, HttpListenerResponse res)
252        {
[36935]253            var str = getContentStr(req);
254            var keys = HttpUtility.ParseQueryString(str);
255            var ids = keys["ids"];
256            //content=HttpUtility.UrlDecode(content);
[36859]257            var r=new Random();
258            var sep = "---" + r.Next(1000000) + "----" + r.Next(1000000)+"\n";
259            var buf = "";
[36935]260            foreach (var line in Str.lines(ids)) {
261                Debug.syslog("getContents " + line);
[36859]262                var d=documentSet.byId(line);
263                if (d==null) continue;
264                buf += sep;
[36935]265                if (d.str["id"]!=d.id)
266                {
267                    buf += "id :" + d.id + "\n";
268                }
[36859]269                buf += "lastUpdate :" + TimeFormat.format(d.lastUpdate) + "\n";
[36935]270                //buf += "\n";
[36859]271                buf += d.content;
272                buf += "\n";
273            }
274            buf += sep;
[36935]275            Debug.syslog("getContents respond");
276               
[36859]277            Httpd.respondByString(res, buf);
[36935]278            Debug.syslog("getContents done");
[36859]279        }
280
[36512]281        private void search(string cstr, HttpListenerResponse res)
282        {
283            var buf = "";
284            foreach (var d in documentSet.search(cstr, true))
285            {
286                buf += "<a href=\"/byid/" + d.id + "\">" + d.ToString() + "</a><br/>\n";
287
288            }
289            res.ContentType = "text/html; charset=utf-8";
290            Httpd.respondByString(res, buf);
291        }
[36503]292    }
293}
Note: See TracBrowser for help on using the browser.