Exemple #1
0
        private void Main2(ArgsReader ar)
        {
            if (ar.ArgIs("/BEFORE-DL"))
            {
                BeforeDLIntervent.Perform();
                return;
            }
            if (ar.ArgIs("/DISK-YELLOW"))
            {
#if true
                throw new Exception("廃止");
#else // del @ 2020.4.1
                foreach (IService service in new ServiceDistributor().GetAllService())
                {
                    service.DiskYellow();
                }
                return;
#endif
            }
            if (ar.HasArgs())
            {
                throw new Exception("不明なコマンド引数");
            }

            JsonTools.DecodeStringFilter    = v => JString.ToJString(v, true, true, true, true);
            JsonTools.DecodeNestingLevelMax = 30;
            JsonTools.DecodeObjectCountMax  = 1000;

            HTTPRequest.I = new HTTPRequest();

            HTTPRequest.I.IP           = File.ReadAllLines("IP.httdat", Encoding.ASCII)[0];            // 正規化済み @ Post2
            HTTPRequest.I.Method       = File.ReadAllLines("Method.htt2dat", Encoding.ASCII)[0];       // 正規化済み @ Post2
            HTTPRequest.I.URLPath      = File.ReadAllLines("Path.htt2dat", Encoding.ASCII)[0];         // 正規化済み @ Post2
            HTTPRequest.I.HTTP_Version = File.ReadAllLines("HTTP_Version.htt2dat", Encoding.ASCII)[0]; // 正規化済み @ Post2

            ProcMain.WriteLog("IP: " + HTTPRequest.I.IP);
            ProcMain.WriteLog("Method: " + HTTPRequest.I.Method);
            ProcMain.WriteLog("URLPath: " + HTTPRequest.I.URLPath);
            ProcMain.WriteLog("HTTP_Version: " + HTTPRequest.I.HTTP_Version);

            ParsePathQuery();

            {
                string[] keys   = File.ReadAllLines("HeaderKeys.htt2dat", Encoding.ASCII);               // 正規化済み @ Post2
                string[] values = File.ReadAllLines("HeaderValues.htt2dat", Encoding.ASCII);             // 正規化済み @ Post2

                if (keys.Length != values.Length)
                {
                    throw null;                     // 想定外
                }
                for (int index = 0; index < keys.Length; index++)
                {
                    string key   = keys[index];
                    string value = values[index];

                    ProcMain.WriteLog("Header: " + key + " ⇒ " + value);

                    HTTPRequest.I.HeaderPairs.Add(key, value);
                }
            }

            {
                byte[] body = File.ReadAllBytes("Body.htt2dat");

                string   serviceName = HTTPRequest.I.Query["sn"];
                IService service     = new ServiceDistributor().GetService(serviceName);

                object prm  = JsonTools.Decode(body);
                string sPrm = JsonTools.Encode(prm);

                if (600 < sPrm.Length)
                {
                    sPrm = sPrm.Substring(0, 500) + "...(省略)";                     // 長すぎると表示に時間が掛かるので、
                }
                ProcMain.WriteLog("prm: " + sPrm);

                try
                {
                    object ret = service.Perform(prm);

                    string sRet = JsonTools.Encode(ObjectTree.Conv(ret));
                    ProcMain.WriteLog("ret: " + sRet);
                    byte[] resBody = Encoding.UTF8.GetBytes(sRet);

                    File.WriteAllBytes("ResBody.htt2dat", resBody);

                    File.WriteAllLines("ResHeader.htt2dat", new string[]
                    {
                        "Content-Type: application/json",
                    });
                }
                catch (Exception e)
                {
                    ProcMain.WriteLog(e);

                    File.WriteAllText("ResHeaderFirstLine.htt2dat", "HTTP/1.1 400 Or 500\r\n", Encoding.ASCII);
                }
            }
        }
Exemple #2
0
		public void Main(ArgsReader ar)
		{
			int portNo = 80;
			DocRoot docRoot = new DocRoot();
			MIMEType mimeType = new MIMEType();

			if (ar.HasArgs())
				portNo = int.Parse(ar.NextArg());

			portNo = IntTools.ToRange(portNo, 1, 65535);

			while (ar.HasArgs())
				docRoot.AddRootDir(ar.NextArg());

			HTTPServerChannel.RequestTimeoutMillis = 30000; // 30 sec
			HTTPServerChannel.ResponseTimeoutMillis = 2 * 86400000; // 2 day
			//HTTPServerChannel.FirstLineTimeoutMillis = 2000; // 2 sec == def
			HTTPServerChannel.IdleTimeoutMillis = 10000; // 10 sec
			HTTPServerChannel.BodySizeMax = 2000000; // 2 MB
			HTTPServerChannel.BuffSize = 500000; // 500 KB

			JsonTools.DecodeStringFilter = v => JString.ToJString(v, true, true, true, true);
			JsonTools.DecodeNestingLevelMax = 30;
			JsonTools.DecodeObjectCountMax = 1000;

			HTTPServer hs = new HTTPServer()
			{
				PortNo = portNo,
				//Backlog = 100, // == def
				//ConnectMax = 30, // == def

				Interlude = () =>
				{
					return Console.KeyAvailable == false;
				},

				HTTPConnected = channel =>
				{
					string method = channel.Method;
					string path = channel.Path;

					HTTPRequest hr = new HTTPRequest();

					hr.IP = channel.Channel.Handler.RemoteEndPoint.ToString(); // TODO
					hr.Method = JString.ToJString(channel.Method, false, false, false, false); // 正規化
					hr.URLPath = JString.ToJString(channel.Path, true, false, false, true); // 正規化

					// HACK ??? ParsePathQuery より前に DecodeURL しているのでクエリに '?', '&', '=' を使えない???

					ParsePathQuery(hr);

					// 特別な処理:アスタリスクの直前までをパスと見なす。
					{
						int i = hr.Path.IndexOf('*');

						if (i != -1)
							hr.Path = hr.Path.Substring(0, i);
					}

					if (hr.Path[hr.Path.Length - 1] == '/')
						hr.Path += "index.html";

					hr.Path = CommonUtils.GetFairRelPath(hr.Path);
					hr.HTTP_Version = JString.ToJString(channel.HTTPVersion, false, false, false, false); // 正規化

					foreach (string[] headerPair in channel.HeaderPairs)
					{
						hr.HeaderPairs.Add(
							JString.ToJString(headerPair[0], true, false, false, true), // 正規化
							JString.ToJString(headerPair[1], true, false, false, true)  // 正規化
							);
					}

					if (hr.Method == "GET")
					{
						hr.Json = null;
					}
					else if (method == "POST")
					{
						hr.Json = JsonTools.Decode(channel.Body); // 正規化
					}
					else
					{
						throw new Exception("不明なメソッド");
					}

					// HACK ??? フォルダの場合の 301 対応

					string targetFile = docRoot.GetRootDirs().Select(v => Path.Combine(v, hr.Path)).FirstOrDefault(v => File.Exists(v));

					if (targetFile == null)
					{
						channel.ResStatus = 404;
					}
					else
					{
						if (StringTools.EndsWithIgnoreCase(targetFile, ".alt.txt"))
						{
							string intervateClassName = File.ReadAllLines(targetFile, Encoding.ASCII)[0];
							Type intervateClass = Type.GetType(intervateClassName + "," + Assembly.GetEntryAssembly().GetName().Name);
							ReflectTools.MethodUnit intervateCtor = ReflectTools.GetConstructor(intervateClass);
							IService service = (IService)intervateCtor.Construct(new object[0]);

							object ret = service.Perform(hr, ref targetFile);

							if (ret != null)
							{
								string sRet = JsonTools.Encode(ObjectTree.Conv(ret));
								byte[] resBody = Encoding.UTF8.GetBytes(sRet);

								channel.ResStatus = 200;
								channel.ResBody_B = resBody;
								channel.ResContentType = "application/json";

								goto endSetResponse;
							}
						}
						channel.ResStatus = 200;

						if (new FileInfo(targetFile).Length <= 2000000)
							channel.ResBody_B = File.ReadAllBytes(targetFile);
						else
							channel.ResBody = ResponseFileReader(targetFile);

						channel.ResContentType = mimeType.FileToContentType(targetFile);

					endSetResponse:
						;
					}
				},
			};

			ProcMain.WriteLog("Server Started");

			hs.Perform();

			ProcMain.WriteLog("Server Ended");
		}