Esempio n. 1
0
        public Method FindMethodByName(string name)
        {
            //
            // First make a quick, case-sensitive look-up.
            //

            int i = InvariantStringArray.BinarySearch(_methodNames, name);

            if (i >= 0)
            {
                return(_sortedMethods[i]);
            }

            //
            // Failing, use a slower case-insensitive look-up.
            // TODO: Consider speeding up FindMethodByName for case-insensitive look-ups.
            //

            foreach (Method method in _methods)
            {
                if (CaselessString.Equals(method.Name, name))
                {
                    return(method);
                }
            }

            return(null);
        }
Esempio n. 2
0
        protected virtual object InferFeature()
        {
            HttpRequest request = Context.Request;
            string      verb    = request.RequestType;

            if (CaselessString.Equals(verb, "GET") ||
                CaselessString.Equals(verb, "HEAD"))
            {
                //
                // If there is path tail then it indicates a GET-safe RPC.
                //

                if (request.PathInfo.Length > 1)
                {
                    return(GetFeatureByName("getrpc"));
                }

                //
                // Otherwise, get the feature name from anonymous query
                // string parameter.
                //

                return(GetFeatureByName(Mask.EmptyString(request.QueryString[null], "help")));
            }
            else if (CaselessString.Equals(verb, "POST"))
            {
                //
                // POST means RPC.
                //

                return(GetFeatureByName("rpc"));
            }

            return(null);
        }
Esempio n. 3
0
        protected override void ProcessRequest()
        {
            if (!CaselessString.Equals(Request.RequestType, "POST"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP POST only.", Request.RequestType));
            }

            //
            // Sets the "Cache-Control" header value to "no-cache".
            // NOTE: It does not send the common HTTP 1.0 request directive
            // "Pragma" with the value "no-cache".
            //

            Response.Cache.SetCacheability(HttpCacheability.NoCache);

            //
            // Response will be plain text, though it would have been nice to
            // be more specific, like text/json.
            //

            Response.ContentType = "application/json";

            //
            // Delegate rest of the work to JsonRpcServer.
            //

            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(Service);

            using (new JsonRpcDispatchScope(dispatcher, Context))
                using (TextReader reader = GetRequestReader())
                    dispatcher.Process(reader, Response.Output);
        }
Esempio n. 4
0
        private static object ReadParameters(Method method, JsonReader reader, JsonImportHandler importer)
        {
            Debug.Assert(method != null);
            Debug.Assert(reader != null);
            Debug.Assert(importer != null);

            reader.MoveToContent();

            Parameter[] parameters = method.GetParameters();

            if (reader.TokenClass == JsonTokenClass.Array)
            {
                reader.Read();
                ArrayList argList = new ArrayList(parameters.Length);

                for (int i = 0; i < parameters.Length && reader.TokenClass != JsonTokenClass.EndArray; i++)
                {
                    argList.Add(importer(parameters[i].ParameterType, reader));
                }

                reader.StepOut();
                return(argList.ToArray());
            }
            else if (reader.TokenClass == JsonTokenClass.Object)
            {
                reader.Read();
                JsonObject argByName = new JsonObject();

                while (reader.TokenClass != JsonTokenClass.EndObject)
                {
                    // TODO: Imporve this lookup.
                    // FIXME: Does not work when argument is positional.

                    Type   parameterType = AnyType.Value;
                    string name          = reader.ReadMember();

                    foreach (Parameter parameter in parameters)
                    {
                        if (CaselessString.Equals(parameter.Name, name))
                        {
                            parameterType = parameter.ParameterType;
                            break;
                        }
                    }

                    argByName.Put(name, importer(parameterType, reader));
                }

                reader.Read();
                return(argByName);
            }
            else
            {
                return(importer(AnyType.Value, reader));
            }
        }
Esempio n. 5
0
        private TextReader GetRequestReader()
        {
            string contentType = Request.ContentType.Split(';')[0];

            if (CaselessString.Equals(contentType, "application/x-www-form-urlencoded"))
            {
                string request = Request.Form.Count == 1 ? Request.Form[0] : Request.Form["JSON-RPC"];
                return(new StringReader(request));
            }
            else
            {
                return(new StreamReader(Request.InputStream, Request.ContentEncoding));
            }
        }
Esempio n. 6
0
        protected override void ProcessRequest()
        {
            string httpMethod = Request.RequestType;

            if (!CaselessString.Equals(httpMethod, "GET") &&
                !CaselessString.Equals(httpMethod, "HEAD"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP GET or HEAD only.", httpMethod));
            }

            string callback = Mask.NullString(Request.QueryString["jsonp"]);
            bool   padded   = callback.Length > 0;

            //
            // The response type depends on whether JSONP (JSON with
            // Padding) is in effect or not.
            //

            Response.ContentType = padded ? "text/javascript" : "application/json";

            //
            // Validate that the JSONP callback method conforms to the
            // allowed syntax. If not, issue a client-side exception
            // that will certainly help to bring problem to light, even if
            // a little too aggressively.
            //

            if (padded)
            {
                if (!_jsonpex.IsMatch(callback))
                {
                    Response.Write("throw new Error('Invalid JSONP callback parameter value.');");
                    Response.End();
                }
            }

            //
            // Convert the query string into a call object.
            //

            StringWriter sw     = new StringWriter();
            JsonWriter   writer = JsonText.CreateWriter(sw);

            writer.WriteStartObject();

            writer.WriteMember("id");
            writer.WriteNumber(-1);

            writer.WriteMember("method");

            string methodName = Mask.NullString(Request.PathInfo);

            if (methodName.Length == 0)
            {
                writer.WriteNull();
            }
            else
            {
                //
                // If the method name contains periods then we replace it
                // with dashes to mean the one and same thing. This is
                // done to provide dashes as an alternative to some periods
                // since some web servers may block requests (for security
                // reasons) if a path component of the URL contains more
                // than one period.
                //

                writer.WriteString(methodName.Substring(1).Replace('-', '.'));
            }

            writer.WriteMember("params");
            NameValueCollection query = new NameValueCollection(Request.QueryString);

            query.Remove(string.Empty);
            JsonConvert.Export(Request.QueryString, writer);

            writer.WriteEndObject();

            //
            // Delegate rest of the work to JsonRpcDispatcher.
            //

            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(Service);

            using (new JsonRpcDispatchScope(dispatcher, Context))
            {
                dispatcher.RequireIdempotency = true;

                if (padded)
                {
                    //
                    // For JSONP, see details here:
                    // http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
                    //

                    Response.Write(callback);
                    Response.Write('(');
                }

                dispatcher.Process(new StringReader(sw.ToString()), Response.Output, true);

                if (padded)
                {
                    Response.Write(')');
                }
            }
        }