]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // Licensed to the Apache Software Foundation(ASF) under one |
2 | // or more contributor license agreements.See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership.The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | using System; | |
19 | using System.Text; | |
20 | using System.Threading; | |
21 | using System.Threading.Tasks; | |
22 | using Microsoft.AspNetCore.Http; | |
23 | using Microsoft.Extensions.Logging; | |
24 | using Thrift.Processor; | |
25 | using Thrift.Protocol; | |
26 | using Thrift.Transport.Client; | |
27 | ||
28 | namespace Thrift.Transport.Server | |
29 | { | |
30 | // ReSharper disable once InconsistentNaming | |
31 | public class THttpServerTransport | |
32 | { | |
33 | protected const string ContentType = "application/x-thrift"; | |
34 | private readonly ILogger _logger; | |
35 | private readonly RequestDelegate _next; | |
36 | protected Encoding Encoding = Encoding.UTF8; | |
37 | ||
38 | protected TProtocolFactory InputProtocolFactory; | |
39 | protected TProtocolFactory OutputProtocolFactory; | |
40 | ||
41 | protected TTransportFactory InputTransportFactory; | |
42 | protected TTransportFactory OutputTransportFactory; | |
43 | ||
44 | protected ITAsyncProcessor Processor; | |
45 | ||
46 | public THttpServerTransport(ITAsyncProcessor processor, RequestDelegate next = null, ILoggerFactory loggerFactory = null) | |
47 | : this(processor, new TBinaryProtocol.Factory(), null, next, loggerFactory) | |
48 | { | |
49 | } | |
50 | ||
51 | public THttpServerTransport( | |
52 | ITAsyncProcessor processor, | |
53 | TProtocolFactory protocolFactory, | |
54 | TTransportFactory transFactory = null, | |
55 | RequestDelegate next = null, | |
56 | ILoggerFactory loggerFactory = null) | |
57 | : this(processor, protocolFactory, protocolFactory, transFactory, transFactory, next, loggerFactory) | |
58 | { | |
59 | } | |
60 | ||
61 | public THttpServerTransport( | |
62 | ITAsyncProcessor processor, | |
63 | TProtocolFactory inputProtocolFactory, | |
64 | TProtocolFactory outputProtocolFactory, | |
65 | TTransportFactory inputTransFactory = null, | |
66 | TTransportFactory outputTransFactory = null, | |
67 | RequestDelegate next = null, | |
68 | ILoggerFactory loggerFactory = null) | |
69 | { | |
70 | // loggerFactory == null is not illegal anymore | |
71 | ||
72 | Processor = processor ?? throw new ArgumentNullException(nameof(processor)); | |
73 | InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory)); | |
74 | OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory)); | |
75 | ||
76 | InputTransportFactory = inputTransFactory; | |
77 | OutputTransportFactory = outputTransFactory; | |
78 | ||
79 | _next = next; | |
80 | _logger = (loggerFactory != null) ? loggerFactory.CreateLogger<THttpServerTransport>() : new NullLogger<THttpServerTransport>(); | |
81 | } | |
82 | ||
83 | public async Task Invoke(HttpContext context) | |
84 | { | |
85 | context.Response.ContentType = ContentType; | |
86 | await ProcessRequestAsync(context, context.RequestAborted); //TODO: check for correct logic | |
87 | } | |
88 | ||
89 | public async Task ProcessRequestAsync(HttpContext context, CancellationToken cancellationToken) | |
90 | { | |
91 | var transport = new TStreamTransport(context.Request.Body, context.Response.Body); | |
92 | ||
93 | try | |
94 | { | |
95 | var intrans = (InputTransportFactory != null) ? InputTransportFactory.GetTransport(transport) : transport; | |
96 | var outtrans = (OutputTransportFactory != null) ? OutputTransportFactory.GetTransport(transport) : transport; | |
97 | ||
98 | var input = InputProtocolFactory.GetProtocol(intrans); | |
99 | var output = OutputProtocolFactory.GetProtocol(outtrans); | |
100 | ||
101 | while (await Processor.ProcessAsync(input, output, cancellationToken)) | |
102 | { | |
103 | if (!context.Response.HasStarted) // oneway method called | |
104 | await context.Response.Body.FlushAsync(cancellationToken); | |
105 | } | |
106 | } | |
107 | catch (TTransportException) | |
108 | { | |
109 | if (!context.Response.HasStarted) // if something goes bust, let the client know | |
110 | context.Response.StatusCode = 500; | |
111 | } | |
112 | finally | |
113 | { | |
114 | transport.Close(); | |
115 | } | |
116 | } | |
117 | } | |
118 | } |