502 lines
19 KiB
C#
502 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
using Newtonsoft.Json;
|
|
using System.IO.Compression;
|
|
using System.IO.Pipes;
|
|
|
|
namespace MontoyaTech.Rest.Net
|
|
{
|
|
/// <summary>
|
|
/// A set of extensions to help with HttpListenerResponses.
|
|
/// </summary>
|
|
public static class HttpListenerResponseExtensions
|
|
{
|
|
/// <summary>
|
|
/// Sets the response to have no body.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public static HttpListenerResponse WithNoBody(this HttpListenerResponse response)
|
|
{
|
|
response.ContentLength64 = 0;
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to text and writes the given text to it.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="text"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithText(this HttpListenerResponse response, string text)
|
|
{
|
|
response.ContentType = "text/plain; charset=utf-8";
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(text);
|
|
|
|
response.ContentLength64 = bytes.Length;
|
|
|
|
response.OutputStream.Write(bytes, 0, bytes.Length);
|
|
|
|
response.OutputStream.Dispose();
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to text and writes the given text compressed to it.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="text"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCompressedText(this HttpListenerResponse response, string text)
|
|
{
|
|
response.ContentType = "text/plain; charset=utf-8";
|
|
|
|
response.Headers.Add("Content-Encoding", "gzip");
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(text);
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
using (var compressedStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
|
|
compressedStream.Write(bytes, 0, bytes.Length);
|
|
|
|
response.ContentLength64 = memoryStream.Length;
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
memoryStream.CopyTo(response.OutputStream);
|
|
|
|
response.OutputStream.Dispose();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to json and serializes the object as json and writes it.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="obj"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithJson(this HttpListenerResponse response, object obj)
|
|
{
|
|
response.ContentType = "application/json; charset=utf-8";
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
|
|
|
|
response.ContentLength64 = bytes.Length;
|
|
|
|
response.OutputStream.Write(bytes, 0, bytes.Length);
|
|
|
|
response.OutputStream.Dispose();
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to json and writes the given json compressed to it.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="obj"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCompressedJson(this HttpListenerResponse response, object obj)
|
|
{
|
|
response.ContentType = "application/json; charset=utf-8";
|
|
response.Headers.Add("Content-Encoding", "gzip");
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
using (var compressedStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
|
|
compressedStream.Write(bytes, 0, bytes.Length);
|
|
|
|
response.ContentLength64 = memoryStream.Length;
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
memoryStream.CopyTo(response.OutputStream);
|
|
|
|
response.OutputStream.Dispose();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to a file and writes the given file content to the response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="filePath">The path of the file to send.</param>
|
|
/// <param name="mimeType">The mime type of the file to send, if null, it will be auto detected if possible.</param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithFile(this HttpListenerResponse response, string filePath, string mimeType = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("filePath must not be null or empty");
|
|
|
|
if (string.IsNullOrWhiteSpace(mimeType))
|
|
mimeType = Path.GetExtension(filePath).GetMimeType();
|
|
|
|
response.ContentType = mimeType;
|
|
response.Headers.Add("Content-Deposition", $@"attachment; filename=""{Path.GetFileName(filePath)}""");
|
|
|
|
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
|
{
|
|
response.ContentLength64 = fileStream.Length;
|
|
|
|
fileStream.CopyTo(response.OutputStream);
|
|
|
|
response.OutputStream.Dispose();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to a file and writes the file content with name to the response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="filePath"></param>
|
|
/// <param name="content"></param>
|
|
/// <param name="mimeType"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public static HttpListenerResponse WithFile(this HttpListenerResponse response, string filePath, byte[] content, string mimeType = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("filePath must not be null or empty");
|
|
|
|
if (string.IsNullOrWhiteSpace(mimeType))
|
|
mimeType = Path.GetExtension(filePath).GetMimeType();
|
|
|
|
response.ContentType = mimeType;
|
|
response.Headers.Add("Content-Deposition", $@"attachment; filename=""{Path.GetFileName(filePath)}""");
|
|
response.ContentLength64 = content.Length;
|
|
|
|
response.OutputStream.Write(content, 0, content.Length);
|
|
|
|
response.OutputStream.Dispose();
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to a file and compresses the given file content to the response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="filePath">The path of the file to send.</param>
|
|
/// <param name="mimeType">The mime type of the file to send, if null, it will be auto detected if possible.</param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCompressedFile(this HttpListenerResponse response, string filePath, string mimeType = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("filePath must not be null or empty");
|
|
|
|
if (string.IsNullOrWhiteSpace(mimeType))
|
|
mimeType = Path.GetExtension(filePath).GetMimeType();
|
|
|
|
response.ContentType = mimeType;
|
|
response.Headers.Add("Content-Deposition", $@"attachment; filename=""{Path.GetFileName(filePath)}""");
|
|
response.Headers.Add("Content-Encoding", "gzip");
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
using (var compressedStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
|
|
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
|
fileStream.CopyTo(compressedStream);
|
|
|
|
response.ContentLength64 = memoryStream.Length;
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
memoryStream.CopyTo(response.OutputStream);
|
|
|
|
response.OutputStream.Dispose();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to a file and writes the file content with name to the response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="filePath"></param>
|
|
/// <param name="content"></param>
|
|
/// <param name="mimeType"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public static HttpListenerResponse WithCompressedFile(this HttpListenerResponse response, string filePath, byte[] content, string mimeType = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("filePath must not be null or empty");
|
|
|
|
if (string.IsNullOrWhiteSpace(mimeType))
|
|
mimeType = Path.GetExtension(filePath).GetMimeType();
|
|
|
|
response.ContentType = mimeType;
|
|
response.Headers.Add("Content-Deposition", $@"attachment; filename=""{Path.GetFileName(filePath)}""");
|
|
response.Headers.Add("Content-Encoding", "gzip");
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
using (var compressedStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
|
|
compressedStream.Write(content, 0, content.Length);
|
|
|
|
response.ContentLength64 = memoryStream.Length;
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
memoryStream.CopyTo(response.OutputStream);
|
|
|
|
response.OutputStream.Dispose();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to a precompressed file and writes the file contents to the response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="filePath"></param>
|
|
/// <param name="content"></param>
|
|
/// <param name="mimeType"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public static HttpListenerResponse WithPreCompressedFile(this HttpListenerResponse response, string filePath, byte[] content, string mimeType = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("filePath must not be null or empty");
|
|
|
|
if (string.IsNullOrWhiteSpace(mimeType))
|
|
mimeType = Path.GetExtension(filePath).GetMimeType();
|
|
|
|
response.ContentType = mimeType;
|
|
response.Headers.Add("Content-Deposition", $@"attachment; filename=""{Path.GetFileName(filePath)}""");
|
|
response.Headers.Add("Content-Encoding", "gzip");
|
|
response.ContentLength64 = content.Length;
|
|
|
|
response.OutputStream.Write(content, 0, content.Length);
|
|
|
|
response.OutputStream.Dispose();
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response content type to html and writes the given html to it.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="html"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithHtml(this HttpListenerResponse response, string html)
|
|
{
|
|
response.ContentType = "text/html; charset=utf-8";
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(html);
|
|
|
|
response.ContentLength64 = bytes.Length;
|
|
|
|
response.OutputStream.Write(bytes, 0, bytes.Length);
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the status code for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="status"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithStatus(this HttpListenerResponse response, HttpStatusCode status)
|
|
{
|
|
try
|
|
{
|
|
response.StatusCode = (int)status;
|
|
return response;
|
|
}
|
|
catch
|
|
{
|
|
return response;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name">The name of the cookie</param>
|
|
/// <param name="value">The value of the cookie</param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, string name, string value)
|
|
{
|
|
response.SetCookie(new Cookie(name, value));
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="expires"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, string name, string value, DateTime expires)
|
|
{
|
|
response.SetCookie(new Cookie(name, value) { Expires = expires });
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="httpOnly"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, string name, string value, bool httpOnly)
|
|
{
|
|
response.SetCookie(new Cookie(name, value) { HttpOnly = httpOnly });
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="httpOnly"></param>
|
|
/// <param name="secure"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, string name, string value, bool httpOnly, bool secure)
|
|
{
|
|
response.SetCookie(new Cookie(name, value) { HttpOnly = httpOnly, Secure = secure });
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="httpOnly"></param>
|
|
/// <param name="secure"></param>
|
|
/// <param name="expires"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, string name, string value, bool httpOnly, bool secure, DateTime expires)
|
|
{
|
|
response.SetCookie(new Cookie(name, value) { HttpOnly = httpOnly, Secure = secure, Expires = expires });
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a cookie for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="cookie"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithCookie(this HttpListenerResponse response, Cookie cookie)
|
|
{
|
|
response.SetCookie(cookie);
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a header for a given response.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithHeader(this HttpListenerResponse response, string name, string value)
|
|
{
|
|
response.AddHeader(name, value);
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the status code for a given response to redirect with the url to redirect to.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="url"></param>
|
|
/// <returns>This response.</returns>
|
|
public static HttpListenerResponse WithRedirect(this HttpListenerResponse response, string url)
|
|
{
|
|
try
|
|
{
|
|
response.StatusCode = (int)HttpStatusCode.Redirect;
|
|
|
|
response.AddHeader("Location", url);
|
|
|
|
return response;
|
|
}
|
|
catch
|
|
{
|
|
return response;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response to bad request with a text message saying the request was null or empty.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public static HttpListenerResponse BadRequestNull(this HttpListenerResponse response)
|
|
{
|
|
return response.WithStatus(HttpStatusCode.BadRequest).WithText("Request was null or empty.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response to a bad request with a text message saying the request was invalid.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public static HttpListenerResponse BadRequestInvalid(this HttpListenerResponse response)
|
|
{
|
|
return response.WithStatus(HttpStatusCode.BadRequest).WithText("Request data was invalid.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response to a bad request with a text message saying the request was out of range.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public static HttpListenerResponse BadRequestOutOfRange(this HttpListenerResponse response)
|
|
{
|
|
return response.WithStatus(HttpStatusCode.BadRequest).WithText("Request data was out of range");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the response to a bad request with a text message saying a field in the request was out of range.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="fieldName"></param>
|
|
/// <returns></returns>
|
|
public static HttpListenerResponse BadRequestOutOfRange(this HttpListenerResponse response, string fieldName)
|
|
{
|
|
return response.WithStatus(HttpStatusCode.BadRequest).WithText($"{fieldName} in request is out of range.");
|
|
}
|
|
}
|
|
}
|