コード例 #1
0
        public Task RequestFilterAsync(IRequest req, IResponse res, object requestDto)
        {
            if (!string.IsNullOrEmpty(allowedOrigins))
            {
                res.AddHeader(HttpHeaders.AllowOrigin, allowedOrigins);
            }
            if (!string.IsNullOrEmpty(allowedMethods))
            {
                res.AddHeader(HttpHeaders.AllowMethods, allowedMethods);
            }
            if (!string.IsNullOrEmpty(allowedHeaders))
            {
                res.AddHeader(HttpHeaders.AllowHeaders, allowedHeaders);
            }
            if (allowCredentials)
            {
                res.AddHeader(HttpHeaders.AllowCredentials, "true");
            }

            if (AutoHandleOptionRequests && req.Verb == HttpMethods.Options)
            {
                res.EndRequest();
            }

            return(TypeConstants.EmptyTask);
        }
コード例 #2
0
        private void HandleOptionsRequest(IRequest request, IResponse response)
        {
            var origin  = request.CorsOrigin;
            var allowed = OriginIsAllowed(request, origin);

            response.StatusCode = allowed ? HttpStatusCode.OK : HttpStatusCode.Forbidden;
            if (allowed)
            {
                var requestMethod  = (request.Headers["Access-Control-Request-Method"] ?? "").ToUpper();
                var allowedMethods = new List <string>()
                {
                    "POST", "GET", "OPTIONS"
                };
                if (!allowedMethods.Contains(requestMethod))
                {
                    allowedMethods.Add(requestMethod);
                }

                var requestHeaders = (request.Headers["Access-Control-Request-Headers"] ?? "")
                                     .Split(',')
                                     .Select(r => (r ?? "").Trim().ToUpper())
                                     .Where(r => r != "")
                                     .ToArray();
                var allowedHeaders = new string[] { "X-VirtualRadarServer-AircraftIds" }
                .Concat(requestHeaders)
                .Distinct()
                .ToArray();

                response.AddHeader("Access-Control-Allow-Origin", origin);
                response.AddHeader("Access-Control-Allow-Methods", String.Join(", ", allowedMethods.ToArray()));
                response.AddHeader("Access-Control-Allow-Headers", String.Join(", ", allowedHeaders));
            }
            response.ContentLength = 0;
        }
コード例 #3
0
        /// <summary>
        /// Non ASP.NET requests
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="operationName"></param>
        public override void ProcessRequest(IRequest request, IResponse response, string operationName)
        {
            if (string.IsNullOrEmpty(RelativeUrl) && string.IsNullOrEmpty(AbsoluteUrl))
                throw new ArgumentException("RelativeUrl and AbsoluteUrl is Required");

            if (!string.IsNullOrEmpty(AbsoluteUrl))
            {
                response.StatusCode = (int)StatusCode;
                response.AddHeader(HttpHeaders.Location, this.AbsoluteUrl);
            }
            else
            {
                var absoluteUrl = request.GetApplicationUrl();
                if (!string.IsNullOrEmpty(RelativeUrl))
                {
                    if (this.RelativeUrl.StartsWith("/"))
                        absoluteUrl = absoluteUrl.CombineWith(this.RelativeUrl);
                    else if (this.RelativeUrl.StartsWith("~/"))
                        absoluteUrl = absoluteUrl.CombineWith(this.RelativeUrl.Replace("~/", ""));
                    else
                        absoluteUrl = request.AbsoluteUri.CombineWith(this.RelativeUrl);
                }
                response.StatusCode = (int)StatusCode;
                response.AddHeader(HttpHeaders.Location, absoluteUrl);
            }

            response.EndHttpHandlerRequest(skipClose: true);
        }
コード例 #4
0
        public override Task ProcessRequestAsync(IRequest request, IResponse response, string operationName)
        {
            if (string.IsNullOrEmpty(RelativeUrl) && string.IsNullOrEmpty(AbsoluteUrl))
            {
                throw new ArgumentException("RelativeUrl and AbsoluteUrl is Required");
            }

            if (!string.IsNullOrEmpty(AbsoluteUrl))
            {
                response.StatusCode = (int)StatusCode;
                response.AddHeader(HttpHeaders.Location, this.AbsoluteUrl);
            }
            else
            {
                if (RelativeUrl.StartsWith("http://") || RelativeUrl.StartsWith("https://"))
                {
                    throw new ArgumentException($"'{RelativeUrl}' is not a RelativeUrl, use AbsoluteUrl instead");
                }

                var absoluteUrl = this.RelativeUrl.StartsWith("/")
                    ? request.GetApplicationUrl().CombineWith(this.RelativeUrl) //preserve compat
                    : request.ResolveAbsoluteUrl(MakeRelative(this.RelativeUrl));

                response.StatusCode = (int)StatusCode;
                response.AddHeader(HttpHeaders.Location, absoluteUrl);
            }

            response.EndHttpHandlerRequest(skipClose: true);
            return(TypeConstants.EmptyTask);
        }
コード例 #5
0
        public OSHttpResponse(IPipelineHandlerContext context, IRequest request, IResponse response)
        {
            _httpContext  = context;
            _httpRequest  = request;
            _httpResponse = response;

            _httpResponse.AddHeader("remote_addr", MainServer.Instance.HostName);
            _httpResponse.AddHeader("remote_port", MainServer.Instance.Port.ToString());
        }
コード例 #6
0
        public OSHttpResponse(IPipelineHandlerContext context, IRequest request, IResponse response)
        {
            _httpContext = context;
            _httpRequest = request;
            _httpResponse = response;

            _httpResponse.AddHeader("remote_addr", MainServer.Instance.HostName);
            _httpResponse.AddHeader("remote_port", MainServer.Instance.Port.ToString());
        }
コード例 #7
0
        /// <summary>
        /// Filters the response.
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="res">The res.</param>
        /// <param name="dto">The dto.</param>
        public void FilterResponse(IRequest req, IResponse res, object dto)
        {
            // Try to prevent compatibility view
            res.AddHeader("X-UA-Compatible", "IE=Edge");

            var exception = dto as Exception;

            if (exception != null)
            {
                _logger.ErrorException("Error processing request for {0}", exception, req.RawUrl);

                if (!string.IsNullOrEmpty(exception.Message))
                {
                    var error = exception.Message.Replace(Environment.NewLine, " ");
                    error = RemoveControlCharacters(error);

                    res.AddHeader("X-Application-Error-Code", error);
                }
            }

            if (dto is CompressedResult)
            {
                // Per Google PageSpeed
                // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed.
                // The correct version of the resource is delivered based on the client request header.
                // This is a good choice for applications that are singly homed and depend on public proxies for user locality.
                res.AddHeader("Vary", "Accept-Encoding");
            }

            var hasOptions = dto as IHasOptions;

            if (hasOptions != null)
            {
                // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
                string contentLength;

                if (hasOptions.Options.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
                {
                    var length = long.Parse(contentLength, UsCulture);

                    if (length > 0)
                    {
                        var response = (HttpListenerResponse)res.OriginalResponse;

                        response.ContentLength64 = length;

                        // Disable chunked encoding. Technically this is only needed when using Content-Range, but
                        // anytime we know the content length there's no need for it
                        response.SendChunked = false;
                    }
                }
            }
        }
コード例 #8
0
ファイル: ResponseFilter.cs プロジェクト: Rycius/MediaBrowser
        /// <summary>
        /// Filters the response.
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="res">The res.</param>
        /// <param name="dto">The dto.</param>
        public void FilterResponse(IRequest req, IResponse res, object dto)
        {
            // Try to prevent compatibility view
            res.AddHeader("X-UA-Compatible", "IE=Edge");

            var exception = dto as Exception;

            if (exception != null)
            {
                _logger.ErrorException("Error processing request for {0}", exception, req.RawUrl);

                if (!string.IsNullOrEmpty(exception.Message))
                {
                    var error = exception.Message.Replace(Environment.NewLine, " ");
                    error = RemoveControlCharacters(error);

                    res.AddHeader("X-Application-Error-Code", error);
                }
            }

            if (dto is CompressedResult)
            {
                // Per Google PageSpeed
                // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed. 
                // The correct version of the resource is delivered based on the client request header. 
                // This is a good choice for applications that are singly homed and depend on public proxies for user locality.                        
                res.AddHeader("Vary", "Accept-Encoding");
            }

            var hasOptions = dto as IHasOptions;

            if (hasOptions != null)
            {
                // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
                string contentLength;

                if (hasOptions.Options.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
                {
                    var length = long.Parse(contentLength, UsCulture);

                    if (length > 0)
                    {
                        var response = (HttpListenerResponse)res.OriginalResponse;

                        response.ContentLength64 = length;
                       
                        // Disable chunked encoding. Technically this is only needed when using Content-Range, but
                        // anytime we know the content length there's no need for it
                        response.SendChunked = false;
                    }
                }
            }
        }
コード例 #9
0
 private void AddCacheHeaders(IResponse response, int cacheSeconds)
 {
     if (cacheSeconds > 0)
     {
         response.AddHeader("Cache-Control", String.Format("max-age={0}", cacheSeconds));
     }
     else
     {
         response.AddHeader("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate");
         response.AddHeader("Expires", "Fri, 31 Dec 1999 01:00:00 GMT");
         response.AddHeader("Pragma", "no-cache"); // for IE
         response.AddHeader("Vary", "*");
     }
 }
コード例 #10
0
        public void RequestFilter(IRequest req, IResponse res, object requestDto)
        {
            if (!string.IsNullOrEmpty(allowedOrigins))
                res.AddHeader(HttpHeaders.AllowOrigin, allowedOrigins);
            if (!string.IsNullOrEmpty(allowedMethods))
                res.AddHeader(HttpHeaders.AllowMethods, allowedMethods);
            if (!string.IsNullOrEmpty(allowedHeaders))
                res.AddHeader(HttpHeaders.AllowHeaders, allowedHeaders);
            if (allowCredentials)
                res.AddHeader(HttpHeaders.AllowCredentials, "true");

            if (AutoHandleOptionRequests && req.Verb == HttpMethods.Options)
                res.EndRequest();
        }
コード例 #11
0
        public override void Execute(IRequest req, IResponse res, object requestDto)
        {
            var authErrorMessage = "";
            try
            {
                // Perform security check
                if (CanExecute(req))
                    return;
            }
            catch (System.Exception ex)
            {
                authErrorMessage = ex.Message;
                var message = string.Format("Blocked unauthorized request: {0} {1} by ip = {2} due to {3}",
                    req.Verb,
                    req.AbsoluteUri,
                    req.UserHostAddress ?? "unknown",
                    authErrorMessage);
                Log.Error(message);
            }

            // Security failed!
            var responseMessage = "You are not authorized. " + authErrorMessage;

            res.StatusCode = (int)HttpStatusCode.Unauthorized;
            res.StatusDescription = responseMessage;
            res.AddHeader(HttpHeaders.WwwAuthenticate, string.Format("{0} realm=\"{1}\"", "", "custom api"));
            res.ContentType = "text/plain";
            res.Write(responseMessage);
            res.Close();
        }
コード例 #12
0
        /// <summary>
        /// Create a WWW-Authenticate header
        /// </summary>
        public void CreateChallenge(IRequest request, IResponse response)
        {
            var nonce = GetCurrentNonce();

            var challenge = new StringBuilder("Digest realm=\"");

            challenge.Append(_realmRepository.GetRealm(request));
            challenge.Append("\"");
            challenge.Append(", nonce=\"");
            challenge.Append(nonce);
            challenge.Append("\"");
            challenge.Append(", opaque=\"" + Guid.NewGuid().ToString().Replace("-", string.Empty) + "\"");

            /* Disable the stale mechanism
             * We should really generate the responses directly in these classes.
             * challenge.Append(", stale=");
             * challenge.Append((bool)options[0] ? "true" : "false");
             * challenge.Append("false");
             * */

            challenge.Append(", algorithm=MD5");
            challenge.Append(", qop=auth");


            response.AddHeader("WWW-Authenticate", challenge.ToString());
        }
コード例 #13
0
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="response"></param>
        /// <param name="image"></param>
        /// <param name="format"></param>
        public void SendImage(IResponse response, Image image, ImageFormat format)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }
            if (format == null)
            {
                throw new ArgumentNullException("format");
            }
            if (format != ImageFormat.Bmp && format != ImageFormat.Gif && format != ImageFormat.Png)
            {
                throw new NotSupportedException(String.Format("Responder does not support sending {0} images", format));
            }

            response.AddHeader("Cache-Control", "max-age=21600");

            byte[] bytes;
            using (var stream = new MemoryStream()) {
                using (var copy = (Image)image.Clone()) {
                    copy.Save(stream, format);
                }

                bytes = stream.ToArray();
            }

            response.StatusCode    = HttpStatusCode.OK;
            response.MimeType      = ImageMimeType(format);
            response.ContentLength = bytes.Length;
            response.OutputStream.Write(bytes, 0, bytes.Length);
        }
コード例 #14
0
ファイル: ResponderBase.cs プロジェクト: ThreeHeadz/Bam.Net
 protected void SetContentDisposition(IResponse response, string path)
 {
     if (Path.GetExtension(path).Equals(".pdf", StringComparison.InvariantCultureIgnoreCase))
     {
         response.AddHeader("Content-Disposition", $"attachment; filename={Path.GetFileName(path)}");
     }
 }
コード例 #15
0
 public override Task OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
     //Needs to be 'Basic ' in order for HttpWebRequest to accept challenge and send NetworkCredentials
     httpRes.AddHeader(HttpHeaders.WwwAuthenticate, $"Basic realm=\"{this.AuthRealm}\"");
     return(HostContext.AppHost.HandleShortCircuitedErrors(httpReq, httpRes, httpReq.Dto));
 }
コード例 #16
0
ファイル: Etags.cs プロジェクト: dekkerb115/Bam.Net
        public static void Set(IResponse response, string path, byte[] content)
        {
            string etag = content.Sha1();

            response.AddHeader("ETag", etag);
            Etags.Values.AddOrUpdate(path, etag, (p, v) => etag);
        }
コード例 #17
0
ファイル: AddHeaderAttribute.cs プロジェクト: vebin/soa
        public override void Execute(IRequest req, IResponse res, object requestDto)
        {
            if (StatusCode != null)
            {
                res.StatusCode = StatusCode.Value;
            }

            if (StatusDescription != null)
            {
                res.StatusDescription = StatusDescription;
            }

            if (!string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Value))
            {
                if (Name.EqualsIgnoreCase(HttpHeaders.ContentType))
                {
                    req.ResponseContentType = Value; //Looked at in WriteRespone
                }
                else if (Name == "DefaultContentType")
                {
                    if (!req.HasExplicitResponseContentType)
                    {
                        req.ResponseContentType = Value; //Looked at in WriteRespone
                    }
                }
                else
                {
                    res.AddHeader(Name, Value);
                }
            }
        }
コード例 #18
0
    public override void Execute(IRequest req, IResponse res, object requestDto)
    {
        // Get the correct repository to authenticate against
        var repositories            = HostContext.TryResolve <MyUserRepository[]>();
        MyUserRepository repository = null;

        if (repositories != null)
        {
            repository = repositories.FirstOrDefault(r => r.Name == _repositoryName);
        }
        // Determine if request has basic authentication
        var authorization = req.GetHeader(HttpHeaders.Authorization);

        if (repository != null && !String.IsNullOrEmpty(authorization) && authorization.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
        {
            // Decode the credentials
            var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authorization.Substring(6))).Split(':');
            if (credentials.Length == 2)
            {
                // Try and match the credentials to a user
                var password = repository.Users.GetValueOrDefault(credentials[0]);
                if (password != null && password == credentials[1])
                {
                    // Credentials are valid
                    return;
                }
            }
        }
        // User requires to authenticate
        res.StatusCode = (int)HttpStatusCode.Unauthorized;
        res.AddHeader(HttpHeaders.WwwAuthenticate, string.Format("basic realm=\"{0}\"", _realmName));
        res.EndRequest();
    }
コード例 #19
0
 public override void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
     //Needs to be 'Basic ' in order for HttpWebRequest to accept challenge and send NetworkCredentials
     httpRes.AddHeader(HttpHeaders.WwwAuthenticate, $"Basic realm=\"{this.AuthRealm}\"");
     httpRes.EndRequest();
 }
コード例 #20
0
        /// <summary>
        /// Create a WWW-Authenticate header
        /// </summary>
        public void CreateChallenge(IRequest request, IResponse response)
        {
            var nonce = GetCurrentNonce();

            var challenge = new StringBuilder("Digest realm=\"");
            challenge.Append(_realmRepository.GetRealm(request));
            challenge.Append("\"");
            challenge.Append(", nonce=\"");
            challenge.Append(nonce);
            challenge.Append("\"");
            challenge.Append(", opaque=\"" + Guid.NewGuid().ToString().Replace("-", string.Empty) + "\"");

            /* Disable the stale mechanism
             * We should really generate the responses directly in these classes.
            challenge.Append(", stale=");
            challenge.Append((bool)options[0] ? "true" : "false");
            challenge.Append("false");
             * */

            challenge.Append(", algorithm=MD5");
            challenge.Append(", qop=auth");


            response.AddHeader("WWW-Authenticate", challenge.ToString());
        }
コード例 #21
0
        public override void Execute(IRequest request, IResponse response, object requestDto)
        {
            try
            {
                var            cryptoKeyProvider = ServiceStackHost.Instance.Container.Resolve <ICryptoKeyProvider>();
                ICryptoKeyPair authZServerKeys   = cryptoKeyProvider.GetCryptoKey(CryptoKeyType.AuthZServer);
                ICryptoKeyPair apiServiceKeys    = cryptoKeyProvider.GetCryptoKey(CryptoKeyType.ApiService);

                var tokenAnalyzer = new StandardAccessTokenAnalyzer(authZServerKeys.PublicSigningKey,
                                                                    apiServiceKeys.PrivateEncryptionKey);
                var resourceServer = new ResourceServer(tokenAnalyzer);

                // Verify the signed bearer token (for specified scopes), and extract the user's identity
                AccessToken token = resourceServer.GetAccessToken((HttpRequestBase)request.OriginalRequest, scopes);

                // Assign this user to the current HTTP context
                var user = new OAuthPrincipal(token.User, GetUserRoles(token));
                ((HttpRequestBase)request.OriginalRequest).RequestContext.HttpContext.User = user;
            }
            catch (ProtocolFaultResponseException ex)
            {
                //TODO: if the token is invalid in some way (i.e. malformed) then return 400-BadRequest.
                // The token is either: expired or invalid or revoked, we need to return 401-Unauthorized
                response.AddHeader(HttpHeaders.WwwAuthenticate, @"Bearer");
                throw HttpErrorThrower.Unauthorized(ex.Message);
            }
        }
コード例 #22
0
        public override void Execute(IRequest req, IResponse res, object requestDto)
        {
            if (StatusCode != null)
            {
                res.StatusCode = StatusCode.Value;
            }

            if (StatusDescription != null)
            {
                res.StatusDescription = StatusDescription;
            }

            if (!string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Value))
            {
                if (Name.EqualsIgnoreCase(HttpHeaders.ContentType))
                {
                    req.ResponseContentType = Value; //Looked at in WriteRespone
                }
                else if (Name == "DefaultContentType")
                {
                    if (!req.HasExplicitResponseContentType)
                    {
                        req.ResponseContentType = Value; //Looked at in WriteRespone
                    }
                }
                else
                {
                    res.AddHeader(Name, Value);
                }
            }
        }
コード例 #23
0
 /// <summary>
 /// See interface docs.
 /// </summary>
 /// <param name="request"></param>
 /// <param name="response"></param>
 public void AddCorsHeaders(IRequest request, IResponse response)
 {
     if (request.IsValidCorsRequest)
     {
         response.AddHeader("Access-Control-Allow-Origin", request.CorsOrigin);
     }
 }
コード例 #24
0
        /// <summary>
        /// Non ASP.NET requests
        /// </summary>
        public override void ProcessRequest(IRequest request, IResponse response, string operationName)
        {
            var defaultUrl = HostContext.Config.ServiceEndpointsMetadataConfig.DefaultMetadataUri;

            if (request.PathInfo == "/")
            {
                var relativeUrl = defaultUrl.Substring(defaultUrl.IndexOf('/'));
                var absoluteUrl = request.RawUrl.TrimEnd('/') + relativeUrl;
                response.StatusCode = (int)HttpStatusCode.Redirect;
                response.AddHeader(HttpHeaders.Location, absoluteUrl);
            }
            else
            {
                response.StatusCode = (int)HttpStatusCode.Redirect;
                response.AddHeader(HttpHeaders.Location, defaultUrl);
            }
        }
コード例 #25
0
        public virtual void SetResponseCorrelationId(IRequest request, IResponse response, object dto)
        {
            var correlationId = request.GetCorrelationId(HeaderName);

            log.Debug($"Setting correlation Id {correlationId} to header {HeaderName} on response object");

            response.AddHeader(HeaderName, correlationId);
        }
コード例 #26
0
        /// <summary>
        /// Non ASP.NET requests
        /// </summary>
        public override void ProcessRequest(IRequest request, IResponse response, string operationName)
        {
            var defaultUrl = HostContext.Config.ServiceEndpointsMetadataConfig.DefaultMetadataUri;

            if (request.PathInfo == "/")
            {
                var relativeUrl = defaultUrl.Substring(defaultUrl.IndexOf('/'));
                var absoluteUrl = request.RawUrl.TrimEnd('/') + relativeUrl;
                response.StatusCode = (int)HttpStatusCode.Redirect;
                response.AddHeader(HttpHeaders.Location, absoluteUrl);
            }
            else
            {
                response.StatusCode = (int)HttpStatusCode.Redirect;
                response.AddHeader(HttpHeaders.Location, defaultUrl);
            }
        }
コード例 #27
0
            public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
            {
                res.ContentType = MimeTypes.ServerSentEvents;
                res.AddHeader(HttpHeaders.CacheControl, "no-cache");
                res.KeepAlive = true;
                res.Flush();

                IAuthSession session    = req.GetSession();
                var          userAuthId = session != null ? session.UserAuthId : null;
                var          feature    = HostContext.GetPlugin <SimpleServerEventsFeature>();

                //var now = DateTime.UtcNow;
                var subscriptionId = SessionExtensions.CreateRandomSessionId();
                var eventClient    = new EventClient(res)
                {
                    SubscriptionId = subscriptionId,     // A session can have multiple subscriptions / clients
                };

                if (feature.OnCreated != null)
                {
                    feature.OnCreated(eventClient, req);
                }

                //var heartbeatUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath))
                //    .AddQueryParam("id", subscriptionId);

                var privateArgs = new Dictionary <string, string>(eventClient.Meta)
                {
                    { "id", subscriptionId },
                    //{"heartbeatUrl", heartbeatUrl},
                    //{"heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
                };

                // Register the client
                req.TryResolve <IServerEventsBroker>().Connect(eventClient);

                if (feature.OnConnected != null)
                {
                    feature.OnConnected(eventClient, privateArgs);
                }

                // Welcome our new client
                res.OutputStream.Write(": " + subscriptionId + " connected\n\n");     // Write initial stream so the client knows we're alive
                res.Flush();
                var tcs = new TaskCompletionSource <bool>();

                eventClient.OnDispose = client =>
                {
                    try
                    {
                        res.EndHttpHandlerRequest(skipHeaders: true);
                    }
                    catch { }
                    tcs.SetResult(true);
                };

                return(tcs.Task);
            }
コード例 #28
0
        //Own function that adds the custom Http headers to the server's response
        private void AddResponseHeaders(IRequest req, IResponse res, object dto)
        {
            res.ContentType = MimeTypes.Json;

            //Get TimeStamp
            System.DateTime initDate  = new DateTime(1970, 1, 1, 0, 0, 0);
            TimeSpan        tsUtcTime = new TimeSpan(System.DateTime.UtcNow.Ticks - initDate.Ticks);

            //var token = ApiSignature.CreateToken(res, dto == null ? string.Empty : dto.SerializeToString(), _secret);

            //Add custom fields to header
            if (!string.IsNullOrEmpty(ApiCustomHttpHeaders.UserId))
            {
                res.AddHeader(ApiCustomHttpHeaders.UserId, req.GetHeader(ApiCustomHttpHeaders.UserId));
            }
            if (!string.IsNullOrEmpty(ApiCustomHttpHeaders.DeviceId))
            {
                res.AddHeader(ApiCustomHttpHeaders.DeviceId, req.GetHeader(ApiCustomHttpHeaders.DeviceId));
            }
            res.AddHeader(ApiCustomHttpHeaders.Signature, "sdgthdtyj");
            res.AddHeader(ApiCustomHttpHeaders.VEWSVersion, "V1R0");
            res.AddHeader(ApiCustomHttpHeaders.SignatureMethod, "HMAC_SHA256");
            res.AddHeader(ApiCustomHttpHeaders.TimeStamp, ((ulong)tsUtcTime.TotalMilliseconds).ToString());
            if (!string.IsNullOrEmpty(ApiCustomHttpHeaders.ReqId))
            {
                res.AddHeader(ApiCustomHttpHeaders.ReqId, req.GetHeader(ApiCustomHttpHeaders.ReqId));
            }
        }
コード例 #29
0
        public override Task OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
        {
            var digestHelper = new DigestAuthFunctions();

            httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
            httpRes.AddHeader(HttpHeaders.WwwAuthenticate,
                              $"{Provider} realm=\"{AuthRealm}\", nonce=\"{digestHelper.GetNonce(httpReq.UserHostAddress, PrivateKey)}\", qop=\"auth\"");
            return(HostContext.AppHost.HandleShortCircuitedErrors(httpReq, httpRes, httpReq.Dto));
        }
コード例 #30
0
 public virtual void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     if (httpRes.StatusCode == (int)HttpStatusCode.OK)
     {
         httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
     }
     httpRes.AddHeader(HttpHeaders.WwwAuthenticate, $"{this.Provider} realm=\"{this.AuthRealm}\"");
     httpRes.EndRequest();
 }
コード例 #31
0
        public static void AddHeaderLastModified(this IResponse httpRes, DateTime?lastModified)
        {
            if (!lastModified.HasValue)
            {
                return;
            }
            var lastWt = lastModified.Value.ToUniversalTime();

            httpRes.AddHeader(HttpHeaders.LastModified, lastWt.ToString("r"));
        }
コード例 #32
0
        public override void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
        {
            var digestHelper = new DigestAuthFunctions();

            httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
            httpRes.AddHeader(
                HttpHeaders.WwwAuthenticate,
                "{0} realm=\"{1}\", nonce=\"{2}\", qop=\"auth\"".Fmt(Provider, AuthRealm, digestHelper.GetNonce(httpReq.UserHostAddress, PrivateKey)));
            httpRes.EndRequest();
        }
コード例 #33
0
        public static Task HandleFailedAuth(IAuthProvider authProvider,
            IAuthSession session, IRequest httpReq, IResponse httpRes)
        {
            if (authProvider is AuthProvider baseAuthProvider)
                return baseAuthProvider.OnFailedAuthentication(session, httpReq, httpRes);

            httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
            httpRes.AddHeader(HttpHeaders.WwwAuthenticate, $"{authProvider.Provider} realm=\"{authProvider.AuthRealm}\"");
            return HostContext.AppHost.HandleShortCircuitedErrors(httpReq, httpRes, httpReq.Dto);
        }
コード例 #34
0
 public static void ApplyGlobalResponseHeaders(this IResponse httpRes)
 {
     if (HostContext.Config == null)
     {
         return;
     }
     foreach (var globalResponseHeader in HostContext.Config.GlobalResponseHeaders)
     {
         httpRes.AddHeader(globalResponseHeader.Key, globalResponseHeader.Value);
     }
 }
コード例 #35
0
ファイル: ResponseFilter.cs プロジェクト: zxz2020/jellyfin
        /// <summary>
        /// Filters the response.
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="res">The res.</param>
        /// <param name="dto">The dto.</param>
        public void FilterResponse(IRequest req, IResponse res, object dto)
        {
            // Try to prevent compatibility view
            res.AddHeader("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
            res.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
            res.AddHeader("Access-Control-Allow-Origin", "*");

            if (dto is Exception exception)
            {
                _logger.LogError(exception, "Error processing request for {RawUrl}", req.RawUrl);

                if (!string.IsNullOrEmpty(exception.Message))
                {
                    var error = exception.Message.Replace(Environment.NewLine, " ");
                    error = RemoveControlCharacters(error);

                    res.AddHeader("X-Application-Error-Code", error);
                }
            }

            if (dto is IHasHeaders hasHeaders)
            {
                if (!hasHeaders.Headers.ContainsKey("Server"))
                {
                    hasHeaders.Headers["Server"] = "Microsoft-NetCore/2.0, UPnP/1.0 DLNADOC/1.50";
                }

                // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
                if (hasHeaders.Headers.TryGetValue("Content-Length", out string contentLength) &&
                    !string.IsNullOrEmpty(contentLength))
                {
                    var length = long.Parse(contentLength, UsCulture);

                    if (length > 0)
                    {
                        res.SetContentLength(length);
                        res.SendChunked = false;
                    }
                }
            }
        }
コード例 #36
0
        public static void SetLocation(this IResponse response, string resourceId)
        {
            if (response == null || !resourceId.HasValue())
            {
                return;
            }

            var request = response.Request;
            var value   = "{0}/{1}".Fmt(request.AbsoluteUri, resourceId);

            response.AddHeader("Location", value);
        }
コード例 #37
0
        /// <summary>
        ///     This method will only send the WWW-Authenticate response header when the User-Agent request
        ///     header contains servicestack i.e. it's the servicestack client and not a browser
        /// </summary>
        public override void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
        {
            //Only return digest header if User-Agent is the ServiceStack .NET Client
            //expected user agent value is: "ServiceStack .NET Client {Version}"
            if (httpReq.Headers["User-Agent"].ToLower().Contains("servicestack"))
            {
                httpRes.AddHeader("WWW-Authenticate",
                                  "{0} realm=\"{1}\"".Fmt(Provider, AuthRealm));
            }

            httpRes.StatusCode = 401;
            httpRes.EndRequest(false);
        }
コード例 #38
0
        private static void SetLimitHeaders(IResponse response, RateLimitResult result)
        {
            var headerResults = RateLimitHeader.Create(result?.Results);

            using (var config = JsConfig.BeginScope())
            {
                config.ExcludeTypeInfo = true;
                foreach (var header in headerResults)
                {
                    response.AddHeader(header.HeaderName, header.Limits.ToJson());
                }
            }
        }
コード例 #39
0
        public void Serve(string path, IRequest request, IResponse response)
        {
            if (request.Uri.Segments.Any(p => p == ".."))
                throw new HttpForbiddenException("Disallowed characters in path");
            if (Path.IsPathRooted(path)) path = path.Substring(path.IndexOfAny(new[] { Path.DirectorySeparatorChar, '/', '\\' }) + 1);
            if (!File.Exists(Path.Combine(BaseDirectory, path)))
                throw new HttpNotFoundException("The requested static content was not found.");

            var stream = File.OpenRead(Path.Combine(BaseDirectory, path));
            var extension = Path.GetExtension(path);
            if (extension != null)
                response.ContentType = HttpServer.GetContentTypeForExtension(extension.Substring(1));
            response.AddHeader("Accept-Ranges", "bytes");

            // Handle ranges
            long length = stream.Length;
            if (request.Headers.Any(h => h.Name == "Range"))
            {
                //response.StatusCode = 206; // Breaks things for some unknown reason, quite infuriating
                //response.StatusDescription = "Partial Content";
                var range = request.Headers["Range"].Value;
                var type = range.Remove(range.IndexOf("=", StringComparison.Ordinal));
                if (type != "bytes")
                {
                    response.StatusCode = 400;
                    response.StatusDescription = "Bad Request";
                    return;
                }
                range = range.Substring(range.IndexOf("=", StringComparison.Ordinal) + 1);
                var rangeParts = range.Split('-');
                long start = int.Parse(rangeParts[0]);
                long end;
                if (!long.TryParse(rangeParts[1], out end))
                    end = length;
                length = end - start;
                response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", start, end, length));
                stream.Seek(start, SeekOrigin.Begin);
            }
            //stream._Length = length;
            response.Body = new MemoryStream();
            stream.CopyTo(response.Body);
            stream.Close();
            response.Body.Seek(0, SeekOrigin.Begin);
        }
コード例 #40
0
        public override void Execute(IRequest req, IResponse res, object requestDto)
        {
            if (StatusCode != null)
            {
                res.StatusCode = StatusCode.Value;
            }

            if (StatusDescription != null)
            {
                res.StatusDescription = StatusDescription;
            }

            if (!string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Value))
            {
                if (Name.Equals(HttpHeaders.ContentType, StringComparison.InvariantCultureIgnoreCase))
                {
                    res.ContentType = Value;
                }
                else
                {
                    res.AddHeader(Name, Value);
                }
            }
        }
コード例 #41
0
 public virtual void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
     httpRes.AddHeader(HttpHeaders.WwwAuthenticate, "{0} realm=\"{1}\"".Fmt(this.Provider, this.AuthRealm));
     httpRes.EndRequest();
 }
コード例 #42
0
 public override void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     var digestHelper = new DigestAuthFunctions();
     httpRes.StatusCode = (int) HttpStatusCode.Unauthorized;
     httpRes.AddHeader(
         HttpHeaders.WwwAuthenticate,
         "{0} realm=\"{1}\", nonce=\"{2}\", qop=\"auth\"".Fmt(Provider, AuthRealm, digestHelper.GetNonce(httpReq.UserHostAddress, PrivateKey)));
     httpRes.EndRequest();
 }
コード例 #43
0
 public override void OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
 {
     httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
     //Needs to be 'Basic ' in order for HttpWebRequest to accept challenge and send NetworkCredentials
     httpRes.AddHeader(HttpHeaders.WwwAuthenticate, $"Basic realm=\"{this.AuthRealm}\"");
     httpRes.EndRequest();
 }
コード例 #44
0
        private static void SetLimitHeaders(IResponse response, RateLimitResult result)
        {
            var headerResults = RateLimitHeader.Create(result?.Results);

            using (var config = JsConfig.BeginScope())
            {
                config.ExcludeTypeInfo = true;
                foreach (var header in headerResults)
                {
                    response.AddHeader(header.HeaderName, header.Limits.ToJson());
                }
            }
        }
            public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
            {
                res.ContentType = MimeTypes.ServerSentEvents;
                res.AddHeader(HttpHeaders.CacheControl, "no-cache");
                res.KeepAlive = true;
                res.Flush();

                IAuthSession session = req.GetSession();
                var userAuthId = session != null ? session.UserAuthId : null;
                var feature = HostContext.GetPlugin<SimpleServerEventsFeature>();

                //var now = DateTime.UtcNow;
                var subscriptionId = SessionExtensions.CreateRandomSessionId();
                var eventClient = new EventClient(res)
                {
                    SubscriptionId = subscriptionId,     // A session can have multiple subscriptions / clients
                };

                if (feature.OnCreated != null)
                    feature.OnCreated(eventClient, req);

                //var heartbeatUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath))
                //    .AddQueryParam("id", subscriptionId);

                var privateArgs = new Dictionary<string, string>(eventClient.Meta) {
                        {"id", subscriptionId },
                        //{"heartbeatUrl", heartbeatUrl},
                        //{"heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
                };

                // Register the client
                req.TryResolve<IServerEventsBroker>().Connect(eventClient);

                if (feature.OnConnected != null)
                    feature.OnConnected(eventClient, privateArgs);

                // Welcome our new client
                res.OutputStream.Write(": " + subscriptionId + " connected\n\n");     // Write initial stream so the client knows we're alive
                res.Flush();
                var tcs = new TaskCompletionSource<bool>();

                eventClient.OnDispose = client =>
                {
                    try
                    {
                        res.EndHttpHandlerRequest(skipHeaders: true);
                    }
                    catch { }
                    tcs.SetResult(true);
                };

                return tcs.Task;
            }
コード例 #46
0
        private bool CacheAndWriteResponse(CacheInfo cacheInfo, IRequest req, IResponse res, object response)
        {
            var httpResult = response as IHttpResult;
            var dto = httpResult != null ? httpResult.Response : response;
            if (dto == null || dto is IPartialWriter || dto is IStreamWriter)
                return false;

            var expiresIn = cacheInfo.ExpiresIn.GetValueOrDefault(DefaultExpiresIn);
            var cache = cacheInfo.LocalCache ? HostContext.LocalCache : HostContext.Cache;

            var responseBytes = dto as byte[];
            if (responseBytes == null)
            {
                var rawStr = dto as string;
                if (rawStr != null)
                    responseBytes = rawStr.ToUtf8Bytes();
                else
                {
                    var stream = dto as Stream;
                    if (stream != null)
                        responseBytes = stream.ReadFully();
                }
            }

            var encoding = req.GetCompressionType();
            var cacheKeyEncoded = encoding != null ? cacheInfo.CacheKey + "." + encoding : null;
            if (responseBytes != null || req.ResponseContentType.IsBinary())
            {
                if (responseBytes == null)
                    responseBytes = HostContext.ContentTypes.SerializeToBytes(req, dto);

                cache.Set(cacheInfo.CacheKey, responseBytes, expiresIn);

                if (encoding != null)
                {
                    res.AddHeader(HttpHeaders.ContentEncoding, encoding);
                    responseBytes = responseBytes.CompressBytes(encoding);
                    cache.Set(cacheKeyEncoded, responseBytes, expiresIn);
                }
            }
            else
            {
                var serializedDto = req.SerializeToString(dto);
                if (req.ResponseContentType.MatchesContentType(MimeTypes.Json))
                {
                    var jsonp = req.GetJsonpCallback();
                    if (jsonp != null)
                        serializedDto = jsonp + "(" + serializedDto + ")";
                }

                responseBytes = serializedDto.ToUtf8Bytes();
                cache.Set(cacheInfo.CacheKey, responseBytes, expiresIn);

                if (encoding != null)
                {
                    responseBytes = responseBytes.CompressBytes(encoding);
                    cache.Set(cacheKeyEncoded, responseBytes, expiresIn);
                    res.AddHeader(HttpHeaders.ContentEncoding, encoding);
                }
            }

            var doHttpCaching = cacheInfo.MaxAge != null || cacheInfo.CacheControl != CacheControl.None;
            if (doHttpCaching)
            {
                var cacheControl = BuildCacheControlHeader(cacheInfo);
                if (cacheControl != null)
                {
                    var lastModified = cacheInfo.LastModified.GetValueOrDefault(DateTime.UtcNow);
                    cache.Set("date:" + cacheInfo.CacheKey, lastModified, expiresIn);
                    res.AddHeaderLastModified(lastModified);
                    res.AddHeader(HttpHeaders.CacheControl, cacheControl);

                    if (encoding != null)
                        res.AddHeader(HttpHeaders.Vary, "Accept-Encoding");
                    if (cacheInfo.VaryByUser)
                        res.AddHeader(HttpHeaders.Vary, "Cookie");
                }
            }

            if (httpResult != null)
            {
                foreach (var header in httpResult.Headers)
                {
                    res.AddHeader(header.Key, header.Value);
                }
            }

            res.WriteBytesToResponse(responseBytes, req.ResponseContentType);
            return true;
        }
コード例 #47
0
 /// <summary>
 /// Create a WWW-Authorize header
 /// </summary>
 public void CreateChallenge(IRequest httpRequest, IResponse response)
 {
     response.AddHeader("WWW-Authorize", "Basic realm=\"" + _realm + "\"");
 }
コード例 #48
0
ファイル: ResponseFilter.cs プロジェクト: paul-777/Emby
        /// <summary>
        /// Filters the response.
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="res">The res.</param>
        /// <param name="dto">The dto.</param>
        public void FilterResponse(IRequest req, IResponse res, object dto)
        {
            // Try to prevent compatibility view
            res.AddHeader("X-UA-Compatible", "IE=Edge");

            if (_denyIframeEmbedding())
            {
                res.AddHeader("X-Frame-Options", "SAMEORIGIN");
            }

            var exception = dto as Exception;

            if (exception != null)
            {
                _logger.ErrorException("Error processing request for {0}", exception, req.RawUrl);

                if (!string.IsNullOrEmpty(exception.Message))
                {
                    var error = exception.Message.Replace(Environment.NewLine, " ");
                    error = RemoveControlCharacters(error);

                    res.AddHeader("X-Application-Error-Code", error);
                }
            }

            var vary = "Accept-Encoding";

            var hasOptions = dto as IHasOptions;
            var sharpResponse = res as WebSocketSharpResponse;

            if (hasOptions != null)
            {
                if (!hasOptions.Options.ContainsKey("Server"))
                {
                    hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50";
                    //hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1";
                }

                // Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
                string contentLength;

                if (hasOptions.Options.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
                {
                    var length = long.Parse(contentLength, UsCulture);

                    if (length > 0)
                    {
                        res.SetContentLength(length);
                        
                        var listenerResponse = res.OriginalResponse as HttpListenerResponse;

                        if (listenerResponse != null)
                        {
                            // Disable chunked encoding. Technically this is only needed when using Content-Range, but
                            // anytime we know the content length there's no need for it
                            listenerResponse.SendChunked = false;
                            return;
                        }

                        if (sharpResponse != null)
                        {
                            sharpResponse.SendChunked = false;
                        }
                    }
                }

                string hasOptionsVary;
                if (hasOptions.Options.TryGetValue("Vary", out hasOptionsVary))
                {
                    vary = hasOptionsVary;
                }

                hasOptions.Options["Vary"] = vary;
            }

            //res.KeepAlive = false;

            // Per Google PageSpeed
            // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed. 
            // The correct version of the resource is delivered based on the client request header. 
            // This is a good choice for applications that are singly homed and depend on public proxies for user locality.                        
            res.AddHeader("Vary", vary);
        }
コード例 #49
0
ファイル: SoapHandler.cs プロジェクト: softwx/ServiceStack
 private static void SetErrorStatusIfAny(IResponse res, Message responseMsg, int statusCode)
 {
     if (statusCode >= 400)
     {
         res.AddHeader(HttpHeaders.XStatus, statusCode.ToString());
         res.StatusCode = 200;
         responseMsg.Headers.Add(
             MessageHeader.CreateHeader(
                 HttpHeaders.XStatus,
                 HostContext.Config.WsdlServiceNamespace,
                 statusCode.ToString(),
                 false));
     }
 }
コード例 #50
0
        public static void HandleFailedAuth(IAuthProvider authProvider,
            IAuthSession session, IRequest httpReq, IResponse httpRes)
        {
            var baseAuthProvider = authProvider as AuthProvider;
            if (baseAuthProvider != null)
            {
                baseAuthProvider.OnFailedAuthentication(session, httpReq, httpRes);
                return;
            }

            httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
            httpRes.AddHeader(HttpHeaders.WwwAuthenticate, "{0} realm=\"{1}\""
                .Fmt(authProvider.Provider, authProvider.AuthRealm));

            httpRes.EndRequest();
        }
コード例 #51
0
 /// <summary>
 /// Create a WWW-Authenticate header
 /// </summary>
 public void CreateChallenge(IRequest httpRequest, IResponse response)
 {
     response.AddHeader("WWW-Authenticate", "Basic realm=\"" + _realm + "\"");
     response.StatusCode = 401;
 }
コード例 #52
0
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="response"></param>
        /// <param name="image"></param>
        /// <param name="format"></param>
        public void SendImage(IResponse response, Image image, ImageFormat format)
        {
            if(response == null) throw new ArgumentNullException("response");
            if(image == null) throw new ArgumentNullException("image");
            if(format == null) throw new ArgumentNullException("format");
            if(format != ImageFormat.Bmp && format != ImageFormat.Gif && format != ImageFormat.Png) throw new NotSupportedException(String.Format("Responder does not support sending {0} images", format));

            response.AddHeader("Cache-Control", "max-age=21600");

            byte[] bytes;
            using(var stream = new MemoryStream()) {
                using(var copy = (Image)image.Clone()) {
                    copy.Save(stream, format);
                }

                bytes = stream.ToArray();
            }

            response.StatusCode = HttpStatusCode.OK;
            response.MimeType = ImageMimeType(format);
            response.ContentLength = bytes.Length;
            response.OutputStream.Write(bytes, 0, bytes.Length);
        }
コード例 #53
0
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="response"></param>
        /// <param name="json"></param>
        /// <param name="jsonpCallbackFunction"></param>
        public void SendJson(IResponse response, object json, string jsonpCallbackFunction)
        {
            if(response == null) throw new ArgumentNullException("response");
            if(json == null) throw new ArgumentNullException("json");

            response.AddHeader("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate");

            var type = json.GetType();
            JsonSerialiser serialiser;
            lock(_SyncLock) {
                if(!_JsonSerialiserMap.TryGetValue(type, out serialiser)) {
                    serialiser = new JsonSerialiser();
                    serialiser.Initialise(type);
                    _JsonSerialiserMap.Add(type, serialiser);
                }
            }

            string text;
            using(MemoryStream stream = new MemoryStream()) {
                serialiser.WriteObject(stream, json);
                text = Encoding.UTF8.GetString(stream.ToArray());
            }

            if(!String.IsNullOrEmpty(jsonpCallbackFunction)) text = String.Format("{0}({1})", jsonpCallbackFunction, text);

            SendText(response, text, Encoding.UTF8, MimeType.Json);
        }
コード例 #54
0
        /// <summary>
        /// Create a WWW-Authorize header
        /// </summary>
        public void CreateChallenge(IRequest request, IResponse response)
        {
            var nonce = _nonceService.CreateNonce();

            var challenge = new StringBuilder();
            challenge.AppendFormat(@"Digest realm=""{0}"", ", _realmRepository.GetRealm(request));
            challenge.AppendFormat(@"nonce=""{0}"", ", nonce);
            challenge.Append(@"qop=""auth"", ");
            challenge.Append("algorithm=MD5");


            /* RFC 2617 3.3
                Because the client is required to return the value of the opaque
               directive given to it by the server for the duration of a session,
               the opaque data may be used to transport authentication session state
               information. (Note that any such use can also be accomplished more
               easily and safely by including the state in the nonce.) For example,
               a server could be responsible for authenticating content that
               actually sits on another server. It would achieve this by having the
               first 401 response include a domain directive whose value includes a
               URI on the second server, and an opaque directive whose value            
               contains the state information. The client will retry the request, at
               which time the server might respond with a 301/302 redirection,
               pointing to the URI on the second server. The client will follow the
               redirection, and pass an Authorization header , including the
               <opaque> data.
            */
            // , opaque=""" + Guid.NewGuid().ToString().Replace("-", string.Empty) + "\""


            /* Disable the stale mechanism
             * We should really generate the responses directly in these classes.
            challenge.Append(", stale=");
            challenge.Append((bool)options[0] ? "true" : "false");
            challenge.Append("false");
             * */


            response.AddHeader("WWW-Authorize", challenge.ToString());
        }