-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathRestHandler.cs
More file actions
172 lines (142 loc) · 6.41 KB
/
Copy pathRestHandler.cs
File metadata and controls
172 lines (142 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using ServiceStack.Host.Handlers;
using ServiceStack.MiniProfiler;
using ServiceStack.Web;
namespace ServiceStack.Host
{
public class RestHandler
: ServiceStackHandlerBase, IRequestHttpHandler
{
public RestHandler()
{
this.HandlerAttributes = RequestAttributes.Reply;
}
public static IRestPath FindMatchingRestPath(IHttpRequest httpReq, out string contentType)
{
var pathInfo = GetSanitizedPathInfo(httpReq.PathInfo, out contentType);
return HostContext.ServiceController.GetRestPathForRequest(httpReq.HttpMethod, pathInfo, httpReq);
}
public static IRestPath FindMatchingRestPath(string httpMethod, string pathInfo, out string contentType)
{
pathInfo = GetSanitizedPathInfo(pathInfo, out contentType);
return HostContext.ServiceController.GetRestPathForRequest(httpMethod, pathInfo, null);
}
public static string GetSanitizedPathInfo(string pathInfo, out string contentType)
{
contentType = null;
if (HostContext.Config.AllowRouteContentTypeExtensions)
{
var pos = pathInfo.LastIndexOf('.');
if (pos >= 0)
{
var format = pathInfo.Substring(pos + 1);
contentType = HostContext.ContentTypes.GetFormatContentType(format);
if (contentType != null)
{
pathInfo = pathInfo.Substring(0, pos);
}
}
}
return pathInfo;
}
public IRestPath GetRestPath(IHttpRequest httpReq)
{
if (this.RestPath == null)
{
this.RestPath = FindMatchingRestPath(httpReq, out var contentType);
if (contentType != null)
ResponseContentType = contentType;
}
return this.RestPath;
}
public IRestPath RestPath { get; set; }
// Set from SSHHF.GetHandlerForPathInfo()
public string ResponseContentType { get; set; }
public override bool RunAsAsync() => true;
public override async Task ProcessRequestAsync(IRequest req, IResponse httpRes, string operationName)
{
var httpReq = (IHttpRequest) req;
try
{
var restPath = GetRestPath(httpReq);
if (restPath == null)
throw new NotSupportedException("No RestPath found for: " + httpReq.Verb + " " + httpReq.PathInfo);
httpReq.SetRoute(restPath as RestPath);
httpReq.OperationName = operationName = restPath.RequestType.GetOperationName();
if (appHost.ApplyPreRequestFilters(httpReq, httpRes))
return;
if (ResponseContentType != null)
httpReq.ResponseContentType = ResponseContentType;
appHost.AssertContentType(httpReq.ResponseContentType);
var request = httpReq.Dto = await CreateRequestAsync(httpReq, restPath);
await appHost.ApplyRequestFiltersAsync(httpReq, httpRes, request);
if (httpRes.IsClosed)
return;
var requestContentType = ContentFormat.GetEndpointAttributes(httpReq.ResponseContentType);
httpReq.RequestAttributes |= HandlerAttributes | requestContentType;
var rawResponse = await GetResponseAsync(httpReq, request);
if (httpRes.IsClosed)
return;
await HandleResponse(httpReq, httpRes, rawResponse);
}
//sync with GenericHandler
catch (TaskCanceledException)
{
httpRes.StatusCode = (int)HttpStatusCode.PartialContent;
httpRes.EndRequest();
}
catch (Exception ex)
{
if (!appHost.Config.WriteErrorsToResponse)
{
await appHost.ApplyResponseConvertersAsync(httpReq, ex);
}
else
{
await HandleException(httpReq, httpRes, operationName,
await appHost.ApplyResponseConvertersAsync(httpReq, ex) as Exception ?? ex);
}
}
}
public static async Task<object> CreateRequestAsync(IRequest httpReq, IRestPath restPath)
{
using (Profiler.Current.Step("Deserialize Request"))
{
var dtoFromBinder = GetCustomRequestFromBinder(httpReq, restPath.RequestType);
if (dtoFromBinder != null)
return await HostContext.AppHost.ApplyRequestConvertersAsync(httpReq, dtoFromBinder);
var requestParams = httpReq.GetFlattenedRequestParams();
if (Log.IsDebugEnabled)
Log.DebugFormat("CreateRequestAsync/requestParams:" + string.Join(",", requestParams.Keys));
var ret = await HostContext.AppHost.ApplyRequestConvertersAsync(httpReq,
await CreateRequestAsync(httpReq, restPath, requestParams));
return ret;
}
}
public static async Task<object> CreateRequestAsync(IRequest httpReq, IRestPath restPath, Dictionary<string, string> requestParams)
{
var requestDto = await CreateContentTypeRequestAsync(httpReq, restPath.RequestType, httpReq.ContentType);
return CreateRequest(httpReq, restPath, requestParams, requestDto);
}
public static object CreateRequest(IRequest httpReq, IRestPath restPath, Dictionary<string, string> requestParams, object requestDto)
{
var pathInfo = !restPath.IsWildCardPath
? GetSanitizedPathInfo(httpReq.PathInfo, out _)
: httpReq.PathInfo;
return restPath.CreateRequest(pathInfo, requestParams, requestDto);
}
/// <summary>
/// Used in Unit tests
/// </summary>
/// <returns></returns>
public Task<object> CreateRequestAsync(IRequest httpReq, string operationName)
{
if (this.RestPath == null)
throw new ArgumentNullException(nameof(RestPath), "No RestPath found");
return CreateRequestAsync(httpReq, this.RestPath);
}
}
}