Removing legacy raw format for `send`

Fixes issues #383 and #127
This commit is contained in:
moozzyk 2017-04-17 13:15:06 -07:00
parent fd7707e7d2
commit e691e1cff8
4 changed files with 55 additions and 29 deletions

View File

@ -1,24 +1,25 @@
export interface IHttpClient {
get(url: string): Promise<string>;
post(url: string, content: string): Promise<string>;
get(url: string, headers?: Map<string, string>): Promise<string>;
post(url: string, content: string, headers?: Map<string, string>): Promise<string>;
}
export class HttpClient implements IHttpClient {
get(url: string): Promise<string> {
return this.xhr("GET", url);
get(url: string, headers?: Map<string, string>): Promise<string> {
return this.xhr("GET", url, headers);
}
post(url: string, content: string): Promise<string> {
return this.xhr("POST", url, content);
post(url: string, content: string, headers?: Map<string, string>): Promise<string> {
return this.xhr("POST", url, headers, content);
}
private xhr(method: string, url: string, content?: string): Promise<string> {
private xhr(method: string, url: string, headers?: Map<string, string>, content?: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(method, url, true);
if (method === "POST" && content != null) {
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
if (headers) {
headers.forEach((value, header) => xhr.setRequestHeader(header, value));
}
xhr.send(content);

View File

@ -139,7 +139,7 @@ export class ServerSentEventsTransport implements ITransport {
}
async send(data: any): Promise<void> {
await this.httpClient.post(this.url + "/send?" + this.queryString, data);
return send(this.httpClient, `${this.url}/send?${this.queryString}`, data);
}
stop(): void {
@ -231,7 +231,7 @@ export class LongPollingTransport implements ITransport {
}
async send(data: any): Promise<void> {
await this.httpClient.post(this.url + "/send?" + this.queryString, data);
return send(this.httpClient, `${this.url}/send?${this.queryString}`, data);
}
stop(): void {
@ -245,3 +245,11 @@ export class LongPollingTransport implements ITransport {
onDataReceived: DataReceived;
onClosed: TransportClosed;
}
const headers = new Map<string, string>();
headers.set("Content-Type", "application/vnd.microsoft.aspnetcore.endpoint-messages.v1+text");
async function send(httpClient: IHttpClient, url: string, data: any): Promise<void> {
let message = `T${data.length.toString()}:T:${data};`;
await httpClient.post(url, message, headers);
}

View File

@ -338,31 +338,24 @@ namespace Microsoft.AspNetCore.Sockets
buffer = stream.ToArray();
}
IList<Message> messages;
MessageFormat messageFormat;
if (string.Equals(context.Request.ContentType, MessageFormatter.TextContentType, StringComparison.OrdinalIgnoreCase))
{
var reader = new BytesReader(buffer);
messages = ParseSendBatch(ref reader, MessageFormat.Text);
messageFormat = MessageFormat.Text;
}
else if (string.Equals(context.Request.ContentType, MessageFormatter.BinaryContentType, StringComparison.OrdinalIgnoreCase))
{
var reader = new BytesReader(buffer);
messages = ParseSendBatch(ref reader, MessageFormat.Binary);
messageFormat = MessageFormat.Binary;
}
else
{
// Legacy, single message raw format
var format =
string.Equals(context.Request.Query["format"], "binary", StringComparison.OrdinalIgnoreCase)
? MessageType.Binary
: MessageType.Text;
messages = new List<Message>()
{
new Message(buffer, format, endOfMessage: true)
};
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync($"'{context.Request.ContentType}' is not a valid Content-Type for send requests.");
return;
}
var reader = new BytesReader(buffer);
var messages = ParseSendBatch(ref reader, messageFormat);
// REVIEW: Do we want to return a specific status code here if the connection has ended?
_logger.LogDebug("Received batch of {0} message(s) in '/send'", messages.Count);
@ -449,7 +442,7 @@ namespace Microsoft.AspNetCore.Sockets
return connectionState;
}
private IList<Message> ParseSendBatch(ref BytesReader payload, MessageFormat messageFormat)
private List<Message> ParseSendBatch(ref BytesReader payload, MessageFormat messageFormat)
{
var messages = new List<Message>();

View File

@ -109,6 +109,32 @@ namespace Microsoft.AspNetCore.Sockets.Tests
}
}
[Fact]
public async Task SendRequestsWithInvalidContentTypeAreRejected()
{
var manager = CreateConnectionManager();
var connectionState = manager.CreateConnection();
var dispatcher = new HttpConnectionDispatcher(manager, new LoggerFactory());
using (var strm = new MemoryStream())
{
var context = new DefaultHttpContext();
var services = new ServiceCollection();
services.AddOptions();
services.AddEndPoint<TestEndPoint>();
context.RequestServices = services.BuildServiceProvider();
context.Request.Path = "/send";
context.Request.QueryString = new QueryString($"?id={connectionState.Connection.ConnectionId}");
context.Request.ContentType = "text/plain";
context.Response.Body = strm;
await dispatcher.ExecuteAsync<TestEndPoint>("", context);
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
await strm.FlushAsync();
Assert.Equal("'text/plain' is not a valid Content-Type for send requests.", Encoding.UTF8.GetString(strm.ToArray()));
}
}
[Theory]
[InlineData(TransportType.LongPolling, 204)]
[InlineData(TransportType.WebSockets, 404)]
@ -417,8 +443,6 @@ namespace Microsoft.AspNetCore.Sockets.Tests
}
[Theory]
[InlineData("", "text", "Hello, World", "Hello, World", MessageType.Text)] // Legacy format
[InlineData("", "binary", "Hello, World", "Hello, World", MessageType.Binary)] // Legacy format
[InlineData(TextContentType, null, "T12:T:Hello, World;", "Hello, World", MessageType.Text)]
[InlineData(TextContentType, null, "T16:B:SGVsbG8sIFdvcmxk;", "Hello, World", MessageType.Binary)]
[InlineData(TextContentType, null, "T12:E:Hello, World;", "Hello, World", MessageType.Error)]