/// <summary> /// Keep polling until /// </summary> private void PollThread() { m_curPoll = m_minPoll; m_id = null; MemoryStream ms = new MemoryStream(); CookieContainer cookies = new CookieContainer(5); byte[] readbuf = new byte[1024]; Stream rs; byte[] buf; HttpWebResponse resp; HttpWebRequest req; Stream s; WriteBuf start; while (m_running) { lock (m_lock) { if (m_writeQ.Count == 0) { Monitor.Wait(m_lock, (int)(m_curPoll * 1000.0)); } } // did we get closed? if (!m_running) { break; } if (m_id == null) { GenKeys(); start = new WriteBuf(string.Format("0;{0},", m_keys[m_curKey])); } else { if (m_curKey == 0) { string k = m_keys[0]; GenKeys(); start = new WriteBuf(string.Format("{0};{1};{2},", m_id, k, m_keys[m_curKey])); } else { start = new WriteBuf(string.Format("{0};{1},", m_id, m_keys[m_curKey])); } } m_curKey--; ms.SetLength(0); int count = start.len; while (m_writeQ.Count > 0) { WriteBuf b = (WriteBuf)m_writeQ.Dequeue(); count += b.len; ms.Write(b.buf, b.offset, b.len); } POLL: req = (HttpWebRequest)WebRequest.Create(m_url); req.CookieContainer = cookies; req.ContentType = CONTENT_TYPE; req.Method = METHOD; if (m_cert != null) { req.ClientCertificates.Add(m_cert); } req.KeepAlive = false; req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore); req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore); if (m_proxy != null) { req.Proxy = m_proxy; } req.ContentLength = count; try { ServicePointManager.ServerCertificateValidationCallback = ValidateRemoteCertificate; s = req.GetRequestStream(); s.Write(start.buf, start.offset, start.len); m_remote_cert = req.ServicePoint.Certificate; buf = ms.ToArray(); s.Write(buf, 0, buf.Length); s.Close(); resp = (HttpWebResponse)req.GetResponse(); } catch (WebException ex) { if (ex.Status != WebExceptionStatus.KeepAliveFailure) { m_listener.OnError(this, ex); return; } goto POLL; } if (resp.StatusCode != HttpStatusCode.OK) { m_listener.OnError(this, new WebException("Invalid HTTP return code: " + resp.StatusCode)); return; } CookieCollection cc = resp.Cookies; Debug.Assert(cc != null); Cookie c = cc["ID"]; if ((c == null) || (c.Value == null)) { m_listener.OnError(this, new WebException("No ID cookie returned")); return; } if (m_id == null) { // if ID ends in :0, it's an error if (!c.Value.EndsWith(":0")) { m_id = c.Value; } } if (m_id != c.Value) { switch (c.Value) { case "0:0": m_listener.OnError(this, new XEP25Exception("Unknown XEP25 error")); return; case "-1:0": m_listener.OnError(this, new XEP25Exception("Server error")); return; case "-2:0": m_listener.OnError(this, new XEP25Exception("Bad request")); return; case "-3:0": m_listener.OnError(this, new XEP25Exception("Key sequence error")); return; default: m_listener.OnError(this, new WebException("ID cookie changed")); return; } } if (ms.Length > 0) { m_listener.OnWrite(this, buf, 0, buf.Length); } ms.SetLength(0); rs = resp.GetResponseStream(); int readlen; while ((readlen = rs.Read(readbuf, 0, readbuf.Length)) > 0) { ms.Write(readbuf, 0, readlen); } rs.Close(); if (ms.Length > 0) { buf = ms.ToArray(); try { if (!m_listener.OnRead(this, buf, 0, buf.Length)) { Close(); return; } } catch (NullReferenceException) {} m_curPoll = m_minPoll; } else { m_curPoll *= 1.25; if (m_curPoll > m_maxPoll) { m_curPoll = m_maxPoll; } } } }
/// <summary> /// Keep polling until /// </summary> private void PollThread() { m_curPoll = m_minPoll; m_id = null; MemoryStream ms = new MemoryStream(); CookieContainer cookies = new CookieContainer(5); byte[] readbuf = new byte[1024]; Stream rs; byte[] buf; HttpWebResponse resp; HttpWebRequest req; Stream s; WriteBuf start; while (m_running) { lock (m_lock) { if (m_writeQ.Count == 0) { Monitor.Wait(m_lock, (int)(m_curPoll * 1000.0)); } } // did we get closed? if (!m_running) break; if (m_id == null) { GenKeys(); start = new WriteBuf(string.Format("0;{0},", m_keys[m_curKey])); } else { if (m_curKey == 0) { string k = m_keys[0]; GenKeys(); start = new WriteBuf(string.Format("{0};{1};{2},", m_id, k, m_keys[m_curKey])); } else { start = new WriteBuf(string.Format("{0};{1},", m_id, m_keys[m_curKey])); } } m_curKey--; ms.SetLength(0); int count = start.len; while (m_writeQ.Count > 0) { WriteBuf b = (WriteBuf) m_writeQ.Dequeue(); count += b.len; ms.Write(b.buf, b.offset, b.len); } POLL: req = (HttpWebRequest)WebRequest.Create(m_url); req.CookieContainer = cookies; req.ContentType = CONTENT_TYPE; req.Method = METHOD; if (m_cert != null) req.ClientCertificates.Add(m_cert); req.KeepAlive = false; req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore); req.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore); if (m_proxy != null) req.Proxy = m_proxy; req.ContentLength = count; try { ServicePointManager.ServerCertificateValidationCallback = ValidateRemoteCertificate; s = req.GetRequestStream(); s.Write(start.buf, start.offset, start.len); m_remote_cert = req.ServicePoint.Certificate; buf = ms.ToArray(); s.Write(buf, 0, buf.Length); s.Close(); resp = (HttpWebResponse) req.GetResponse(); } catch (WebException ex) { if (ex.Status != WebExceptionStatus.KeepAliveFailure) { m_listener.OnError(this, ex); return; } goto POLL; } if (resp.StatusCode != HttpStatusCode.OK) { m_listener.OnError(this, new WebException("Invalid HTTP return code: " + resp.StatusCode)); return; } CookieCollection cc = resp.Cookies; Debug.Assert(cc != null); Cookie c = cc["ID"]; if ((c == null) || (c.Value == null)) { m_listener.OnError(this, new WebException("No ID cookie returned")); return; } if (m_id == null) { // if ID ends in :0, it's an error if (!c.Value.EndsWith(":0")) m_id = c.Value; } if (m_id != c.Value) { switch (c.Value) { case "0:0": m_listener.OnError(this, new XEP25Exception("Unknown XEP25 error")); return; case "-1:0": m_listener.OnError(this, new XEP25Exception("Server error")); return; case "-2:0": m_listener.OnError(this, new XEP25Exception("Bad request")); return; case "-3:0": m_listener.OnError(this, new XEP25Exception("Key sequence error")); return; default: m_listener.OnError(this, new WebException("ID cookie changed")); return; } } if (ms.Length > 0) { m_listener.OnWrite(this, buf, 0, buf.Length); } ms.SetLength(0); rs = resp.GetResponseStream(); int readlen; while ((readlen = rs.Read(readbuf, 0, readbuf.Length)) > 0) { ms.Write(readbuf, 0, readlen); } rs.Close(); if (ms.Length > 0) { buf = ms.ToArray(); try { if (!m_listener.OnRead(this, buf, 0, buf.Length)) { Close(); return; } } catch (NullReferenceException) {} m_curPoll = m_minPoll; } else { m_curPoll *= 1.25; if (m_curPoll > m_maxPoll) m_curPoll = m_maxPoll; } } }