public void TestTrackbackCreation() { EntryCollection entries = new EntryCollection(); entries = blogService.GetEntriesForDay(DateTime.MaxValue.AddDays(-2), TimeZone.CurrentTimeZone, String.Empty, int.MaxValue, int.MaxValue, String.Empty); int numberOfTrackings = 3; for (int i = 0; i < numberOfTrackings; i++) { Tracking t = new Tracking(); t.PermaLink = "http://www.foo.com/" + i; t.RefererBlogName = "Trackback " + i; t.RefererExcerpt = ""; t.RefererTitle = "Trackback " + i; t.TargetEntryId = entries[0].EntryId; t.TargetTitle = entries[0].Title; t.TrackingType = TrackingType.Trackback; blogService.AddTracking( t ); } System.Threading.Thread.Sleep(2000); TrackingCollection trackingCollection = blogService.GetTrackingsFor(entries[0].EntryId); Assert.IsTrue(trackingCollection.Count == numberOfTrackings); }
void IBlogDataService.AddTracking(Tracking tracking, params object[] actions) { ((IBlogDataService)this).RunActions(actions); lock (trackingQueue.SyncRoot) { trackingQueue.Enqueue(tracking); } trackingQueueEvent.Set(); }
private void InternalAddTracking(Tracking tracking) { bool trackFound = false; Entry entry = InternalGetEntry(tracking.TargetEntryId); if (entry == null) { StackTrace st = new StackTrace(); string logtext = String.Format("InternalAddTracking: Entry not found: {0}, {1}, {2} {3}", tracking.TrackingType, tracking.TargetTitle, tracking.TargetEntryId, st.ToString()); this.loggingService.AddEvent( new EventDataItem(EventCodes.Error, logtext, "")); return; } DayExtra extra = InternalGetDayExtra(entry.CreatedUtc); if (extra == null) { StackTrace st = new StackTrace(); string logtext = String.Format("InternalAddTracking: DayExtra not found: {0}, {1}, {2}, {3} {4}", tracking.TrackingType, tracking.TargetTitle, tracking.TargetEntryId, entry.CreatedUtc, st.ToString()); this.loggingService.AddEvent( new EventDataItem(EventCodes.Error, logtext, "")); return; } foreach (Tracking trk in extra.Trackings) { if (trk.PermaLink == tracking.PermaLink && String.Compare(trk.TargetEntryId, tracking.TargetEntryId, true) == 0 && trk.TrackingType == tracking.TrackingType) { trackFound = true; break; } } if (!trackFound) { tracking.TargetTitle = entry.Title; extra.Trackings.Add(tracking); extra.Save(data); data.IncrementExtraChange(); } }
public void ProcessRequest( HttpContext context ) { SiteConfig siteConfig = SiteConfig.GetSiteConfig(); string entryId; string title; string excerpt; string url; string blog_name; if ( !siteConfig.EnableTrackbackService ) { context.Response.StatusCode = 503; context.Response.Status = "503 Service Unavailable"; context.Response.End(); return; } // Try blocking them once, on the off chance they sent us a referrer string referrer = context.Request.UrlReferrer!=null?context.Request.UrlReferrer.AbsoluteUri:""; if (ReferralBlackList.IsBlockedReferrer(referrer)) { if (siteConfig.EnableReferralUrlBlackList404s) { context.Response.StatusCode = 404; context.Response.End(); return; } } entryId = context.Request.QueryString["guid"]; if ( context.Request.HttpMethod == "POST" ) { title = context.Request.Form["title"]; excerpt= context.Request.Form["excerpt"]; url = context.Request.Form["url"]; blog_name = context.Request.Form["blog_name"]; } /* GET is no longer in the Trackback spec. Keeping * this arround for testing. Just uncomment. else if ( context.Request.HttpMethod == "GET" ) { title = context.Request.QueryString["title"]; excerpt= context.Request.QueryString["excerpt"]; url = context.Request.QueryString["url"]; blog_name = context.Request.QueryString["blog_name"]; } */ else { context.Response.Redirect(SiteUtilities.GetStartPageUrl(siteConfig)); return; } if ( url != null && url.Length > 0 ) { try { // First line of defense, try blocking again with the URL they are tracking us back with if (ReferralBlackList.IsBlockedReferrer(url)) { if (siteConfig.EnableReferralUrlBlackList404s) { context.Response.StatusCode = 404; context.Response.End(); return; } } ILoggingDataService logService = LoggingDataServiceFactory.GetService(SiteConfig.GetLogPathFromCurrentContext()); IBlogDataService dataService = BlogDataServiceFactory.GetService(SiteConfig.GetContentPathFromCurrentContext(),logService ); Entry entry = dataService.GetEntry( entryId ); if ( entry != null ) { try { string requestBody = null; // see if this is a spammer HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest; webRequest.Method="GET"; webRequest.UserAgent = SiteUtilities.GetUserAgent(); HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse; // now we want to get the page contents of the target body using (StreamReader requestReader = new StreamReader(response.GetResponseStream())) { requestBody = requestReader.ReadToEnd(); } response.Close(); // the source URL in the page could be URL encoded like the ClickThroughHandler does string urlEncodedBaseUrl = HttpUtility.UrlEncode(SiteUtilities.GetBaseUrl()); // check to see if the source's page contains a link to us if (Regex.Match(requestBody, SiteUtilities.GetBaseUrl()).Success == false && Regex.Match(requestBody, urlEncodedBaseUrl).Success == false) { logService.AddEvent(new EventDataItem( EventCodes.TrackbackBlocked, context.Request.UserHostAddress + " because it did not contain a link", SiteUtilities.GetPermaLinkUrl(entryId), url, entry.Title )); context.Response.StatusCode = 404; context.Response.End(); return; } } catch { // trackback url is not even alive logService.AddEvent(new EventDataItem( EventCodes.TrackbackBlocked, context.Request.UserHostAddress + " because the server did not return a valid response", SiteUtilities.GetPermaLinkUrl(entryId), url, entry.Title )); context.Response.StatusCode = 404; context.Response.End(); return; } // if we've gotten this far, the trackback is real and valid Tracking t = new Tracking(); t.PermaLink = url; t.Referer = context.Request.UrlReferrer != null ? context.Request.UrlReferrer.ToString() : String.Empty; t.RefererBlogName = blog_name; t.RefererExcerpt = excerpt; t.RefererTitle = title; t.RefererIPAddress = context.Request.UserHostAddress; t.TargetEntryId = entryId; t.TargetTitle = entry.Title; t.TrackingType = TrackingType.Trackback; ISpamBlockingService spamBlockingService = siteConfig.SpamBlockingService; if (spamBlockingService != null) { bool isSpam = false; try { isSpam = spamBlockingService.IsSpam(t); } catch(Exception ex) { logService.AddEvent(new EventDataItem(EventCodes.Error, String.Format("The external spam blocking service failed for trackback from {0}. Original exception: {1}", t.PermaLink, ex), SiteUtilities.GetPermaLinkUrl(entryId))); } if (isSpam) { //TODO: maybe we can add a configuration option to moderate trackbacks. // For now, we'll just avoid saving suspected spam logService.AddEvent(new EventDataItem( EventCodes.TrackbackBlocked, context.Request.UserHostAddress + " because it was considered spam by the external blocking service.", SiteUtilities.GetPermaLinkUrl(entryId), url, entry.Title )); context.Response.StatusCode = 404; context.Response.End(); return; } } if ( siteConfig.SendTrackbacksByEmail && siteConfig.SmtpServer != null && siteConfig.SmtpServer.Length > 0 ) { MailMessage emailMessage = new MailMessage(); if ( siteConfig.NotificationEMailAddress != null && siteConfig.NotificationEMailAddress.Length > 0 ) { emailMessage.To.Add(siteConfig.NotificationEMailAddress); } else { emailMessage.To.Add(siteConfig.Contact); } emailMessage.Subject = String.Format("Weblog trackback by '{0}' on '{1}'", t.PermaLink, t.TargetTitle); emailMessage.Body = String.Format("You were tracked back from\n{0}\r\non your weblog entry '{1}'\n({2}\r\n\r\nDelete Trackback: {3})", t.PermaLink, t.TargetTitle, SiteUtilities.GetPermaLinkUrl(entryId), SiteUtilities.GetTrackbackDeleteUrl(entryId, t.PermaLink, t.TrackingType)); emailMessage.IsBodyHtml = false; emailMessage.BodyEncoding = System.Text.Encoding.UTF8; emailMessage.From = new MailAddress(siteConfig.Contact); SendMailInfo sendMailInfo = new SendMailInfo(emailMessage, siteConfig.SmtpServer, siteConfig.EnableSmtpAuthentication, siteConfig.UseSSLForSMTP, siteConfig.SmtpUserName, siteConfig.SmtpPassword, siteConfig.SmtpPort); dataService.AddTracking(t, sendMailInfo ); } else { dataService.AddTracking( t ); } logService.AddEvent( new EventDataItem( EventCodes.TrackbackReceived, entry.Title, SiteUtilities.GetPermaLinkUrl(entryId), url)); // return the correct Trackback response // http://www.movabletype.org/docs/mttrackback.html context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>0</error></response>"); return; } } catch (System.Threading.ThreadAbortException ex) { // absorb ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,ex); return; } catch( Exception exc ) { // absorb ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,exc); // return the correct Trackback response // http://www.movabletype.org/docs/mttrackback.html context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>1</error><message>" + exc.ToString() + "</message></response>"); return; } } if ( entryId != null && entryId.Length > 0 ) { context.Response.Redirect(SiteUtilities.GetPermaLinkUrl(siteConfig,entryId)); } else { context.Response.Redirect(SiteUtilities.GetStartPageUrl(siteConfig)); } }
public string ping( string sourceUri, string targetUri) { if ( !siteConfig.EnablePingbackService ) { throw new ServiceDisabledException(); } string returnValue="0"; if (ReferralBlackList.IsBlockedReferrer(sourceUri)) { if (siteConfig.EnableReferralUrlBlackList404s) { this.Context.Response.StatusCode = 404; this.Context.Response.End(); throw new XmlRpcFaultException(404, "not found"); } } try { string entryId=null; // OmarS: need to rewrite the URL so w can find the entryId Uri uriTargetUri = new Uri( SiteUtilities.MapUrl(targetUri) ); string query = uriTargetUri.Query; if ( query.Length>0 && query[0]=='?') { query = query.Substring(1); } else { return returnValue; } string[] queryItems = query.Split('&'); if ( queryItems == null ) return returnValue; foreach( string queryItem in queryItems ) { string[] keyvalue = queryItem.Split('='); if ( keyvalue.Length==2) { string key=keyvalue[0]; string @value=keyvalue[1]; if ( key == "guid") { entryId = @value; break; } } } if ( entryId != null ) { Entry entry = dataService.GetEntry(entryId); if ( entry != null ) { Tracking t = new Tracking(); t.PermaLink = sourceUri; t.Referer = this.Context.Request.UrlReferrer != null ? this.Context.Request.UrlReferrer.ToString() : String.Empty; t.RefererBlogName = sourceUri; t.RefererExcerpt = String.Empty; t.RefererTitle = sourceUri; t.TargetEntryId = entryId; t.TargetTitle = entry.Title; t.TrackingType = TrackingType.Pingback; t.RefererIPAddress = this.Context.Request.UserHostAddress; ISpamBlockingService spamBlockingService = siteConfig.SpamBlockingService; if (spamBlockingService != null) { bool isSpam = false; try { isSpam = spamBlockingService.IsSpam(t); } catch(Exception ex) { logDataService.AddEvent(new EventDataItem(EventCodes.Error, String.Format("The external spam blocking service failed for pingback from {0}. Original exception: {1}", sourceUri, ex), targetUri)); } if (isSpam) { //TODO: May provide moderation in the future. For now we just ignore the pingback logDataService.AddEvent(new EventDataItem( EventCodes.PingbackBlocked, "Pingback blocked from " + sourceUri + " because it was considered spam by the external blocking service.", targetUri, sourceUri)); System.Web.HttpContext.Current.Response.StatusCode = 404; System.Web.HttpContext.Current.Response.End(); throw new XmlRpcFaultException(404, "not found"); } } if ( siteConfig.SendPingbacksByEmail && siteConfig.SmtpServer != null && siteConfig.SmtpServer.Length > 0 ) { MailMessage emailMessage = new MailMessage(); if ( siteConfig.NotificationEMailAddress != null && siteConfig.NotificationEMailAddress.Length > 0 ) { emailMessage.To.Add(siteConfig.NotificationEMailAddress); } else { emailMessage.To.Add(siteConfig.Contact); } emailMessage.Subject = String.Format("Weblog pingback by '{0}' on '{1}'", sourceUri, t.TargetTitle); emailMessage.Body = String.Format("You were pinged back by\n{0}\r\non your weblog entry '{1}'\n({2}\r\n\r\nDelete Trackback: {3})", sourceUri, t.TargetTitle, SiteUtilities.GetPermaLinkUrl(entry), SiteUtilities.GetTrackbackDeleteUrl(entryId, t.PermaLink, t.TrackingType)); emailMessage.IsBodyHtml = false; emailMessage.BodyEncoding = System.Text.Encoding.UTF8; emailMessage.From = new MailAddress(siteConfig.Contact); SendMailInfo sendMailInfo = new SendMailInfo(emailMessage, siteConfig.SmtpServer, siteConfig.EnableSmtpAuthentication, siteConfig.UseSSLForSMTP, siteConfig.SmtpUserName, siteConfig.SmtpPassword, siteConfig.SmtpPort); dataService.AddTracking(t, sendMailInfo ); } else { dataService.AddTracking(t); } logDataService.AddEvent( new EventDataItem(EventCodes.PingbackReceived,entry.Title,targetUri,sourceUri)); returnValue = sourceUri; } } } catch( Exception e ) { ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,e); return "0"; } return returnValue; }