Ejemplo n.º 1
0
        // 处理一次请求
        private void _request_once(HttpListenerContext ctx)
        {
            HttpListenerRequest  req = ctx.Request;
            HttpListenerResponse res = ctx.Response;

            FawRequest _req = new FawRequest()
            {
                _check_int = m_check_int, _check_long = m_check_long, _check_string = m_check_string
            };

            _req.m_url    = req.RawUrl;         // 此处缺失schema://domain:host
            _req.m_method = req.HttpMethod.ToUpper();

            // 获取请求命令
            _req.m_path = req.RawUrl.simplify_path();
            int _p = _req.m_path.IndexOfAny(new char [] { '?', '#' });

            if (_p > 0)
            {
                _req.m_path = _req.m_path.Substring(0, _p);
            }

            // 获取请求内容
            foreach (string str_key in req.QueryString.AllKeys)
            {
                _req.m_gets.Add(str_key, req.QueryString [str_key]);
            }
            if (_req.m_method == "POST")
            {
                (_req.m_posts, _req.m_files) = parse_form(req);
            }

            // 获取请求者IP
            if ((req.Headers ["X-Real-IP"]?.Length ?? 0) > 0)
            {
                _req.m_ip       = req.Headers ["X-Real-IP"];
                _req.m_agent_ip = req.UserHostAddress;
            }
            else
            {
                _req.m_ip = req.UserHostAddress;
            }

            FawResponse _res = new FawResponse();

            try {
                // 生成请求内容
                res.StatusCode = 200;
                byte [] result_data = new byte [0];
                if (_req.m_method != "HEAD")
                {
                    try {
                        if (_req.m_path.left_is("/api/"))
                        {
                            bool _proc = false;
                            if (m_request_handlers.ContainsKey($"{_req.m_method} {_req.m_path}"))
                            {
                                m_request_handlers [$"{_req.m_method} {_req.m_path}"].process(_req, _res);
                                _proc = true;
                            }
                            else if (m_request_handlers.ContainsKey($" {_req.m_path}"))
                            {
                                m_request_handlers [$" {_req.m_path}"].process(_req, _res);
                                _proc = true;
                            }
                            if (!_proc)
                            {
                                throw new Exception("Unknown request / 未知请求");
                            }
                        }
                        else if (_req.m_path.left_is("/swagger/") && m_doc_info != null)
                        {
                            if (_req.m_path == "/swagger/api.json")
                            {
                                _res.write(m_swagger_data);
                                _res.set_content_from_filename(_req.m_path);
                            }
                            else
                            {
                                var _asm_path = $"{MethodBase.GetCurrentMethod ().DeclaringType.Namespace}.Swagger.res.{_req.m_path.mid ("/swagger/")}";
                                using (var _stream = Assembly.GetCallingAssembly().GetManifestResourceStream(_asm_path)) {
                                    if (_stream == null)
                                    {
                                        throw new Exception("File Not Found");
                                    }
                                    var _buffer = new byte [_stream.Length];
                                    _stream.Read(_buffer);
                                    _res.write(_buffer);
                                    _res.set_content_from_filename(_asm_path);
                                }
                            }
                        }
                        else if (_req.m_path.left_is("/monitor/") && m_monitor != null)
                        {
                            if (_req.m_path == "/monitor/data.json")
                            {
                                _res.write(m_monitor.get_json().Result);
                                _res.set_content_from_filename(_req.m_path);
                            }
                        }
                        else if (_req.m_method == "GET")
                        {
                            bool _is_404 = (_req.m_path == "/404.html");
                            if (_is_404)
                            {
                                _res.m_status_code = 404;
                            }
                            else if (_req.m_path == "/")
                            {
                                if (File.Exists($"{m_wwwroot}index.html"))
                                {
                                    _req.m_path = "/index.html";
                                }
                                else if (File.Exists($"{m_wwwroot}index.htm"))
                                {
                                    _req.m_path = "/index.htm";
                                }
                            }
                            _req.m_path = $"{m_wwwroot}{_req.m_path.Substring (1)}";
                            if (File.Exists(_req.m_path))
                            {
                                _res.write_file(_req.m_path);
                            }
                            else if (_is_404)
                            {
                                _res.write("404 Not Found");
                            }
                            else
                            {
                                _res.redirect("404.html");
                            }
                        }
                        result_data    = _res._get_writes();
                        res.StatusCode = _res.m_status_code;
                    } catch (KeyNotFoundException ex) {
                        result_data    = get_failure_res($"not given parameter {ex.Message.mid ("The given key '", "'")}");
                        res.StatusCode = 500;
                    } catch (Exception ex) {
                        result_data    = get_failure_res(ex.GetType().Name == "Exception" ? ex.Message : ex.ToString());
                        res.StatusCode = 500;
                    }
                }

                // 生成请求头
                foreach (var(_key, _value) in _res.m_headers)
                {
                    res.AppendHeader(_key, _value);
                }
                Action <string, string> _unique_add_header = (_key, _value) => {
                    if (!_res.m_headers.ContainsKey(_key))
                    {
                        res.AppendHeader(_key, _value);
                    }
                };

                // HTTP头输入可以自定
                _unique_add_header("Cache-Control", (_req.m_method == "GET" ? "private" : "no-store"));
                _unique_add_header("Content-Type", "text/plain; charset=utf-8");
                _unique_add_header("Server", "Microsoft-IIS/7.5");                  // nginx/1.9.12
                _unique_add_header("X-Powered-By", "ASP.NET");
                _unique_add_header("X-AspNet-Version", "4.0.30319");
                _unique_add_header("Access-Control-Allow-Origin", "*");
                _unique_add_header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,Accept");
                _unique_add_header("Access-Control-Allow-Methods", "HEAD,GET,POST,PUT,DELETE,OPTIONS");
                //_unique_add_header ("Content-Length", "");

                // 添加cookie
                //res.SetCookie (new Cookie ());

                // 是否启用压缩
                string [] encodings = req.Headers ["Accept-Encoding"]?.Split(',') ?? new string [0];
                encodings = (from p in encodings select p.Trim().ToLower()).ToArray();
                if (Array.IndexOf(encodings, "gzip") >= 0)
                {
                    // 使用 gzip 压缩
                    _unique_add_header("Content-Encoding", "gzip");
                    _unique_add_header("Vary", "Accept-Encoding");
                    result_data = result_data.gzip_compress();
                }
                else if (Array.IndexOf(encodings, "deflate") >= 0)
                {
                    // 使用 deflate 压缩
                    _unique_add_header("Content-Encoding", "deflate");
                    _unique_add_header("Vary", "Accept-Encoding");
                    result_data = result_data.deflate_compress();
                }
                res.OutputStream.Write(result_data, 0, result_data.Length);
            } catch (Exception ex) {
                Log.show_error(ex);
            } finally {
                res.Close();
            }
        }
Ejemplo n.º 2
0
        public void process(FawRequest _req, FawResponse _res)
        {
            var  _params        = new object [m_params.Count];
            bool _ignore_return = false;

            for (int i = 0; i < m_params.Count; ++i)
            {
                if (m_params [i].Item1 != null)
                {
                    _params [i] = _req.get_type_value(m_params [i].Item1, m_params [i].Item2);
                }
                else
                {
                    switch (m_params [i].Item2)
                    {
                    case "FawRequest":
                        _params [i] = _req;
                        break;

                    case "FawResponse":
                        _params [i]    = _res;
                        _ignore_return = true;
                        break;

                    case ":IP":
                        _params [i] = _req.m_ip;
                        break;

                    case ":AgentIP":
                        _params [i] = _req.m_agent_ip;
                        break;

                    default:
                        throw new Exception("Request parameter types that are not currently supported / 暂不支持的Request参数类型");
                    }
                }
            }
            try {
                var _ret = m_method.Invoke(null, _params);
                //if (_ret.GetType () == typeof (Task<>)) // 始终为False
                if (_ret is Task _t)
                {
                    if (_ret.GetType() != typeof(Task))
                    {
                        _ret = _ret.GetType().InvokeMember("Result", BindingFlags.GetProperty, null, _ret, null);
                    }
                    else
                    {
                        _t.Wait();
                        _ret = null;
                    }
                }
                if (!_ignore_return)
                {
                    if (_ret is byte _byte)
                    {
                        _res.write(_byte);
                    }
                    else if (_ret is byte [] _bytes)
                    {
                        _res.write(_bytes);
                    }
                    else
                    {
                        string _content = (_ret.GetType().IsPrimitive ? _ret.to_str() : _ret.to_json());
                        object _o;
                        if (_content == "")
                        {
                            _o = new { result = "success" };
                        }
                        else if (_content[0] != '[' && _content[0] != '{')
                        {
                            _o = new { result = "success", content = _content };
                        }
                        else
                        {
                            _o = new { result = "success", content = JToken.Parse(_content) };
                        }
                        _res.write(_o.to_json());
                    }
                }
            } catch (TargetInvocationException ex) {
                throw ex.InnerException;
            }
        }