//partly according to: https://williambert.online/2013/06/allow-cors-with-localhost-in-chrome/ /// <summary> /// Sets response headers to enable CORS. /// </summary> /// <param name="response">HTTP response.</param> /// <returns>Modified HTTP response.</returns> public static HttpListenerResponse WithCORS(this HttpListenerResponse response) { if (response == null) { throw new ArgumentNullException(nameof(response), "Response must not be null."); } response.WithHeader("Access-Control-Allow-Origin", "*"); response.WithHeader("Access-Control-Allow-Headers", "Cache-Control, Pragma, Accept, Origin, Authorization, Content-Type, X-Requested-With"); response.WithHeader("Access-Control-Allow-Methods", "GET, POST"); response.WithHeader("Access-Control-Allow-Credentials", "true"); return(response); }
static void fromStream(HttpListenerRequest request, HttpListenerResponse response, Stream stream, string mime) { if (request.Headers.AllKeys.Count(x => x == BYTES_RANGE_HEADER) > 1) { throw new NotSupportedException("Multiple 'Range' headers are not supported."); } int start = 0, end = (int)stream.Length - 1; //partial stream response support var rangeStr = request.Headers[BYTES_RANGE_HEADER]; if (rangeStr != null) { var range = rangeStr.Replace("bytes=", String.Empty) .Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries) .Select(x => Int32.Parse(x)) .ToArray(); start = (range.Length > 0) ? range[0] : 0; end = (range.Length > 1) ? range[1] : (int)(stream.Length - 1); response.WithHeader("Accept-Ranges", "bytes") .WithHeader("Content-Range", "bytes " + start + "-" + end + "/" + stream.Length) .WithCode(HttpStatusCode.PartialContent); response.KeepAlive = true; } //common properties response.WithContentType(mime); response.ContentLength64 = (end - start + 1); //data delivery try { stream.Position = start; stream.CopyTo(response.OutputStream, Math.Min(MAX_BUFFER_SIZE, end - start + 1)); } catch (Exception ex) when(ex is HttpListenerException) //request canceled { response.StatusCode = (int)HttpStatusCode.NoContent; } finally { stream.Close(); response.Close(); } }