static void AssertQueryString(string expected, string actual)
        {
            var ed = new QueryStringDecoder(expected);
            var ad = new QueryStringDecoder(actual);

            Assert.Equal(ed.Path, ad.Path);

            IDictionary <string, List <string> > edParams = ed.Parameters;
            IDictionary <string, List <string> > adParams = ad.Parameters;

            Assert.Equal(edParams.Count, adParams.Count);

            foreach (string name in edParams.Keys)
            {
                List <string> expectedValues = edParams[name];

                Assert.True(adParams.ContainsKey(name));
                List <string> values = adParams[name];
                Assert.Equal(expectedValues.Count, values.Count);

                foreach (string value in expectedValues)
                {
                    Assert.Contains(value, values);
                }
            }
        }
        public void UriSlashPath()
        {
            var uri = new Uri("http://localhost:8080/?param1=value1&param2=value2&param3=value3");
            var d   = new QueryStringDecoder(uri);

            Assert.Equal("/", d.Path);
            IDictionary <string, List <string> > parameters = d.Parameters;

            Assert.Equal(3, parameters.Count);

            KeyValuePair <string, List <string> > entry = parameters.ElementAt(0);

            Assert.Equal("param1", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value1", entry.Value[0]);

            entry = parameters.ElementAt(1);
            Assert.Equal("param2", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value2", entry.Value[0]);

            entry = parameters.ElementAt(2);
            Assert.Equal("param3", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value3", entry.Value[0]);
        }
예제 #3
0
 internal ParameterParser(QueryStringDecoder decoder, Configuration conf)
 {
     this.path = DecodeComponent(Sharpen.Runtime.Substring(decoder.Path(), WebHdfsHandler
                                                           .WebhdfsPrefixLength), Charsets.Utf8);
     this.@params = decoder.Parameters();
     this.conf    = conf;
 }
예제 #4
0
 protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg)
 {
     StringBuilder stringBuilder = new StringBuilder("请求参数:\r\n");
     {
         if (msg.Method == HttpMethod.Get)
         {
             var fer = new QueryStringDecoder(msg.Uri);
             foreach (var item in fer.Parameters)
             {
                 stringBuilder.AppendFormat("{0}:{1}\r\n", item.Key, item.Value[0]);
             }
         }
         if (msg.Method == HttpMethod.Post)
         {
             var postRequestDecoder = new HttpPostRequestDecoder(msg).Offer(msg);
             foreach (var item in postRequestDecoder.GetBodyHttpDatas())
             {
                 var mixedAttribute = postRequestDecoder.Next() as MixedAttribute;
                 stringBuilder.AppendFormat("{0}:{1}\r\n", mixedAttribute?.Name, mixedAttribute?.Value);
                 mixedAttribute.Release();
             }
         }
         byte[] text = Encoding.UTF8.GetBytes(stringBuilder.ToString());
         WriteResponse(ctx, Unpooled.WrappedBuffer(text), AsciiString.Cached("text/plain"), AsciiString.Cached(text.Length.ToString()));
     }
 }
예제 #5
0
        private static string GetOp(QueryStringDecoder decoder)
        {
            IDictionary <string, IList <string> > parameters = decoder.Parameters();

            return(parameters.Contains("op") ? StringUtils.ToUpperCase(parameters["op"][0]) :
                   null);
        }
        public void UriNoPath()
        {
            var uri = new Uri("http://localhost:8080?param1=value1&param2=value2&param3=value3");
            var d   = new QueryStringDecoder(uri);

            // The path component cannot be empty string,
            // if there are no path component, it shoudl be '/' as above UriSlashPath test
            Assert.Equal("/", d.Path);
            IDictionary <string, List <string> > parameters = d.Parameters;

            Assert.Equal(3, parameters.Count);

            KeyValuePair <string, List <string> > entry = parameters.ElementAt(0);

            Assert.Equal("param1", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value1", entry.Value[0]);

            entry = parameters.ElementAt(1);
            Assert.Equal("param2", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value2", entry.Value[0]);

            entry = parameters.ElementAt(2);
            Assert.Equal("param3", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("value3", entry.Value[0]);
        }
예제 #7
0
        public virtual void TestDecodePath()
        {
            string             EscapedPath  = "/test%25+1%26%3Dtest?op=OPEN&foo=bar";
            string             ExpectedPath = "/test%+1&=test";
            Configuration      conf         = new Configuration();
            QueryStringDecoder decoder      = new QueryStringDecoder(WebHdfsHandler.WebhdfsPrefix
                                                                     + EscapedPath);
            ParameterParser testParser = new ParameterParser(decoder, conf);

            NUnit.Framework.Assert.AreEqual(ExpectedPath, testParser.Path());
        }
예제 #8
0
        /// <exception cref="System.Exception"/>
        protected override void ChannelRead0(ChannelHandlerContext ctx, HttpRequest request
                                             )
        {
            if (request.GetMethod() != HttpMethod.Get)
            {
                DefaultHttpResponse resp = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus
                                                                   .MethodNotAllowed);
                resp.Headers().Set(HttpHeaders.Names.Connection, HttpHeaders.Values.Close);
                ctx.Write(resp).AddListener(ChannelFutureListener.Close);
                return;
            }
            QueryStringDecoder decoder = new QueryStringDecoder(request.GetUri());
            string             op      = GetOp(decoder);
            string             content;
            string             path = GetPath(decoder);

            switch (op)
            {
            case "GETFILESTATUS":
            {
                content = image.GetFileStatus(path);
                break;
            }

            case "LISTSTATUS":
            {
                content = image.ListStatus(path);
                break;
            }

            case "GETACLSTATUS":
            {
                content = image.GetAclStatus(path);
                break;
            }

            default:
            {
                throw new ArgumentException("Invalid value for webhdfs parameter" + " \"op\"");
            }
            }
            Log.Info("op=" + op + " target=" + path);
            DefaultFullHttpResponse resp_1 = new DefaultFullHttpResponse(HttpVersion.Http11,
                                                                         HttpResponseStatus.Ok, Unpooled.WrappedBuffer(Sharpen.Runtime.GetBytesForString(
                                                                                                                           content, Charsets.Utf8)));

            resp_1.Headers().Set(HttpHeaders.Names.ContentType, WebHdfsHandler.ApplicationJsonUtf8
                                 );
            resp_1.Headers().Set(HttpHeaders.Names.ContentLength, resp_1.Content().ReadableBytes
                                     ());
            resp_1.Headers().Set(HttpHeaders.Names.Connection, HttpHeaders.Values.Close);
            ctx.Write(resp_1).AddListener(ChannelFutureListener.Close);
        }
예제 #9
0
        public static string FirstValue(QueryStringDecoder query, string key)
        {
            if (null == query)
            {
                return(null);
            }

            if (!query.Parameters.TryGetValue(key, out var values))
            {
                return(null);
            }
            return(values[0]);
        }
예제 #10
0
        /// <exception cref="System.Exception"/>
        protected override void ChannelRead0(ChannelHandlerContext ctx, HttpRequest req)
        {
            Preconditions.CheckArgument(req.GetUri().StartsWith(WebhdfsPrefix));
            QueryStringDecoder queryString = new QueryStringDecoder(req.GetUri());

            @params = new ParameterParser(queryString, conf);
            DataNodeUGIProvider ugiProvider = new DataNodeUGIProvider(@params);

            ugi  = ugiProvider.Ugi();
            path = @params.Path();
            InjectToken();
            ugi.DoAs(new _PrivilegedExceptionAction_110(this, ctx, req));
        }
예제 #11
0
        /// <exception cref="System.IO.FileNotFoundException"/>
        private static string GetPath(QueryStringDecoder decoder)
        {
            string path = decoder.Path();

            if (path.StartsWith(WebHdfsHandler.WebhdfsPrefix))
            {
                return(Sharpen.Runtime.Substring(path, WebHdfsHandler.WebhdfsPrefixLength));
            }
            else
            {
                throw new FileNotFoundException("Path: " + path + " should " + "start with " + WebHdfsHandler
                                                .WebhdfsPrefix);
            }
        }
        public void EmptyStrings()
        {
            var pathSlash = new QueryStringDecoder("path/");

            Assert.Equal("path/", pathSlash.RawPath());
            Assert.Equal("", pathSlash.RawQuery());
            var pathQuestion = new QueryStringDecoder("path?");

            Assert.Equal("path", pathQuestion.RawPath());
            Assert.Equal("", pathQuestion.RawQuery());
            var empty = new QueryStringDecoder("");

            Assert.Equal("", empty.RawPath());
            Assert.Equal("", empty.RawQuery());
        }
        public void HasPath()
        {
            var d = new QueryStringDecoder("1=2", false);

            Assert.Equal("", d.Path);
            IDictionary <string, List <string> > parameters = d.Parameters;

            Assert.Equal(1, parameters.Count);
            Assert.True(parameters.ContainsKey("1"));
            List <string> param = parameters["1"];

            Assert.NotNull(param);
            Assert.Single(param);
            Assert.Equal("2", param[0]);
        }
예제 #14
0
        public virtual void TestDeserializeHAToken()
        {
            Configuration conf = DFSTestUtil.NewHAConfiguration(LogicalName);

            Org.Apache.Hadoop.Security.Token.Token <DelegationTokenIdentifier> token = new Org.Apache.Hadoop.Security.Token.Token
                                                                                       <DelegationTokenIdentifier>();
            QueryStringDecoder decoder = new QueryStringDecoder(WebHdfsHandler.WebhdfsPrefix
                                                                + "/?" + NamenodeAddressParam.Name + "=" + LogicalName + "&" + DelegationParam.Name
                                                                + "=" + token.EncodeToUrlString());
            ParameterParser testParser = new ParameterParser(decoder, conf);

            Org.Apache.Hadoop.Security.Token.Token <DelegationTokenIdentifier> tok2 = testParser
                                                                                      .DelegationToken();
            NUnit.Framework.Assert.IsTrue(HAUtil.IsTokenForLogicalUri(tok2));
        }
        public void HashDos()
        {
            var buf = new StringBuilder();

            buf.Append('?');
            for (int i = 0; i < 65536; i++)
            {
                buf.Append('k');
                buf.Append(i);
                buf.Append("=v");
                buf.Append(i);
                buf.Append('&');
            }

            var d = new QueryStringDecoder(buf.ToString());
            IDictionary <string, List <string> > parameters = d.Parameters;

            Assert.Equal(1024, parameters.Count);
        }
        public void UrlDecoding()
        {
            string caffe = new string(
                // "Caffé" but instead of putting the literal E-acute in the
                // source file, we directly use the UTF-8 encoding so as to
                // not rely on the platform's default encoding (not portable).
                new [] { 'C', 'a', 'f', 'f', '\u00E9' /* C3 A9 */ });

            string[] tests =
            {
                // Encoded   ->   Decoded or error message substring
                "",                                 "",
                "foo",                              "foo",
                "f+o",                              "f o",
                "f++",                              "f  ",
                "fo%",                              "unterminated escape sequence at index 2 of: fo%",
                "%42",                              "B",
                "%5f",                              "_",
                "f%4",                              "unterminated escape sequence at index 1 of: f%4",
                "%x2",                              "invalid hex byte 'x2' at index 1 of '%x2'",
                "%4x",                              "invalid hex byte '4x' at index 1 of '%4x'",
                "Caff%C3%A9",                       caffe,
                "случайный праздник",               "случайный праздник",
                "случайный%20праздник",             "случайный праздник",
                "случайный%20праздник%20%E2%98%BA", "случайный праздник ☺",
            };

            for (int i = 0; i < tests.Length; i += 2)
            {
                string encoded  = tests[i];
                string expected = tests[i + 1];
                try
                {
                    string decoded = QueryStringDecoder.DecodeComponent(encoded);
                    Assert.Equal(expected, decoded);
                }
                catch (ArgumentException e)
                {
                    Assert.Equal(expected, e.Message);
                }
            }
        }
        public void Uri2()
        {
            var uri = new Uri("http://foo.com/images;num=10?query=name;value=123");
            var d   = new QueryStringDecoder(uri);

            Assert.Equal("/images;num=10", d.Path);
            IDictionary <string, List <string> > parameters = d.Parameters;

            Assert.Equal(2, parameters.Count);

            KeyValuePair <string, List <string> > entry = parameters.ElementAt(0);

            Assert.Equal("query", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("name", entry.Value[0]);

            entry = parameters.ElementAt(1);
            Assert.Equal("value", entry.Key);
            Assert.Single(entry.Value);
            Assert.Equal("123", entry.Value[0]);
        }
예제 #18
0
        protected override void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest request)
        {
            QueryStringDecoder queryString = new QueryStringDecoder(request.Uri);
            string             streamId    = StreamId(request);
            int latency = Http2ExampleUtil.ToInt(Http2ExampleUtil.FirstValue(queryString, LATENCY_FIELD_NAME), 0);

            if (latency < MIN_LATENCY || latency > MAX_LATENCY)
            {
                SendBadRequest(ctx, streamId);
                return;
            }
            string x = Http2ExampleUtil.FirstValue(queryString, IMAGE_COORDINATE_X);
            string y = Http2ExampleUtil.FirstValue(queryString, IMAGE_COORDINATE_Y);

            if (x == null || y == null)
            {
                HandlePage(ctx, streamId, latency, request);
            }
            else
            {
                HandleImage(x, y, ctx, streamId, latency, request);
            }
        }
예제 #19
0
        protected override void ChannelRead0(IChannelHandlerContext ctx, IHttpObject msg)
        {
            if (msg is IHttpRequest request)
            {
                s_logger.LogTrace("=========The Request Header========");
                s_logger.LogDebug(request.ToString());
                s_logger.LogTrace("===================================");
                _request = request;
                var uriPath = GetPath(request.Uri);
                if (!uriPath.StartsWith("/form"))
                {
                    // Write Menu
                    WriteMenu(ctx);
                    return;
                }
                _responseContent.Clear();
                _responseContent.Append("WELCOME TO THE WILD WILD WEB SERVER\r\n");
                _responseContent.Append("===================================\r\n");

                _responseContent.Append("VERSION: " + request.ProtocolVersion.Text + "\r\n");

                _responseContent.Append("REQUEST_URI: " + request.Uri + "\r\n\r\n");
                _responseContent.Append("\r\n\r\n");

                // new getMethod
                foreach (var entry in request.Headers)
                {
                    _responseContent.Append("HEADER: " + entry.Key + '=' + entry.Value + "\r\n");
                }
                _responseContent.Append("\r\n\r\n");

                // new getMethod
                ISet <ICookie> cookies;
                string         value = request.Headers.GetAsString(HttpHeaderNames.Cookie);
                if (value == null)
                {
                    cookies = new HashSet <ICookie>();
                }
                else
                {
                    cookies = ServerCookieDecoder.StrictDecoder.Decode(value);
                }
                foreach (var cookie in cookies)
                {
                    _responseContent.Append("COOKIE: " + cookie + "\r\n");
                }
                _responseContent.Append("\r\n\r\n");

                QueryStringDecoder decoderQuery = new QueryStringDecoder(request.Uri);
                var uriAttributes = decoderQuery.Parameters;
                foreach (var attr in uriAttributes)
                {
                    foreach (var attrVal in attr.Value)
                    {
                        _responseContent.Append("URI: " + attr.Key + '=' + attrVal + "\r\n");
                    }
                }
                _responseContent.Append("\r\n\r\n");

                // if GET Method: should not try to create an HttpPostRequestDecoder
                if (HttpMethod.Get.Equals(request.Method))
                {
                    // GET Method: should not try to create an HttpPostRequestDecoder
                    // So stop here
                    _responseContent.Append("\r\n\r\nEND OF GET CONTENT\r\n");
                    // Not now: LastHttpContent will be sent writeResponse(ctx.channel());
                    return;
                }
                try
                {
                    _decoder = new HttpPostRequestDecoder(s_factory, request);
                }
                catch (ErrorDataDecoderException e1)
                {
                    s_logger.LogError(e1.ToString());
                    _responseContent.Append(e1.Message);
                    WriteResponseAsync(ctx.Channel, true);
                    return;
                }

                var readingChunks = HttpUtil.IsTransferEncodingChunked(request);
                _responseContent.Append("Is Chunked: " + readingChunks + "\r\n");
                _responseContent.Append("IsMultipart: " + _decoder.IsMultipart + "\r\n");
                if (readingChunks)
                {
                    // Chunk version
                    _responseContent.Append("Chunks: ");
                }
            }

            // check if the decoder was constructed before
            // if not it handles the form get
            if (_decoder != null)
            {
                if (msg is IHttpContent chunk) // New chunk is received
                {
                    try
                    {
                        _decoder.Offer(chunk);
                    }
                    catch (ErrorDataDecoderException e1)
                    {
                        s_logger.LogError(e1.ToString());
                        _responseContent.Append(e1.Message);
                        WriteResponseAsync(ctx.Channel, true);
                        return;
                    }
                    _responseContent.Append('o');
                    // example of reading chunk by chunk (minimize memory usage due to
                    // Factory)
                    ReadHttpDataChunkByChunk();
                    // example of reading only if at the end
                    if (chunk is ILastHttpContent)
                    {
                        WriteResponseAsync(ctx.Channel);

                        Reset();
                    }
                }
            }
            else
            {
                WriteResponseAsync(ctx.Channel);
            }
        }
예제 #20
0
        protected override async void ChannelRead0(IChannelHandlerContext ctx, IFullHttpRequest msg)
        {
            try
            {
                IFullHttpRequest   request            = msg;
                string             uri                = request.Uri;
                QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri);
                string             path               = queryStringDecoder.Path;
                if (!path.Equals(Settings.Ins.HttpUrl))
                {
                    await ctx.CloseAsync();

                    return;
                }

                // chrome等浏览器会请求一次.ico
                if (uri.EndsWith(".ico"))
                {
                    await ctx.WriteAndFlushAsync(response(""));

                    return;
                }

                Dictionary <string, string> paramMap = new Dictionary <string, string>();
                HttpMethod method = request.Method;

                QueryStringDecoder decoder = new QueryStringDecoder(request.Uri);
                foreach (var keyValuePair in decoder.Parameters)
                {
                    paramMap.Add(keyValuePair.Key, keyValuePair.Value[0]);
                }

                if (Equals(HttpMethod.Post, method))
                {
                    var headCType = request.Headers.Get(HttpHeaderNames.ContentType, null);
                    if (headCType == null)
                    {
                        await ctx.WriteAndFlushAsync(response(HttpHeaderNames.ContentType + " is null"));

                        await ctx.CloseAsync();

                        return;
                    }

                    string content_type = headCType.ToString().ToLower();
                    if (content_type != null && content_type.Equals("application/json"))
                    {
                        // json 格式
                        string str      = request.Content.ToString(Encoding.UTF8);
                        var    jsonNode = JSON.Parse(str) as JSONClass;
                        if (jsonNode == null)
                        {
                            return;
                        }

                        var enumerator = jsonNode.GetEnumerator();
                        while (enumerator.MoveNext())
                        {
                            var keyValuePair = (KeyValuePair <string, JSONNode>)enumerator.Current;
                            if (paramMap.ContainsKey(keyValuePair.Key))
                            {
                                await ctx.WriteAndFlushAsync(response("参数重复了:" + keyValuePair.Key));

                                await ctx.CloseAsync();

                                return;
                            }

                            if (!string.IsNullOrEmpty(keyValuePair.Value.Value))
                            {
                                paramMap.Add(keyValuePair.Key, keyValuePair.Value.Value);
                            }
                            else
                            {
                                paramMap.Add(keyValuePair.Key, keyValuePair.Value.ToString());
                            }
                        }
                    }
                    else
                    {
                        // key value 形式
                        HttpPostRequestDecoder decoder1 = new HttpPostRequestDecoder(request);
                        decoder1.Offer(request);
                        List <IInterfaceHttpData> parmList = decoder1.GetBodyHttpDatas();
                        foreach (var httpData in parmList)
                        {
                            if (httpData is IAttribute data)
                            {
                                paramMap.Add(data.Name, data.Value);
                            }
                        }

                        decoder1.Destroy();
                    }
                }

                string res = await handleHttpRequest(ctx.Channel.RemoteAddress.ToString(), uri, paramMap);

                await ctx.WriteAndFlushAsync(response(res));
            }
            catch (Exception e)
            {
                LOGGER.Error("http response error {} \n {}", e.Message, e.StackTrace);
                try
                {
                    await ctx.WriteAndFlushAsync(response(e.Message));

                    await ctx.CloseAsync();
                }
                catch (Exception)
                {
                    LOGGER.Error("HTTP连接关闭异常");
                }
            }
        }
예제 #21
0
			/// <exception cref="System.Exception"/>
			public override void MessageReceived(ChannelHandlerContext ctx, MessageEvent evt)
			{
				HttpRequest request = (HttpRequest)evt.GetMessage();
				if (request.GetMethod() != HttpMethod.Get)
				{
					this.SendError(ctx, HttpResponseStatus.MethodNotAllowed);
					return;
				}
				// Check whether the shuffle version is compatible
				if (!ShuffleHeader.DefaultHttpHeaderName.Equals(request.GetHeader(ShuffleHeader.HttpHeaderName
					)) || !ShuffleHeader.DefaultHttpHeaderVersion.Equals(request.GetHeader(ShuffleHeader
					.HttpHeaderVersion)))
				{
					this.SendError(ctx, "Incompatible shuffle request version", HttpResponseStatus.BadRequest
						);
				}
				IDictionary<string, IList<string>> q = new QueryStringDecoder(request.GetUri()).GetParameters
					();
				IList<string> keepAliveList = q["keepAlive"];
				bool keepAliveParam = false;
				if (keepAliveList != null && keepAliveList.Count == 1)
				{
					keepAliveParam = Sharpen.Extensions.ValueOf(keepAliveList[0]);
					if (ShuffleHandler.Log.IsDebugEnabled())
					{
						ShuffleHandler.Log.Debug("KeepAliveParam : " + keepAliveList + " : " + keepAliveParam
							);
					}
				}
				IList<string> mapIds = this.SplitMaps(q["map"]);
				IList<string> reduceQ = q["reduce"];
				IList<string> jobQ = q["job"];
				if (ShuffleHandler.Log.IsDebugEnabled())
				{
					ShuffleHandler.Log.Debug("RECV: " + request.GetUri() + "\n  mapId: " + mapIds + "\n  reduceId: "
						 + reduceQ + "\n  jobId: " + jobQ + "\n  keepAlive: " + keepAliveParam);
				}
				if (mapIds == null || reduceQ == null || jobQ == null)
				{
					this.SendError(ctx, "Required param job, map and reduce", HttpResponseStatus.BadRequest
						);
					return;
				}
				if (reduceQ.Count != 1 || jobQ.Count != 1)
				{
					this.SendError(ctx, "Too many job/reduce parameters", HttpResponseStatus.BadRequest
						);
					return;
				}
				int reduceId;
				string jobId;
				try
				{
					reduceId = System.Convert.ToInt32(reduceQ[0]);
					jobId = jobQ[0];
				}
				catch (FormatException)
				{
					this.SendError(ctx, "Bad reduce parameter", HttpResponseStatus.BadRequest);
					return;
				}
				catch (ArgumentException)
				{
					this.SendError(ctx, "Bad job parameter", HttpResponseStatus.BadRequest);
					return;
				}
				string reqUri = request.GetUri();
				if (null == reqUri)
				{
					// TODO? add upstream?
					this.SendError(ctx, HttpResponseStatus.Forbidden);
					return;
				}
				HttpResponse response = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus
					.Ok);
				try
				{
					this.VerifyRequest(jobId, ctx, request, response, new Uri("http", string.Empty, this
						.port, reqUri));
				}
				catch (IOException e)
				{
					ShuffleHandler.Log.Warn("Shuffle failure ", e);
					this.SendError(ctx, e.Message, HttpResponseStatus.Unauthorized);
					return;
				}
				IDictionary<string, ShuffleHandler.Shuffle.MapOutputInfo> mapOutputInfoMap = new 
					Dictionary<string, ShuffleHandler.Shuffle.MapOutputInfo>();
				Org.Jboss.Netty.Channel.Channel ch = evt.GetChannel();
				string user = this._enclosing.userRsrc[jobId];
				// $x/$user/appcache/$appId/output/$mapId
				// TODO: Once Shuffle is out of NM, this can use MR APIs to convert
				// between App and Job
				string outputBasePathStr = this.GetBaseLocation(jobId, user);
				try
				{
					this.PopulateHeaders(mapIds, outputBasePathStr, user, reduceId, request, response
						, keepAliveParam, mapOutputInfoMap);
				}
				catch (IOException e)
				{
					ch.Write(response);
					ShuffleHandler.Log.Error("Shuffle error in populating headers :", e);
					string errorMessage = this.GetErrorMessage(e);
					this.SendError(ctx, errorMessage, HttpResponseStatus.InternalServerError);
					return;
				}
				ch.Write(response);
				//Initialize one ReduceContext object per messageReceived call
				ShuffleHandler.ReduceContext reduceContext = new ShuffleHandler.ReduceContext(mapIds
					, reduceId, ctx, user, mapOutputInfoMap, outputBasePathStr);
				for (int i = 0; i < Math.Min(this._enclosing.maxSessionOpenFiles, mapIds.Count); 
					i++)
				{
					ChannelFuture nextMap = this.SendMap(reduceContext);
					if (nextMap == null)
					{
						return;
					}
				}
			}
        public void BasicUris()
        {
            var d = new QueryStringDecoder("http://localhost/path");

            Assert.Equal(0, d.Parameters.Count);
        }
        public void Basic()
        {
            var d = new QueryStringDecoder("/foo");

            Assert.Equal("/foo", d.Path);
            Assert.Equal(0, d.Parameters.Count);

            d = new QueryStringDecoder("/foo%20bar");
            Assert.Equal("/foo bar", d.Path);
            Assert.Equal(0, d.Parameters.Count);

            d = new QueryStringDecoder("/foo?a=b=c");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Single(d.Parameters["a"]);
            Assert.Equal("b=c", d.Parameters["a"][0]);

            d = new QueryStringDecoder("/foo?a=1&a=2");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["a"].Count);
            Assert.Equal("1", d.Parameters["a"][0]);
            Assert.Equal("2", d.Parameters["a"][1]);

            d = new QueryStringDecoder("/foo%20bar?a=1&a=2");
            Assert.Equal("/foo bar", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["a"].Count);
            Assert.Equal("1", d.Parameters["a"][0]);
            Assert.Equal("2", d.Parameters["a"][1]);

            d = new QueryStringDecoder("/foo?a=&a=2");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["a"].Count);
            Assert.Equal("", d.Parameters["a"][0]);
            Assert.Equal("2", d.Parameters["a"][1]);

            d = new QueryStringDecoder("/foo?a=1&a=");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["a"].Count);
            Assert.Equal("1", d.Parameters["a"][0]);
            Assert.Equal("", d.Parameters["a"][1]);

            d = new QueryStringDecoder("/foo?a=1&a=&a=");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(3, d.Parameters["a"].Count);
            Assert.Equal("1", d.Parameters["a"][0]);
            Assert.Equal("", d.Parameters["a"][1]);
            Assert.Equal("", d.Parameters["a"][2]);

            d = new QueryStringDecoder("/foo?a=1=&a==2");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["a"].Count);
            Assert.Equal("1=", d.Parameters["a"][0]);
            Assert.Equal("=2", d.Parameters["a"][1]);

            d = new QueryStringDecoder("/foo?abc=1%2023&abc=124%20");
            Assert.Equal("/foo", d.Path);
            Assert.Equal(1, d.Parameters.Count);
            Assert.Equal(2, d.Parameters["abc"].Count);
            Assert.Equal("1 23", d.Parameters["abc"][0]);
            Assert.Equal("124 ", d.Parameters["abc"][1]);
        }