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

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, 11 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"
9 #include "wtf/ASCIICType.h"
10 #include "wtf/NotFound.h"
11 #include "wtf/StdLibExtras.h"
12 #include "wtf/text/TextCodec.h"
13 #include "wtf/text/TextEncoding.h"
14 #include "wtf/text/TextEncodingRegistry.h"
15
16 namespace blink {
17
18 namespace {
19
20 String fromUTF8(const char* bytes, size_t size)
21 {
22 return newTextCodec(UTF8Encoding())->decode(bytes, size, WTF::DataEOF);
tyoshino (SeeGerritForStatus) 2016/01/28 07:31:44 hmm, you've chosen this approach since TextCodec i
yhirano 2016/01/28 08:45:37 Changed so that the parser keeps the codec instanc
23 }
24
25 } // namespace
26
27 void EventSourceParser::addBytes(const char* bytes, size_t size)
28 {
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 if (m_isRecognizingBOM && m_line.size() + (i - start) == WTF_ARRAY_LENGT H(kBOM)) {
33 Vector<char> line = m_line;
34 line.append(&bytes[start], i - start);
35 ASSERT(line.size() == WTF_ARRAY_LENGTH(kBOM));
36 m_isRecognizingBOM = false;
37 if (memcmp(line.data(), kBOM, sizeof(kBOM)) == 0) {
38 start = i;
39 m_line.clear();
40 continue;
41 }
42 }
43 if (m_isRecognizingCRLF && bytes[i] == '\n') {
44 // This is the latter part of "\r\n".
45 m_isRecognizingCRLF = false;
46 ++start;
47 continue;
48 }
49 m_isRecognizingCRLF = false;
50 if (bytes[i] == '\r' || bytes[i] == '\n') {
51 m_line.append(&bytes[start], i - start);
52 parseLine();
53 m_line.clear();
54 start = i + 1;
55 m_isRecognizingCRLF = bytes[i] == '\r';
56 m_isRecognizingBOM = false;
57 }
58 }
59 if (m_isStopped)
60 return;
61 m_line.append(&bytes[start], size - start);
62 }
63
64 void EventSourceParser::parseLine()
65 {
66 if (m_line.size() == 0) {
67 // We dispatch an event when seeing an empty line.
68 if (!m_data.isEmpty()) {
69 ASSERT(m_data[m_data.size() - 1] == '\n');
70 m_lastEventId = m_id;
71 String data = fromUTF8(m_data.data(), m_data.size() - 1);
72 m_client->onMessageEvent(m_event.isEmpty() ? EventTypeNames::message : m_event, data, m_lastEventId);
73 m_data.clear();
74 }
75 m_event = AtomicString();
76 return;
77 }
78 size_t fieldNameEnd = m_line.find(':');
79 size_t fieldValueStart;
80 if (fieldNameEnd == WTF::kNotFound) {
81 fieldNameEnd = m_line.size();
82 fieldValueStart = fieldNameEnd;
83 } else {
84 fieldValueStart = fieldNameEnd + 1;
85 if (fieldValueStart < m_line.size() && m_line[fieldValueStart] == ' ') {
86 ++fieldValueStart;
87 }
88 }
89 size_t fieldValueSize = m_line.size() - fieldValueStart;
90 String fieldName = fromUTF8(m_line.data(), fieldNameEnd);
91 if (fieldName == "event") {
92 m_event = AtomicString(fromUTF8(m_line.data() + fieldValueStart, fieldVa lueSize));
93 } else if (fieldName == "data") {
94 m_data.append(m_line.data() + fieldValueStart, fieldValueSize);
95 m_data.append('\n');
96 } else if (fieldName == "id") {
97 m_id = AtomicString(fromUTF8(m_line.data() + fieldValueStart, fieldValue Size));
98 } else if (fieldName == "retry") {
99 bool hasOnlyDigits = true;
100 for (size_t i = fieldValueStart; i < m_line.size() && hasOnlyDigits; ++i )
101 hasOnlyDigits = isASCIIDigit(m_line[i]);
102 if (fieldValueStart == m_line.size()) {
103 m_client->onReconnectionTimeSet(EventSource::defaultReconnectDelay);
104 } else if (hasOnlyDigits) {
105 bool ok;
106 auto reconnectionTime = fromUTF8(m_line.data() + fieldValueStart, fi eldValueSize).toUInt64(&ok);
107 if (ok)
108 m_client->onReconnectionTimeSet(reconnectionTime);
109 }
110 } else {
111 // Unrecognized field name. Ignore!
112 }
113 }
114
115 DEFINE_TRACE(EventSourceParser)
116 {
117 visitor->trace(m_client);
118 }
119
120 } // namespace blink
121
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/page/EventSourceParser.h ('k') | third_party/WebKit/Source/core/page/EventSourceParserTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698