public Task <EditorHttpResonseData> WebAPIProccessor(string apiParams, HttpListenerResponse response) { string filePath = IPath.Combine(BApplication.DevOpsPublishAssetsPath, PublishPipelineTools.UPLOAD_FOLDER_SUFFIX, apiParams); if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 400; response.Abort(); } else { response.StatusCode = 200; response.ContentType = "application/octet-stream"; FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } //自行处理 return(null); }
public static void WaitForConnections() { listener.Prefixes.Add("http://*:" + Port + "/"); listener.Start(); Thread iconthread = new Thread(() => createIcon(true)); iconthread.Name = "IconThread"; iconthread.Start(); while (true) { while (true) { HttpListenerContext s = listener.GetContext(); HttpListenerResponse response = s.Response; if (BanList.Contains(s.Request.RemoteEndPoint.Address.ToString())) { response.Abort(); continue; } response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, user, password"); response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); response.AppendHeader("Access-Control-Allow-Origin", "*"); response.AppendHeader("Content-Type", "text/plain;charset=UTF-8"); response.ContentEncoding = Encoding.UTF8; totalconnections++; SpawnNewClient = new Thread(() => NewClient(s)); SpawnNewClient.Start(); } } }
public bool Abort() { try { response.Abort(); return(true); } catch (Exception) { return(false); } }
public static void WriteFileChunked(this HttpListenerResponse response, string path) { if (!File.Exists(path)) { response.StatusCode = (int)HttpStatusCode.NotFound; response.WriteText($"The file '{path}' could not be found. Are you sure this is the correct url?"); return; } //Get exetension var ext = Path.GetExtension(path); response.ContentType = ContentType.FromFileExtension(ext); response.ContentEncoding = Encoding.UTF8; //Send in chunks response.SendChunked = true; //Prepare read values int bytesRead; byte[] chunk = new byte[CHUNK_SIZE]; //Do the reading try { using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BinaryReader reader = new BinaryReader(stream)) { using (Stream outputStream = response.OutputStream) { while ((bytesRead = reader.Read(chunk, 0, chunk.Length)) > 0) { outputStream.Write(chunk, 0, bytesRead); } } } } } catch (Exception e) { throw e; } finally { response.Abort(); } }
[ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementation))] // [ActiveIssue(19975, TestPlatforms.AnyUnix)] public async Task Abort_Invoke_ForciblyTerminatesConnection() { Client.Send(Factory.GetContent("1.1", "POST", null, "Give me a context, please", null, headerOnly: false)); HttpListenerContext context = await Factory.GetListener().GetContextAsync(); HttpListenerResponse response = context.Response; Stream ouputStream = response.OutputStream; response.Abort(); // Aborting the response should dispose the response. Assert.Throws <ObjectDisposedException>(() => response.ContentType = null); // The output stream should be not be disposed. // NOTE: using Assert.Throws<ObjectDisposedException>(() => ...) doesn't work here as XUnit internally // throws an ObjectDisposedException after we have caught the ObjectDisposedException. bool threwObjectDisposedException = false; try { ouputStream.Write(SimpleMessage, 0, SimpleMessage.Length); } catch (ObjectDisposedException) { threwObjectDisposedException = true; } Assert.True(threwObjectDisposedException); // The connection should be forcibly terminated. Assert.Throws <SocketException>(() => GetClientResponse(120)); // Extra calls to Abort, Close or Dispose are nops. response.Abort(); response.Close(); ((IDisposable)response).Dispose(); }
static void ReturnInternalError(HttpListenerResponse response, Exception cause) { Console.Error.WriteLine(cause); response.StatusCode = (int)HttpStatusCode.InternalServerError; response.ContentType = "text/plain"; try { using (var writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) writer.Write(cause.ToString()); response.Close(); } catch (Exception e) { Console.Error.WriteLine(e); response.Abort(); } }
public async Task Dispose_Invoke_ClosesConnection() { using (HttpListenerResponse response = await GetResponse()) { Stream ouputStream = response.OutputStream; ((IDisposable)response).Dispose(); // Aborting the response should dispose the response. Assert.Throws <ObjectDisposedException>(() => response.ContentType = null); // The output stream should be disposed. ouputStream.Write(SimpleMessage, 0, SimpleMessage.Length); // The connection should not be forcibly terminated. string clientResponse = GetClientResponse(120); Assert.NotEmpty(clientResponse); // Extra calls to Abort, Close or Dispose are nops. response.Abort(); response.Close(); ((IDisposable)response).Dispose(); } }
public void Abort() { _response.Abort(); }
public void Abort() => inner.Abort();
public override void Abort() { res.Abort(); }
//处理客户端请求 private void HandleRequest(object ctx) { HttpListenerContext context = ctx as HttpListenerContext; HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; try { string rawUrl = request.RawUrl; int paramStartIndex = rawUrl.IndexOf('?'); if (paramStartIndex > 0) { rawUrl = rawUrl.Substring(0, paramStartIndex); } else if (paramStartIndex == 0) { rawUrl = ""; } #region 网页请求 //string InputStream = ""; using (var streamReader = new StreamReader(request.InputStream)) { //InputStream = streamReader.ReadToEnd(); } string filePath = ""; if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/") { filePath = WebHomeDir + "/index.html"; // + directorySeparatorChar + "Index.html"; } else { filePath = WebHomeDir + rawUrl; //.Replace("/", directorySeparatorChar); } if (!File.Exists(filePath)) { HttpPacket packet = HttpPacketFactory.createPacket(rawUrl); if (null != packet) { packet.handlePacket(ref response, ref request); } else { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Flush(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Flush(); } #endregion } catch (Exception ex) { UnityUtility.logInfo(typeof(HttpServerManager) + ex.Message); response.StatusCode = 200; response.ContentType = "text/plain"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } } try { response.Close(); } catch (Exception ex) { UnityUtility.logInfo(typeof(HttpServerManager) + ex.Message); } }
async void GetContent_Callback(IAsyncResult ar) { listener.BeginGetContext(GetContent, listener); HttpListenerContext context = listener.EndGetContext(ar); HttpListenerRequest req = context.Request; using (HttpListenerResponse res = context.Response) { string filePath; //重定向 if (redirect_rules(req.Url.AbsolutePath)) { Console.WriteLine("ressrv: redir {0}", req.Url.AbsolutePath); filePath = conf["res_redirect_dir"].ToString() + req.Url.AbsolutePath; } else { filePath = conf["res_dir"].ToString() + req.Url.AbsolutePath; } //本地缓存 if (System.IO.File.Exists(filePath)) { //命中本地缓存 Console.WriteLine("ressrv: HitCache {0} ", req.RawUrl); try { await SendFileAsync(res, filePath); res.Close(); return; } catch (IOException e) { Console.WriteLine("ressrv: Cache IOException {0}\r\n{1}", req.RawUrl, e.Message); } } #region 请求官方 //请求官方 Console.WriteLine("ressrv: proxy {0} ", conf["official_address"] + req.RawUrl); HttpWebRequest c_req = HttpWebRequest.CreateHttp(conf["official_address"] + req.RawUrl); HttpWebResponse c_res = null; //尝试连接官方获取c_res对象 try { c_res = (HttpWebResponse)await c_req.GetResponseAsync(); } catch (WebException e) { if (e.Response != null) { HttpWebResponse e_res = (HttpWebResponse)e.Response; Console.WriteLine("ressrv: {0} {1} ", (int)e_res.StatusCode, e_res.ResponseUri); res.StatusCode = (int)e_res.StatusCode; e_res.Dispose(); } else { Console.WriteLine("ressrv: 502 {0}", e.Message); res.StatusCode = 502; } res.Close(); return; } using (c_res) { res.ContentLength64 = c_res.ContentLength; res.ContentType = c_res.ContentType; //尝试获取文件流 FileStream f_stream = null; try { string dirName = Path.GetDirectoryName(filePath); if (!Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } f_stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None); } catch (IOException) { //throw; } //start copy using (Stream c_stream = c_res.GetResponseStream(), s_stream = res.OutputStream) { try { await CopyStreamAsync(c_stream, s_stream, f_stream); //dispose f_stream if (f_stream != null) { f_stream.Close(); f_stream.Dispose(); Console.WriteLine("ressrv: Cached {0}", req.Url.AbsolutePath); } } catch (Exception e) { if (f_stream != null) { lock (FileDelete_lock) { f_stream.Close(); File.Delete(filePath); } f_stream.Dispose(); } Console.WriteLine("ressrv: Error {0}", e.Message); res.Abort(); } finally { s_stream.Close(); c_stream.Close(); } } c_res.Close(); } res.Close(); } #endregion }
//处理客户端请求 private async void HandleRequest(object ctx) { HttpListenerContext context = ctx as HttpListenerContext; HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; try { string rawUrl = System.Web.HttpUtility.UrlDecode(request.RawUrl); int paramStartIndex = rawUrl.IndexOf('?'); if (paramStartIndex > 0) { rawUrl = rawUrl.Substring(0, paramStartIndex); } else if (paramStartIndex == 0) { rawUrl = ""; } if (string.Compare(rawUrl, "/ImageUpload", true) == 0) { var result = new ResoponseResult() { Count = 0 }; var count = 0; #region 图片 using (var stream = request.InputStream) { using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, request.ContentEncoding)) { var content = await reader.ReadToEndAsync(); var param = JsonConvert.DeserializeObject <RequestParam>(content); if (param != null) { param.Images.ForEach(x => { var base64Pic = x.pic; var fileName = Guid.NewGuid().ToString("N") + "." + x.Type; string filePath = FormConfigUtil.WifiPath + "\\" + fileName; byte[] bt = Convert.FromBase64String(base64Pic.Substring(base64Pic.IndexOf(',') + 1)); var picStream = new System.IO.MemoryStream(bt); var bitmap = new Bitmap(picStream); bitmap.Save(filePath); picStream.Close(); form.PushImages(bitmap, filePath, x.Type, result); }); } } } response.ContentType = "text/html;charset=utf-8"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.Write(JsonConvert.SerializeObject(result)); } #endregion } else { #region 网页请求 string InputStream = ""; using (var streamReader = new StreamReader(request.InputStream)) { InputStream = streamReader.ReadToEnd(); } string filePath = ""; if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/") { filePath = WebHomeDir + directorySeparatorChar + "Index.html"; } else { filePath = WebHomeDir + rawUrl.Replace("/", directorySeparatorChar); } if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } #endregion } } catch (Exception ex) { response.StatusCode = 200; response.ContentType = "text/plain"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("500"); } } try { response.Close(); } catch (Exception ex) { throw; //LogHelper.WriteLog(typeof(HttpServerBLL), ex); } }
// // Summary: // Closes the connection to the client without sending a response. public void Abort() { response.Abort(); context.Close(); }
/// <summary> /// This methods is the start of incoming HTTP request handling. /// </summary> /// <param name="context"></param> public virtual void HandleRequest(HttpListenerContext context) { HttpListenerRequest request = context.Request; using (HttpListenerResponse response = context.Response) { OSHttpRequest req = new OSHttpRequest(context); OSHttpResponse resp = new OSHttpResponse(context); if (request.HttpMethod == String.Empty) // Can't handle empty requests, not wasting a thread { byte[] buffer = GetHTML500(response); response.ContentLength64 = buffer.LongLength; response.Close(buffer, true); return; } response.KeepAlive = false; string requestMethod = request.HttpMethod; string uriString = request.RawUrl; int requestStartTick = Environment.TickCount; // Will be adjusted later on. int requestEndTick = requestStartTick; IStreamedRequestHandler requestHandler = null; try { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US", true); string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); byte[] buffer = null; if ((request.ContentType == "application/xml" || request.ContentType == "text/xml") && GetXmlRPCHandler(request.RawUrl) != null) { buffer = HandleXmlRpcRequests(req, resp); } else if (TryGetStreamHandler(handlerKey, out requestHandler)) { response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. buffer = requestHandler.Handle(path, request.InputStream, req, resp); } request.InputStream.Close(); try { if (buffer != null) { if (request.ProtocolVersion.Minor == 0) { //HTTP 1.0... no chunking response.ContentLength64 = buffer.Length; using (Stream stream = response.OutputStream) { HttpServerHandlerHelpers.WriteNonChunked(stream, buffer); } } else { response.SendChunked = true; using (Stream stream = response.OutputStream) { HttpServerHandlerHelpers.WriteChunked(stream, buffer); } } //response.ContentLength64 = buffer.LongLength; response.Close(); } else { response.Close(new byte[0], true); } } catch (Exception ex) { if (!(ex is HttpListenerException) || !HttpListenerManager.IGNORE_ERROR_CODES.Contains(((HttpListenerException)ex).ErrorCode)) { MainConsole.Instance.WarnFormat( "[BASE HTTP SERVER]: HandleRequest failed to write all data to the stream: {0}", ex.ToString()); } response.Abort(); } requestEndTick = Environment.TickCount; } catch (Exception e) { MainConsole.Instance.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.ToString()); response.Abort(); } finally { // Every month or so this will wrap and give bad numbers, not really a problem // since its just for reporting int tickdiff = requestEndTick - requestStartTick; if (tickdiff > 3000 && requestHandler != null) { MainConsole.Instance.InfoFormat( "[BASE HTTP SERVER]: Slow handling of {0} {1} took {2}ms", requestMethod, uriString, tickdiff); } else if (MainConsole.Instance.IsTraceEnabled) { MainConsole.Instance.TraceFormat( "[BASE HTTP SERVER]: Handling {0} {1} took {2}ms", requestMethod, uriString, tickdiff); } } } }
public void Abort() { Response.Abort(); }
//处理客户端请求 private void HandleRequest(object ctx) { HttpListenerContext context = ctx as HttpListenerContext; HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; try { string rawUrl = Uri.UnescapeDataString(request.RawUrl); int paramStartIndex = rawUrl.IndexOf('?'); if (paramStartIndex > 0) { rawUrl = rawUrl.Substring(0, paramStartIndex); } else if (paramStartIndex == 0) { rawUrl = ""; } #region 文件请求 { string filePath = WebHomeDir + rawUrl; //替换 // var platforms = BDApplication.GetSupportPlatform(); // foreach (var platform in platforms) // { // var platformStr = BDApplication.GetPlatformPath(platform); // filePath = filePath.Replace(platformStr, platformStr + PublishPipelineTools.UPLOAD_FOLDER_SUFFIX); // } if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } #endregion } } catch (Exception ex) { response.StatusCode = 200; response.ContentType = "text/plain"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } } try { response.Close(); } catch (Exception ex) { Debug.LogError(ex); } }
/// <summary> /// Aborts the request /// </summary> /// <returns> /// itself /// </returns> public IServerResponse Abort() { _res.Abort(); return(this); }
private void Worker(object state) { HttpListenerRequest request = null; HttpListenerResponse response = null; try { var context = state as HttpListenerContext; // request = context.Request; response = context.Response; // if (request.UserLanguages != null && request.UserLanguages.Length > 0) { try { CultureInfo culture = CultureInfo.CreateSpecificCulture(request.UserLanguages[0].ToLowerInvariant().Trim()); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; } catch { } } // if (request.IsSecureConnection) { var clientCertificate = request.GetClientCertificate(); X509Chain chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.Build(clientCertificate); if (chain.ChainStatus.Length != 0) { // Invalid certificate response.StatusCode = (int)HttpStatusCode.Unauthorized; response.OutputStream.Close(); return; } } // response.Headers.Set(HttpResponseHeader.Server, "MIG WebService Gateway"); response.KeepAlive = false; // bool isAuthenticated = (request.Headers["Authorization"] != null); string remoteAddress = request.RemoteEndPoint.Address.ToString(); string logExtras = ""; // if (servicePassword == "" || isAuthenticated) //request.IsAuthenticated) { bool verified = false; // string authUser = ""; string authPass = ""; // //NOTE: context.User.Identity and request.IsAuthenticated //aren't working under MONO with this code =/ //so we proceed by manually parsing Authorization header // //HttpListenerBasicIdentity identity = null; // if (isAuthenticated) { //identity = (HttpListenerBasicIdentity)context.User.Identity; // authuser = identity.Name; // authpass = identity.Password; byte[] encodedDataAsBytes = System.Convert.FromBase64String(request.Headers["Authorization"].Split(' ')[1]); string authtoken = System.Text.Encoding.UTF8.GetString(encodedDataAsBytes); authUser = authtoken.Split(':')[0]; authPass = authtoken.Split(':')[1]; } // //TODO: complete authorization (for now with one fixed user 'admin', add multiuser support) // if (servicePassword == "" || (authUser == serviceUsername && Utility.Encryption.SHA1.GenerateHashString(authPass) == servicePassword)) { verified = true; } // if (verified) { string url = request.RawUrl.TrimStart('/').TrimStart('\\').TrimStart('.'); if (url.IndexOf("?") > 0) { url = url.Substring(0, url.IndexOf("?")); } // Check if this url is an alias url = UrlAliasCheck(url.TrimEnd('/')); // // url aliasing check if (url == "" || url.TrimEnd('/') == baseUrl.TrimEnd('/')) { // default home redirect response.Redirect("/" + baseUrl.TrimEnd('/') + "/index.html"); //TODO: find a solution for HG homepage redirect ---> ?" + new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds + "#page_control"); response.Close(); } else { var connectionWatch = Stopwatch.StartNew(); MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1} [OPEN]", response.StatusCode, request.RawUrl))); // this url is reserved for Server Sent Event stream if (url.TrimEnd('/').Equals("events")) { // TODO: move all of this to a separate function // Server sent events // NOTE: no PreProcess or PostProcess events are fired in this case //response.KeepAlive = true; response.ContentEncoding = Encoding.UTF8; response.ContentType = "text/event-stream"; response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate"); response.Headers.Set(HttpResponseHeader.Pragma, "no-cache"); response.Headers.Set("Access-Control-Allow-Origin", "*"); // 2K padding for IE var padding = ":" + new String(' ', 2048) + "\n"; byte[] paddingData = System.Text.Encoding.UTF8.GetBytes(padding); response.OutputStream.Write(paddingData, 0, paddingData.Length); byte[] retryData = System.Text.Encoding.UTF8.GetBytes("retry: 1000\n"); response.OutputStream.Write(retryData, 0, retryData.Length); DateTime lastTimeStamp = DateTime.UtcNow; var lastId = context.Request.Headers.Get("Last-Event-ID"); if (lastId == null || lastId == "") { var queryValues = HttpUtility.ParseQueryString(context.Request.Url.Query); lastId = queryValues.Get("lastEventId"); } if (lastId != null && lastId != "") { double unixTimestamp = 0; double.TryParse(lastId, NumberStyles.Float | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out unixTimestamp); if (unixTimestamp != 0) { lastTimeStamp = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); lastTimeStamp.AddSeconds(Math.Round(unixTimestamp / 1000d)); } } bool connected = true; var timeoutWatch = Stopwatch.StartNew(); while (connected) { // dirty work around for signaling new event and // avoiding locks on long socket timetout lock (sseEventToken) Monitor.Wait(sseEventToken, 1000); // safely dequeue events List <SseEvent> bufferedData; do { bufferedData = sseEventBuffer.FindAll(le => le != null && le.Timestamp.Ticks > lastTimeStamp.Ticks); if (bufferedData.Count > 0) { foreach (SseEvent entry in bufferedData) { // send events try { // The following throws an error on some mono-arm (Input string was not in the correct format) // entry.Event.UnixTimestamp.ToString("R", CultureInfo.InvariantCulture) byte[] data = System.Text.Encoding.UTF8.GetBytes("id: " + entry.Event.UnixTimestamp.ToString().Replace(",", ".") + "\ndata: " + MigService.JsonSerialize(entry.Event) + "\n\n"); response.OutputStream.Write(data, 0, data.Length); //response.OutputStream.Flush(); lastTimeStamp = entry.Timestamp; } catch (Exception e) { MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1} [ERROR: {2}]", response.StatusCode, request.RawUrl, e.Message))); connected = false; break; } } Thread.Sleep(100); } // there might be new data after sending } while (connected && bufferedData.Count > 0); // check if the remote end point is still alive every 15 seconds or so if (timeoutWatch.Elapsed.TotalSeconds > 15) { connected = connected && IsRemoteEndPointConnected(request.RemoteEndPoint); timeoutWatch.Stop(); timeoutWatch = Stopwatch.StartNew(); } } } else { try { MigClientRequest migRequest = null; if (url.StartsWith("api/")) { string message = url.Substring(url.IndexOf('/', 1) + 1); var migContext = new MigContext(ContextSource.WebServiceGateway, context); migRequest = new MigClientRequest(migContext, new MigInterfaceCommand(message)); // Disable HTTP caching response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate"); response.Headers.Set(HttpResponseHeader.Pragma, "no-cache"); response.Headers.Set(HttpResponseHeader.Expires, "0"); // Store POST data (if any) in the migRequest.RequestData field migRequest.RequestData = WebServiceUtility.ReadToEnd(request.InputStream); migRequest.RequestText = request.ContentEncoding.GetString(migRequest.RequestData); } OnPreProcessRequest(migRequest); bool requestHandled = (migRequest != null && migRequest.Handled); if (requestHandled) { SendResponseObject(context, migRequest.ResponseData); } else if (url.StartsWith(baseUrl) || baseUrl.Equals("/")) { // If request begins <base_url>, process as standard Web request string requestedFile = GetWebFilePath(url); if (!System.IO.File.Exists(requestedFile)) { response.StatusCode = (int)HttpStatusCode.NotFound; WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>"); } else { bool isText = false; if (url.ToLower().EndsWith(".js")) // || requestedurl.EndsWith(".json")) { response.ContentType = "text/javascript"; isText = true; } else if (url.ToLower().EndsWith(".css")) { response.ContentType = "text/css"; isText = true; } else if (url.ToLower().EndsWith(".zip")) { response.ContentType = "application/zip"; } else if (url.ToLower().EndsWith(".png")) { response.ContentType = "image/png"; } else if (url.ToLower().EndsWith(".jpg")) { response.ContentType = "image/jpeg"; } else if (url.ToLower().EndsWith(".gif")) { response.ContentType = "image/gif"; } else if (url.ToLower().EndsWith(".svg")) { response.ContentType = "image/svg+xml"; } else if (url.ToLower().EndsWith(".mp3")) { response.ContentType = "audio/mp3"; } else if (url.ToLower().EndsWith(".wav")) { response.ContentType = "audio/x-wav"; } else if (url.ToLower().EndsWith(".appcache")) { response.ContentType = "text/cache-manifest"; } else if (url.ToLower().EndsWith(".otf") || url.ToLower().EndsWith(".ttf") || url.ToLower().EndsWith(".woff") || url.ToLower().EndsWith(".woff2")) { response.ContentType = "application/octet-stream"; } else if (url.ToLower().EndsWith(".xml")) { response.ContentType = "text/xml"; isText = true; } else { response.ContentType = "text/html"; isText = true; } var file = new System.IO.FileInfo(requestedFile); response.ContentLength64 = file.Length; bool modified = true; if (request.Headers.AllKeys.Contains("If-Modified-Since")) { var modifiedSince = DateTime.MinValue; DateTime.TryParse(request.Headers["If-Modified-Since"], out modifiedSince); if (file.LastWriteTime.ToUniversalTime().Equals(modifiedSince)) { modified = false; } } bool disableCacheControl = HttpCacheIgnoreCheck(url); if (!modified && !disableCacheControl) { // TODO: !IMPORTANT! exclude from caching files that contains SSI tags! response.StatusCode = (int)HttpStatusCode.NotModified; //!!DISABLED!! - The following line was preventing browser to load file from cache //response.Headers.Set(HttpResponseHeader.Date, file.LastWriteTimeUtc.ToString().Replace(",", ".")); } else { response.Headers.Set(HttpResponseHeader.LastModified, file.LastWriteTimeUtc.ToString().Replace(",", ".")); if (disableCacheControl) { response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate"); response.Headers.Set(HttpResponseHeader.Pragma, "no-cache"); response.Headers.Set(HttpResponseHeader.Expires, "0"); } else { response.Headers.Set(HttpResponseHeader.CacheControl, "max-age=86400"); } // PRE PROCESS text output if (isText) { try { WebFile webFile = GetWebFile(requestedFile); response.ContentEncoding = webFile.Encoding; response.ContentType += "; charset=" + webFile.Encoding.BodyName; // We don't need to parse the content again if it's coming from the cache if (!webFile.IsCached) { string body = webFile.Content; if (requestedFile.EndsWith(".md")) { // Built-in Markdown files support body = CommonMark.CommonMarkConverter.Convert(body); // TODO: add a way to include HTML header and footer template to be appended to the // TODO: translated markdown text } else { // HTML file // replace prepocessor directives with values bool tagFound; do { tagFound = false; int ts = body.IndexOf("{include "); if (ts >= 0) { int te = body.IndexOf("}", ts); if (te > ts) { string rs = body.Substring(ts + (te - ts) + 1); string cs = body.Substring(ts, te - ts + 1); string ls = body.Substring(0, ts); // try { if (cs.StartsWith("{include ")) { string fileName = cs.Substring(9).TrimEnd('}').Trim(); fileName = GetWebFilePath(fileName); // Encoding fileEncoding = DetectWebFileEncoding(fileName); if (fileEncoding == null) { fileEncoding = defaultWebFileEncoding; } var incFile = System.IO.File.ReadAllText(fileName, fileEncoding) + rs; body = ls + incFile; } } catch { body = ls + "<h5 style=\"color:red\">Error processing '" + cs.Replace("{", "[").Replace("}", "]") + "'</h5>" + rs; } tagFound = true; } } } while (tagFound); // continue if a pre processor tag was found // {hostos} body = body.Replace("{hostos}", Environment.OSVersion.Platform.ToString()); // {filebase} body = body.Replace("{filebase}", Path.GetFileNameWithoutExtension(requestedFile)); } // update the cache content with parsing results webFile.Content = body; } // Store the cache item if the file cache is enabled if (enableFileCache) { UpdateWebFileCache(requestedFile, webFile.Content, response.ContentEncoding); } // WebServiceUtility.WriteStringToContext(context, webFile.Content); } catch (Exception ex) { // TODO: report internal mig interface error response.StatusCode = (int)HttpStatusCode.InternalServerError; WebServiceUtility.WriteStringToContext(context, ex.Message + "\n" + ex.StackTrace); MigService.Log.Error(ex); } } else { WebServiceUtility.WriteBytesToContext(context, System.IO.File.ReadAllBytes(requestedFile)); } } } requestHandled = true; } OnPostProcessRequest(migRequest); if (!requestHandled && migRequest != null && migRequest.Handled) { SendResponseObject(context, migRequest.ResponseData); } else if (!requestHandled) { response.StatusCode = (int)HttpStatusCode.NotFound; WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>"); } } catch (Exception eh) { // TODO: add error logging Console.Error.WriteLine(eh); } } connectionWatch.Stop(); logExtras = " [CLOSED AFTER " + Math.Round(connectionWatch.Elapsed.TotalSeconds, 3) + " seconds]"; } } else { response.StatusCode = (int)HttpStatusCode.Unauthorized; // this will only work in Linux (mono) //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic"); // this works both on Linux and Windows //response.AddHeader("WWW-Authenticate", "Basic"); } } else { response.StatusCode = (int)HttpStatusCode.Unauthorized; // this will only work in Linux (mono) //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic"); // this works both on Linux and Windows //response.AddHeader("WWW-Authenticate", "Basic"); } MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod.ToString(), String.Format("{0} {1}{2}", response.StatusCode, request.RawUrl, logExtras))); } catch (Exception ex) { MigService.Log.Error(ex); } finally { // // CleanUp/Dispose allocated resources // try { request.InputStream.Close(); } catch { // TODO: add logging } try { response.OutputStream.Close(); } catch { // TODO: add logging } try { response.Close(); } catch { // TODO: add logging } try { response.Abort(); } catch { // TODO: add logging } } }
private void Worker(object state) { HttpListenerRequest request = null; HttpListenerResponse response = null; try { var context = state as HttpListenerContext; // request = context.Request; response = context.Response; // if (request.UserLanguages != null && request.UserLanguages.Length > 0) { try { CultureInfo culture = CultureInfo.CreateSpecificCulture(request.UserLanguages[0].ToLowerInvariant().Trim()); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; } catch { } } // if (request.IsSecureConnection) { var clientCertificate = request.GetClientCertificate(); var chain = new X509Chain { ChainPolicy = { RevocationMode = X509RevocationMode.NoCheck } }; chain.Build(clientCertificate); if (chain.ChainStatus.Length != 0) { // Invalid certificate response.StatusCode = (int)HttpStatusCode.Unauthorized; response.OutputStream.Close(); return; } } // response.Headers.Set(HttpResponseHeader.Server, "MIG WebService Gateway"); response.KeepAlive = false; // bool requestHasAuthorizationHeader = request.Headers["Authorization"] != null; string remoteAddress = request.RemoteEndPoint.Address.ToString(); string logExtras = ""; // if (servicePassword == "" || requestHasAuthorizationHeader) //request.IsAuthenticated) { bool verified = false; // string authUser = ""; string authPass = ""; // //NOTE: context.User.Identity and request.IsAuthenticated //aren't working under MONO with this code =/ //so we proceed by manually parsing Authorization header // //HttpListenerBasicIdentity identity = null; // if (requestHasAuthorizationHeader) { //identity = (HttpListenerBasicIdentity)context.User.Identity; // authuser = identity.Name; // authpass = identity.Password; byte[] encodedDataAsBytes = Convert.FromBase64String(request.Headers["Authorization"].Split(' ')[1]); string authtoken = Encoding.UTF8.GetString(encodedDataAsBytes); authUser = authtoken.Split(':')[0]; authPass = authtoken.Split(':')[1]; } // //TODO: complete authorization (for now with one fixed user 'admin', add multiuser support) // if (servicePassword == "" || authUser == serviceUsername && Utility.Encryption.SHA1.GenerateHashString(authPass) == servicePassword) { verified = true; } // if (verified) { string url = request.RawUrl.TrimStart('/').TrimStart('\\').TrimStart('.'); if (url.IndexOf("?") > 0) { url = url.Substring(0, url.IndexOf("?")); } // Check if this url is an alias url = UrlAliasCheck(url.TrimEnd('/')); // // url aliasing check if (url == "" || url.TrimEnd('/') == baseUrl.TrimEnd('/')) { // default home redirect response.Redirect("/" + baseUrl.TrimEnd('/') + "/index.html"); //TODO: find a solution for HG homepage redirect ---> ?" + new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds + "#page_control"); response.Close(); } else { var connectionWatch = Stopwatch.StartNew(); MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod, $"{response.StatusCode} {request.RawUrl} [OPEN]")); // this url is reserved for Server Sent Event stream if (url.TrimEnd('/').Equals("events")) { HandleEventsRoute(request, response, context, remoteAddress); } else { try { MigClientRequest migRequest = null; if (url.StartsWith("api/")) { string message = url.Substring(url.IndexOf('/', 1) + 1); var migContext = new MigContext(ContextSource.WebServiceGateway, context); migRequest = new MigClientRequest(migContext, new MigInterfaceCommand(message)); // Disable HTTP caching response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate"); response.Headers.Set(HttpResponseHeader.Pragma, "no-cache"); response.Headers.Set(HttpResponseHeader.Expires, "0"); // Store POST data (if any) in the migRequest.RequestData field migRequest.RequestData = WebServiceUtility.ReadToEnd(request.InputStream); migRequest.RequestText = request.ContentEncoding.GetString(migRequest.RequestData); } OnPreProcessRequest(migRequest); bool requestHandled = migRequest != null && migRequest.Handled; if (requestHandled) { SendResponseObject(context, migRequest.ResponseData); } else if (url.StartsWith(baseUrl) || baseUrl.Equals("/")) { // If request begins <base_url>, process as standard Web request string requestedFile = GetWebFilePath(url); if (!File.Exists(requestedFile)) { response.StatusCode = (int)HttpStatusCode.NotFound; WebServiceUtility.WriteStringToContext(context, $"<h1>404 - Not Found</h1><br/>{requestedFile}"); } else { bool isText = false; if (url.ToLower().EndsWith(".js")) // || requestedurl.EndsWith(".json")) { response.ContentType = "text/javascript"; isText = true; } else if (url.ToLower().EndsWith(".css")) { response.ContentType = "text/css"; isText = true; } else if (url.ToLower().EndsWith(".zip")) { response.ContentType = "application/zip"; } else if (url.ToLower().EndsWith(".png")) { response.ContentType = "image/png"; } else if (url.ToLower().EndsWith(".jpg")) { response.ContentType = "image/jpeg"; } else if (url.ToLower().EndsWith(".gif")) { response.ContentType = "image/gif"; } else if (url.ToLower().EndsWith(".svg")) { response.ContentType = "image/svg+xml"; } else if (url.ToLower().EndsWith(".mp3")) { response.ContentType = "audio/mp3"; } else if (url.ToLower().EndsWith(".wav")) { response.ContentType = "audio/x-wav"; } else if (url.ToLower().EndsWith(".appcache")) { response.ContentType = "text/cache-manifest"; } else if (url.ToLower().EndsWith(".otf") || url.ToLower().EndsWith(".ttf") || url.ToLower().EndsWith(".woff") || url.ToLower().EndsWith(".woff2")) { response.ContentType = "application/octet-stream"; } else if (url.ToLower().EndsWith(".xml")) { response.ContentType = "text/xml"; isText = true; } else { response.ContentType = "text/html"; isText = true; } var file = new FileInfo(requestedFile); response.ContentLength64 = file.Length; bool modified = true; if (request.Headers.AllKeys.Contains("If-Modified-Since")) { var modifiedSince = DateTime.MinValue; DateTime.TryParse(request.Headers["If-Modified-Since"], out modifiedSince); if (file.LastWriteTime.ToUniversalTime().Equals(modifiedSince)) { modified = false; } } bool disableCacheControl = HttpCacheIgnoreCheck(url); if (!modified && !disableCacheControl) { // TODO: !IMPORTANT! exclude from caching files that contains SSI tags! response.StatusCode = (int)HttpStatusCode.NotModified; //!!DISABLED!! - The following line was preventing browser to load file from cache //response.Headers.Set(HttpResponseHeader.Date, file.LastWriteTimeUtc.ToString().Replace(",", ".")); } else { response.Headers.Set(HttpResponseHeader.LastModified, file.LastWriteTimeUtc.ToString().Replace(",", ".")); if (disableCacheControl) { response.Headers.Set(HttpResponseHeader.CacheControl, "no-cache, no-store, must-revalidate"); response.Headers.Set(HttpResponseHeader.Pragma, "no-cache"); response.Headers.Set(HttpResponseHeader.Expires, "0"); } else { response.Headers.Set(HttpResponseHeader.CacheControl, "max-age=86400"); } // PRE PROCESS text output if (isText) { try { WebFile webFile = GetWebFile(requestedFile); response.ContentEncoding = webFile.Encoding; response.ContentType += "; charset=" + webFile.Encoding.BodyName; // We don't need to parse the content again if it's coming from the cache if (!webFile.IsCached) { string body = webFile.Content; if (requestedFile.EndsWith(".md")) { // Built-in Markdown files support body = CommonMarkConverter.Convert(body); // TODO: add a way to include HTML header and footer template to be appended to the // TODO: translated markdown text } else { // HTML file // replace prepocessor directives with values bool tagFound; do { tagFound = false; var ts = body.IndexOf("{include "); if (ts >= 0) { var te = body.IndexOf("}", ts); if (te > ts) { var rs = body.Substring(ts + (te - ts) + 1); var cs = body.Substring(ts, te - ts + 1); var ls = body.Substring(0, ts); // try { if (cs.StartsWith("{include ")) { var fileName = cs.Substring(9).TrimEnd('}').Trim(); fileName = GetWebFilePath(fileName); var fileEncoding = DetectWebFileEncoding(fileName) ?? defaultWebFileEncoding; var incFile = File.ReadAllText(fileName, fileEncoding) + rs; body = ls + incFile; } } catch { body = ls + "<h5 style=\"color:red\">Error processing '" + cs.Replace("{", "[").Replace("}", "]") + "'</h5>" + rs; } tagFound = true; } } } while (tagFound); // continue if a pre processor tag was found // {hostos} body = body.Replace("{hostos}", Environment.OSVersion.Platform.ToString()); // {filebase} body = body.Replace("{filebase}", Path.GetFileNameWithoutExtension(requestedFile)); } // update the cache content with parsing results webFile.Content = body; } // Store the cache item if the file cache is enabled if (enableFileCache) { UpdateWebFileCache(requestedFile, webFile.Content, response.ContentEncoding); } // WebServiceUtility.WriteStringToContext(context, webFile.Content); } catch (Exception ex) { // TODO: report internal mig interface error response.StatusCode = (int)HttpStatusCode.InternalServerError; WebServiceUtility.WriteStringToContext(context, ex.Message + "\n" + ex.StackTrace); MigService.Log.Error(ex); } } else { WebServiceUtility.WriteBytesToContext(context, File.ReadAllBytes(requestedFile)); } } } requestHandled = true; } OnPostProcessRequest(migRequest); if (!requestHandled && migRequest != null && migRequest.Handled) { SendResponseObject(context, migRequest.ResponseData); } else if (!requestHandled) { response.StatusCode = (int)HttpStatusCode.NotFound; WebServiceUtility.WriteStringToContext(context, "<h1>404 - Not Found</h1>"); } } catch (Exception eh) { // TODO: add error logging Console.Error.WriteLine(eh); } } connectionWatch.Stop(); logExtras = " [CLOSED AFTER " + Math.Round(connectionWatch.Elapsed.TotalSeconds, 3) + " seconds]"; } } else { response.StatusCode = (int)HttpStatusCode.Unauthorized; // this will only work in Linux (mono) //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic"); // this works both on Linux and Windows response.AddHeader("WWW-Authenticate", "Basic realm=\"User Visible Realm\""); } } else { response.StatusCode = (int)HttpStatusCode.Unauthorized; // this will only work in Linux (mono) //response.Headers.Set(HttpResponseHeader.WwwAuthenticate, "Basic"); // this works both on Linux and Windows response.AddHeader("WWW-Authenticate", "Basic realm=\"User Visible Realm\""); } MigService.Log.Info(new MigEvent(this.GetName(), remoteAddress, "HTTP", request.HttpMethod, $"{response.StatusCode} {request.RawUrl}{logExtras}")); } catch (Exception ex) { MigService.Log.Error(ex); } finally { // // CleanUp/Dispose allocated resources // try { request.InputStream.Close(); } catch { // TODO: add logging } try { response.OutputStream.Close(); } catch { // TODO: add logging } try { response.Close(); } catch { // TODO: add logging } try { response.Abort(); } catch { // TODO: add logging } } }
/// <summary> /// Closes the connection without sending a response /// </summary> internal protected void Abort() { _httpListenerResponse.Abort(); }