mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
AK: Teach URL how to parse data: URLs :^)
This commit is contained in:
parent
da04147cf6
commit
389eb1b693
Notes:
sideshowbarker
2024-07-19 07:15:39 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/389eb1b693d
2 changed files with 58 additions and 3 deletions
54
AK/URL.cpp
54
AK/URL.cpp
|
@ -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())
|
||||||
|
|
7
AK/URL.h
7
AK/URL.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue