AK: Teach URL how to parse data: URLs :^)

This commit is contained in:
Andreas Kling 2020-04-26 22:48:54 +02:00
parent da04147cf6
commit 389eb1b693
Notes: sideshowbarker 2024-07-19 07:15:39 +09:00
2 changed files with 58 additions and 3 deletions

View file

@ -54,6 +54,8 @@ bool URL::parse(const StringView& string)
InPath, InPath,
InQuery, InQuery,
InFragment, InFragment,
InDataMimeType,
InDataPayload,
}; };
Vector<char, 256> buffer; Vector<char, 256> buffer;
@ -75,30 +77,39 @@ bool URL::parse(const StringView& string)
while (index < string.length()) { while (index < string.length()) {
switch (state) { switch (state) {
case State::InProtocol: case State::InProtocol: {
if (is_valid_protocol_character(peek())) { if (is_valid_protocol_character(peek())) {
buffer.append(consume()); buffer.append(consume());
continue; continue;
} }
if (consume() != ':') if (consume() != ':')
return false; return false;
m_protocol = String::copy(buffer);
if (m_protocol == "data") {
buffer.clear();
state = State::InDataMimeType;
continue;
}
if (consume() != '/') if (consume() != '/')
return false; return false;
if (consume() != '/') if (consume() != '/')
return false; return false;
if (buffer.is_empty()) if (buffer.is_empty())
return false; return false;
m_protocol = String::copy(buffer);
if (m_protocol == "http") if (m_protocol == "http")
m_port = 80; m_port = 80;
else if (m_protocol == "https") else if (m_protocol == "https")
m_port = 443; m_port = 443;
buffer.clear();
if (m_protocol == "file") if (m_protocol == "file")
state = State::InPath; state = State::InPath;
else else
state = State::InHostname; state = State::InHostname;
buffer.clear();
continue; continue;
}
case State::InHostname: case State::InHostname:
if (is_valid_hostname_character(peek())) { if (is_valid_hostname_character(peek())) {
buffer.append(consume()); buffer.append(consume());
@ -160,6 +171,41 @@ bool URL::parse(const StringView& string)
case State::InFragment: case State::InFragment:
buffer.append(consume()); buffer.append(consume());
continue; continue;
case State::InDataMimeType: {
if (peek() != ';' && peek() != ',') {
buffer.append(consume());
continue;
}
m_data_mime_type = String::copy(buffer);
buffer.clear();
if (peek() == ';') {
consume();
if (consume() != 'b')
return false;
if (consume() != 'a')
return false;
if (consume() != 's')
return false;
if (consume() != 'e')
return false;
if (consume() != '6')
return false;
if (consume() != '4')
return false;
m_data_payload_is_base64 = true;
}
if (consume() != ',')
return false;
state = State::InDataPayload;
break;
}
case State::InDataPayload:
buffer.append(consume());
break;
} }
} }
if (state == State::InHostname) { if (state == State::InHostname) {
@ -177,6 +223,8 @@ bool URL::parse(const StringView& string)
m_query = String::copy(buffer); m_query = String::copy(buffer);
if (state == State::InFragment) if (state == State::InFragment)
m_fragment = String::copy(buffer); m_fragment = String::copy(buffer);
if (state == State::InDataPayload)
m_data_payload = String::copy(buffer);
if (m_query.is_null()) if (m_query.is_null())
m_query = ""; m_query = "";
if (m_fragment.is_null()) if (m_fragment.is_null())

View file

@ -65,6 +65,10 @@ public:
URL complete_url(const String&) const; URL complete_url(const String&) const;
bool data_payload_is_base64() const { return m_data_payload_is_base64; }
const String& data_mime_type() const { return m_data_mime_type; }
const String& data_payload() const { return m_data_payload; }
static URL create_with_url_or_path(const String& url_or_path); static URL create_with_url_or_path(const String& url_or_path);
static URL create_with_file_protocol(const String& path); static URL create_with_file_protocol(const String& path);
@ -74,11 +78,14 @@ private:
bool m_valid { false }; bool m_valid { false };
u16 m_port { 80 }; u16 m_port { 80 };
bool m_data_payload_is_base64 { false };
String m_protocol; String m_protocol;
String m_host; String m_host;
String m_path; String m_path;
String m_query; String m_query;
String m_fragment; String m_fragment;
String m_data_mime_type;
String m_data_payload;
}; };
} }