summaryrefslogtreecommitdiff
path: root/src/Http.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Http.cpp')
-rw-r--r--src/Http.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/Http.cpp b/src/Http.cpp
new file mode 100644
index 0000000..7b736c6
--- /dev/null
+++ b/src/Http.cpp
@@ -0,0 +1,174 @@
+/*
+ * Http.cpp
+ *
+ * Created on: 2014. 6. 18.
+ * Author: oskwon
+ */
+
+#include <string.h>
+
+#include <sstream>
+
+#include "Util.h"
+#include "Logger.h"
+
+#include "Http.h"
+#include "UriDecoder.h"
+
+using namespace std;
+//----------------------------------------------------------------------
+
+bool HttpHeader::parse_request(std::string header)
+{
+ std::string line, key, value;
+ std::istringstream request_stream;
+ request_stream.str(header);
+
+ request_stream >> method;
+ request_stream >> path;
+ request_stream >> version;
+ std::getline(request_stream, line);
+
+ while(std::getline(request_stream, line)) {
+ if ((line = Util::trim(line)) != "") {
+ Util::split_key_value(line, ":", key, value);
+
+ key = Util::trim(key);
+ value = Util::trim(value);
+
+ params[key] = value;
+ DEBUG("add param : [%s] - [%s]", key.c_str(), value.c_str());
+ }
+ }
+
+ int idx = path.find("?");
+ // page
+ if (idx != std::string::npos) {
+ page = path.substr(0,idx);
+ std::string page_param = path.substr(idx + 1);
+
+ DEBUG("request url : [%s] - [%s]", page.c_str(), page_param.c_str());
+ std::istringstream request_params_stream;
+ request_params_stream.str(page_param);
+ while(std::getline(request_params_stream, line, '&')) {
+ if ((line = Util::trim(line)) != "") {
+ Util::split_key_value(line, "=", key, value);
+
+ key = Util::trim(key);
+ value = Util::trim(value);
+
+ page_params[key] = value;
+ DEBUG("add page param : [%s] - [%s]", key.c_str(), value.c_str());
+ }
+ }
+
+ if (page == "/file") {
+ type = HttpHeader::TRANSCODING_FILE;
+ }
+ else if (page == "/m3u") {
+ type = HttpHeader::M3U;
+ }
+ }
+ // live
+ else {
+ type = HttpHeader::TRANSCODING_LIVE;
+ }
+ return true;
+}
+//----------------------------------------------------------------------
+
+static const char *http_ok = "HTTP/1.1 200 OK\r\n";
+static const char *http_partial = "HTTP/1.1 206 Partial Content\r\n";
+static const char *http_connection = "Connection: Close\r\n";
+static const char *http_server = "Server: transtreamproxy\r\n";
+static const char *http_done = "\r\n";
+std::string HttpHeader::build_response(Mpeg *source)
+{
+ std::ostringstream oss;
+
+ switch(type) {
+ case HttpHeader::TRANSCODING_FILE: {
+ std::string range = params["Range"];
+ off_t seek_offset = 0, content_length = 0;
+
+ if((range.length() > 7) && (range.substr(0, 6) == "bytes=")) {
+ range = range.substr(6);
+ if(range.find('-') == (range.length() - 1)) {
+ seek_offset = Util::strtollu(range);
+ }
+ }
+
+ content_length = source->stream_length - seek_offset;
+ if (seek_offset > 0) {
+ content_length += 1;
+ oss << http_partial;
+ }
+ else {
+ oss << http_ok;
+ }
+ oss << http_connection;
+ oss << "Content-Type: video/mpeg\r\n";
+ oss << http_server;
+ oss << "Accept-Ranges: bytes\r\n";
+ oss << "Content-Length: " << Util::ultostr(content_length) << "\r\n";
+ oss << "Content-Range: bytes " <<
+ Util::ultostr(seek_offset) << "-" <<
+ Util::ultostr(source->stream_length - 1) << "/" <<
+ Util::ultostr(source->stream_length) << "\r\n";
+ oss << http_done;
+ }
+ break;
+ case HttpHeader::TRANSCODING_LIVE: {
+ oss << http_ok;
+ oss << http_connection;
+ oss << "Content-Type: video/mpeg\r\n";
+ oss << http_server;
+ oss << http_done;
+ }
+ break;
+ case HttpHeader::M3U: {
+ std::ostringstream m3u_oss;
+ m3u_oss << "#EXTM3U\n";
+ m3u_oss << "#EXTVLCOPT--http-reconnect=true\n";
+ m3u_oss << "http://" << params["Host"] << "/file?file=" << page_params["file"];
+ if (page_params["position"] != "") {
+ m3u_oss << "&position=" << page_params["position"];
+ }
+ m3u_oss << "\n";
+ m3u_oss << http_done;
+
+ std::string m3u_content = m3u_oss.str();
+
+ oss << http_partial;
+ oss << "Content-Type: audio/x-mpegurl\r\n";
+ oss << "Accept-Ranges: bytes\r\n";
+ oss << http_connection;
+ oss << http_server;
+ oss << "Content-Length: " << Util::ultostr(m3u_content.length()) << "\r\n";
+ oss << "Content-Range: bytes 0-" <<
+ Util::ultostr(m3u_content.length() - 1) << "/" <<
+ Util::ultostr(m3u_content.length()) << "\r\n";
+ oss << http_done;
+ oss << m3u_content;
+ }
+ break;
+ default: return "";
+ }
+ return oss.str();
+}
+//----------------------------------------------------------------------
+
+std::string HttpHeader::read_request()
+{
+ std::string request = "";
+ while (true) {
+ char buffer[128] = {0};
+ fgets(buffer, 127, stdin);
+
+ request += buffer;
+ if(request.find("\r\n\r\n") != string::npos)
+ break;
+ }
+ return request;
+}
+//----------------------------------------------------------------------