Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: third_party/WebKit/Source/core/page/EventSourceParser.cpp

Issue 1642563002: Introduce EventSourceParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@event-source-retry-fix
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/page/EventSourceParser.h"
6
7 #include "core/EventTypeNames.h"
8 #include "core/page/EventSource.h"
tyoshino (SeeGerritForStatus) 2016/01/29 07:00:14 needed?
yhirano 2016/01/29 11:41:16 For EventSource::defaultReconnectDelay.
9 #include "wtf/ASCIICType.h"
10 #include "wtf/NotFound.h"
11 #include "wtf/StdLibExtras.h"
12 #include "wtf/text/TextEncoding.h"
13 #include "wtf/text/TextEncodingRegistry.h"
tyoshino (SeeGerritForStatus) 2016/01/29 07:00:14 add wtf/Assertions.h
yhirano 2016/01/29 11:41:16 Done.
14
15 namespace blink {
16
17 EventSourceParser::EventSourceParser(const AtomicString& lastEventId, Client* cl ient)
18 : m_id(lastEventId)
19 , m_lastEventId(lastEventId)
20 , m_client(client)
21 , m_codec(newTextCodec(UTF8Encoding()))
22 {
23 }
24
25 void EventSourceParser::addBytes(const char* bytes, size_t size)
26 {
27 // A line consists of |m_line| followed by
28 // |bytes[start..(next line break)]|.
29 size_t start = 0;
30 const unsigned char kBOM[] = {0xef, 0xbb, 0xbf};
31 for (size_t i = 0; i < size && !m_isStopped; ++i) {
32 // As kBOM contains neither CR nor LF, we can think BOM and the line
33 // break separately.
34 if (m_isRecognizingBOM && m_line.size() + (i - start) == WTF_ARRAY_LENGT H(kBOM)) {
35 Vector<char> line = m_line;
36 line.append(&bytes[start], i - start);
37 ASSERT(line.size() == WTF_ARRAY_LENGTH(kBOM));
38 m_isRecognizingBOM = false;
39 if (memcmp(line.data(), kBOM, sizeof(kBOM)) == 0) {
40 start = i;
41 m_line.clear();
42 continue;
43 }
44 }
45 if (m_isRecognizingCRLF && bytes[i] == '\n') {
46 // This is the latter part of "\r\n".
47 m_isRecognizingCRLF = false;
48 ++start;
49 continue;
50 }
51 m_isRecognizingCRLF = false;
52 if (bytes[i] == '\r' || bytes[i] == '\n') {
53 m_line.append(&bytes[start], i - start);
54 parseLine();
55 m_line.clear();
56 start = i + 1;
57 m_isRecognizingCRLF = bytes[i] == '\r';
58 m_isRecognizingBOM = false;
59 }
60 }
61 if (m_isStopped)
62 return;
63 m_line.append(&bytes[start], size - start);
64 }
65
66 void EventSourceParser::parseLine()
67 {
68 if (m_line.size() == 0) {
69 m_lastEventId = m_id;
70 // We dispatch an event when seeing an empty line.
71 if (!m_data.isEmpty()) {
72 ASSERT(m_data[m_data.size() - 1] == '\n');
73 String data = fromUTF8(m_data.data(), m_data.size() - 1);
74 m_client->onMessageEvent(m_eventType.isEmpty() ? EventTypeNames::mes sage : m_eventType, data, m_lastEventId);
75 m_data.clear();
76 }
77 m_eventType = nullAtom;
78 return;
79 }
80 size_t fieldNameEnd = m_line.find(':');
81 size_t fieldValueStart;
82 if (fieldNameEnd == WTF::kNotFound) {
83 fieldNameEnd = m_line.size();
84 fieldValueStart = fieldNameEnd;
85 } else {
86 fieldValueStart = fieldNameEnd + 1;
87 if (fieldValueStart < m_line.size() && m_line[fieldValueStart] == ' ') {
88 ++fieldValueStart;
89 }
90 }
91 size_t fieldValueSize = m_line.size() - fieldValueStart;
92 String fieldName = fromUTF8(m_line.data(), fieldNameEnd);
93 if (fieldName == "event") {
94 m_eventType = AtomicString(fromUTF8(m_line.data() + fieldValueStart, fie ldValueSize));
95 } else if (fieldName == "data") {
96 m_data.append(m_line.data() + fieldValueStart, fieldValueSize);
97 m_data.append('\n');
98 } else if (fieldName == "id") {
99 m_id = AtomicString(fromUTF8(m_line.data() + fieldValueStart, fieldValue Size));
100 } else if (fieldName == "retry") {
101 bool hasOnlyDigits = true;
102 for (size_t i = fieldValueStart; i < m_line.size() && hasOnlyDigits; ++i )
103 hasOnlyDigits = isASCIIDigit(m_line[i]);
104 if (fieldValueStart == m_line.size()) {
105 m_client->onReconnectionTimeSet(EventSource::defaultReconnectDelay);
106 } else if (hasOnlyDigits) {
107 bool ok;
108 auto reconnectionTime = fromUTF8(m_line.data() + fieldValueStart, fi eldValueSize).toUInt64Strict(&ok);
109 if (ok)
110 m_client->onReconnectionTimeSet(reconnectionTime);
111 }
112 } else {
113 // Unrecognized field name. Ignore!
114 }
115 }
116
117 String EventSourceParser::fromUTF8(const char* bytes, size_t size)
118 {
119 return m_codec->decode(bytes, size, WTF::DataEOF);
120 }
121
122 DEFINE_TRACE(EventSourceParser)
123 {
124 visitor->trace(m_client);
125 }
126
127 } // namespace blink
128
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698