/// <summary> /// Gets the description of the given URL in a background thread. /// </summary> /// <param name="url">URL to grab.</param> /// <returns>The description from the website's meta tag.</returns> public Task <UrlResponse> AsyncGetDescription(string url) { return(Task.Run( async delegate { UrlResponse response = new UrlResponse(); try { long totalBytes; // Get the length of the file we are going to download. // Ignore if its going to be too big. // // The HEAD method is the same thing as a GET request... the only // difference being the content does not get returned. // // Check the content length first so we don't download a massive file. { HttpRequestMessage headRequest = new HttpRequestMessage(HttpMethod.Head, url); HttpResponseMessage headResponse = await this.httpClient.SendAsync(headRequest); // Set to max value if there is no content length. We'll assume the file is too big // if its trying to hide this. totalBytes = headResponse.Content.Headers.ContentLength ?? long.MaxValue; } // If th length is too big, ignore. if (totalBytes <= maxFileSize) { HttpResponseMessage getResponse = await this.httpClient.GetAsync(url); string webResponse = await getResponse.Content.ReadAsStringAsync(); HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(webResponse); HtmlNode node = doc.DocumentNode.SelectSingleNode("//title"); if (node != null) { // Issue #15: Ensure we decode characters such as < and > response.Title = WebUtility.HtmlDecode(node.InnerText); } } else { this.logger.WriteLine("Ignoring URL '{0}' whose file size is {1}", url, totalBytes); } } catch (Exception e) { this.logger.ErrorWriteLine("Error when getting response from {0}{1}{2}", url, Environment.NewLine, e.ToString()); } return response; } )); }
/// <summary> /// Handles a message from the channel. /// </summary> private async void HandleMessage(MessageHandlerArgs args) { string url; if (UrlReader.TryParseUrl(args.Message, out url)) { UrlResponse urlResponse = await this.urlReader.AsyncGetDescription(url); if (urlResponse.IsValid) { args.Writer.SendMessage( string.Format("Title: {0}", urlResponse.TitleShortened), args.Channel ); } } }