diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/examples/peerconnection/server/main.cc | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/examples/peerconnection/server/main.cc')
-rw-r--r-- | third_party/libwebrtc/examples/peerconnection/server/main.cc | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/third_party/libwebrtc/examples/peerconnection/server/main.cc b/third_party/libwebrtc/examples/peerconnection/server/main.cc new file mode 100644 index 0000000000..50b8c23401 --- /dev/null +++ b/third_party/libwebrtc/examples/peerconnection/server/main.cc @@ -0,0 +1,193 @@ +/* + * Copyright 2011 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdio.h> +#include <stdlib.h> +#if defined(WEBRTC_POSIX) +#include <sys/select.h> +#endif +#include <time.h> + +#include <string> +#include <vector> + +#include "absl/flags/flag.h" +#include "absl/flags/parse.h" +#include "absl/flags/usage.h" +#include "examples/peerconnection/server/data_socket.h" +#include "examples/peerconnection/server/peer_channel.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" +#include "test/field_trial.h" + +ABSL_FLAG( + std::string, + force_fieldtrials, + "", + "Field trials control experimental features. This flag specifies the field " + "trials in effect. E.g. running with " + "--force_fieldtrials=WebRTC-FooFeature/Enabled/ " + "will assign the group Enabled to field trial WebRTC-FooFeature. Multiple " + "trials are separated by \"/\""); +ABSL_FLAG(int, port, 8888, "default: 8888"); + +static const size_t kMaxConnections = (FD_SETSIZE - 2); + +void HandleBrowserRequest(DataSocket* ds, bool* quit) { + RTC_DCHECK(ds && ds->valid()); + RTC_DCHECK(quit); + + const std::string& path = ds->request_path(); + + *quit = (path.compare("/quit") == 0); + + if (*quit) { + ds->Send("200 OK", true, "text/html", "", + "<html><body>Quitting...</body></html>"); + } else if (ds->method() == DataSocket::OPTIONS) { + // We'll get this when a browsers do cross-resource-sharing requests. + // The headers to allow cross-origin script support will be set inside + // Send. + ds->Send("200 OK", true, "", "", ""); + } else { + // Here we could write some useful output back to the browser depending on + // the path. + printf("Received an invalid request: %s\n", ds->request_path().c_str()); + ds->Send("500 Sorry", true, "text/html", "", + "<html><body>Sorry, not yet implemented</body></html>"); + } +} + +int main(int argc, char* argv[]) { + absl::SetProgramUsageMessage( + "Example usage: ./peerconnection_server --port=8888\n"); + absl::ParseCommandLine(argc, argv); + + // InitFieldTrialsFromString stores the char*, so the char array must outlive + // the application. + const std::string force_field_trials = absl::GetFlag(FLAGS_force_fieldtrials); + webrtc::field_trial::InitFieldTrialsFromString(force_field_trials.c_str()); + + int port = absl::GetFlag(FLAGS_port); + + // Abort if the user specifies a port that is outside the allowed + // range [1, 65535]. + if ((port < 1) || (port > 65535)) { + printf("Error: %i is not a valid port.\n", port); + return -1; + } + + ListeningSocket listener; + if (!listener.Create()) { + printf("Failed to create server socket\n"); + return -1; + } else if (!listener.Listen(port)) { + printf("Failed to listen on server socket\n"); + return -1; + } + + printf("Server listening on port %i\n", port); + + PeerChannel clients; + typedef std::vector<DataSocket*> SocketArray; + SocketArray sockets; + bool quit = false; + while (!quit) { + fd_set socket_set; + FD_ZERO(&socket_set); + if (listener.valid()) + FD_SET(listener.socket(), &socket_set); + + for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i) + FD_SET((*i)->socket(), &socket_set); + + struct timeval timeout = {10, 0}; + if (select(FD_SETSIZE, &socket_set, NULL, NULL, &timeout) == SOCKET_ERROR) { + printf("select failed\n"); + break; + } + + for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i) { + DataSocket* s = *i; + bool socket_done = true; + if (FD_ISSET(s->socket(), &socket_set)) { + if (s->OnDataAvailable(&socket_done) && s->request_received()) { + ChannelMember* member = clients.Lookup(s); + if (member || PeerChannel::IsPeerConnection(s)) { + if (!member) { + if (s->PathEquals("/sign_in")) { + clients.AddMember(s); + } else { + printf("No member found for: %s\n", s->request_path().c_str()); + s->Send("500 Error", true, "text/plain", "", + "Peer most likely gone."); + } + } else if (member->is_wait_request(s)) { + // no need to do anything. + socket_done = false; + } else { + ChannelMember* target = clients.IsTargetedRequest(s); + if (target) { + member->ForwardRequestToPeer(s, target); + } else if (s->PathEquals("/sign_out")) { + s->Send("200 OK", true, "text/plain", "", ""); + } else { + printf("Couldn't find target for request: %s\n", + s->request_path().c_str()); + s->Send("500 Error", true, "text/plain", "", + "Peer most likely gone."); + } + } + } else { + HandleBrowserRequest(s, &quit); + if (quit) { + printf("Quitting...\n"); + FD_CLR(listener.socket(), &socket_set); + listener.Close(); + clients.CloseAll(); + } + } + } + } else { + socket_done = false; + } + + if (socket_done) { + printf("Disconnecting socket\n"); + clients.OnClosing(s); + RTC_DCHECK(s->valid()); // Close must not have been called yet. + FD_CLR(s->socket(), &socket_set); + delete (*i); + i = sockets.erase(i); + if (i == sockets.end()) + break; + } + } + + clients.CheckForTimeout(); + + if (FD_ISSET(listener.socket(), &socket_set)) { + DataSocket* s = listener.Accept(); + if (sockets.size() >= kMaxConnections) { + delete s; // sorry, that's all we can take. + printf("Connection limit reached\n"); + } else { + sockets.push_back(s); + printf("New connection...\n"); + } + } + } + + for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i) + delete (*i); + sockets.clear(); + + return 0; +} |