summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Demuxer.cpp47
-rw-r--r--src/Demuxer.h4
-rw-r--r--src/Http.cpp14
-rw-r--r--src/Http.h8
-rw-r--r--src/main.cpp85
5 files changed, 104 insertions, 54 deletions
diff --git a/src/Demuxer.cpp b/src/Demuxer.cpp
index 04cd35b..fbe5b49 100644
--- a/src/Demuxer.cpp
+++ b/src/Demuxer.cpp
@@ -22,7 +22,7 @@
using namespace std;
//-------------------------------------------------------------------------------
-std::string Demuxer::webif_reauest(std::string service, std::string auth) throw(trap)
+std::string Demuxer::webif_reauest(std::string request) throw(http_trap)
{
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
throw(trap("webif create socket fail."));
@@ -32,15 +32,10 @@ std::string Demuxer::webif_reauest(std::string service, std::string auth) throw(
sock_addr.sin_port = htons(80);
sock_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)))
- throw(trap("webif connect fail."));
-
- std::string request = string("GET /web/stream?StreamService=") + service + " HTTP/1.0\r\n";
- if (auth != "")
- request += "Authorization: " + auth + "\r\n";
- request += "\r\n";
+ throw(http_trap("webif connect fail.", 502, "Bad Gateway, webif connect fail"));
if (write(sock, request.c_str(), request.length()) != request.length())
- throw(trap("webif send(request) fail."));
+ throw(http_trap("webif request fail.", 502, "Bad Gateway, webif request error"));
DEBUG("webif request :\n", request.c_str());
std::string response = "";
@@ -56,7 +51,7 @@ std::string Demuxer::webif_reauest(std::string service, std::string auth) throw(
break;
else if (poll_state < 0) {
ERROR("webif receive poll error : %s (%d)", strerror(errno), errno);
- throw(trap("webif receive response error."));
+ throw(http_trap("webif response fail.", 502, "Bad Gateway, webif response error"));
}
if (pollevt[0].revents & POLLIN) {
if (read(sock, buffer, 1024) <= 0) {
@@ -183,27 +178,47 @@ bool Demuxer::parse_webif_response(std::string& response, std::vector<unsigned l
}
//-------------------------------------------------------------------------------
-Demuxer::Demuxer(HttpHeader *header) throw(trap)
+Demuxer::Demuxer(HttpHeader *header) throw(http_trap)
{
demux_id = pat_pid = fd = sock = -1;
pmt_pid = audio_pid = video_pid = 0;
- std::string auth = header->params["WWW-Authenticate"];
- std::string service = header->path.substr(1);
- std::string webif_response = webif_reauest(service, auth);
+ std::string webif_request = string("GET /web/stream?StreamService=") + header->path.substr(1) + " HTTP/1.0\r\n";
+ if (header->params.find("Authorization") != header->params.end()) {
+ if (header->params["Authorization"].length() < 5) {
+ throw(http_trap("no authorization data.", 401, "Unauthorized"));
+ }
+ webif_request += "Authorization: " + header->params["Authorization"] + "\r\n";
+ if (header->params["Cookie"].length() > 0) {
+ webif_request += "Cookie: " + header->params["Cookie"] + "\r\n";
+ }
+ }
+ webif_request += "\r\n";
+
+ std::string webif_response = webif_reauest(webif_request);
DEBUG("webif response :\n%s", webif_response.c_str());
+ if (webif_response.find("WWW-Authenticate") != std::string::npos) {
+ header->authorization = webif_response;
+ throw(http_trap("webif whthentication fail.", 401, "Unauthorized"));
+ }
+
std::vector<unsigned long> new_pids;
if (!parse_webif_response(webif_response, new_pids))
- throw(trap("webif response parsing fail."));
+ throw(http_trap("webif response parsing fail.", 503, "Service Unavailable"));
std::string demuxpath = "/dev/dvb/adapter0/demux" + Util::ultostr(demux_id);
if ((fd = open(demuxpath.c_str(), O_RDWR | O_NONBLOCK)) < 0) {
- throw(trap(std::string("demux open fail : ") + demuxpath));
+ throw(http_trap(std::string("demux open fail : ") + demuxpath, 503, "Service Unavailable"));
}
INFO("demux open success : %s", demuxpath.c_str());
- set_filter(new_pids);
+ try {
+ set_filter(new_pids);
+ }
+ catch (const trap &e) {
+ throw(http_trap(e.what(), 503, "Service Unavailable"));
+ }
}
//-------------------------------------------------------------------------------
diff --git a/src/Demuxer.h b/src/Demuxer.h
index 033c54d..5c90dda 100644
--- a/src/Demuxer.h
+++ b/src/Demuxer.h
@@ -34,13 +34,13 @@ private:
std::vector<unsigned long> pids;
protected:
- std::string webif_reauest(std::string service, std::string auth) throw(trap);
+ std::string webif_reauest(std::string request) throw(http_trap);
bool already_exist(std::vector<unsigned long> &pidlist, int pid);
void set_filter(std::vector<unsigned long> &new_pids) throw(trap);
bool parse_webif_response(std::string& response, std::vector<unsigned long> &new_pids);
public:
- Demuxer(HttpHeader *header) throw(trap);
+ Demuxer(HttpHeader *header) throw(http_trap);
virtual ~Demuxer() throw();
int get_fd() const throw();
};
diff --git a/src/Http.cpp b/src/Http.cpp
index 7b736c6..7746cc9 100644
--- a/src/Http.cpp
+++ b/src/Http.cpp
@@ -172,3 +172,17 @@ std::string HttpHeader::read_request()
return request;
}
//----------------------------------------------------------------------
+
+std::string HttpUtil::http_error(int errcode, std::string errmsg)
+{
+ std::ostringstream oss;
+
+ oss << "HTTP/1.1 " << Util::ultostr(errcode) << " " << errmsg << "\r\n";
+ oss << "Content-Type: text/html\r\n";
+ oss << "Connection: close\r\n";
+ oss << "Accept-Ranges: bytes\r\n";
+ oss << "\r\n";
+
+ return oss.str();
+}
+//----------------------------------------------------------------------
diff --git a/src/Http.h b/src/Http.h
index 31246bc..69f7a09 100644
--- a/src/Http.h
+++ b/src/Http.h
@@ -33,8 +33,7 @@ public:
std::string page;
std::map<std::string, std::string> page_params;
-private:
-
+ std::string authorization;
public:
HttpHeader() : type(UNKNOWN) {}
virtual ~HttpHeader() {}
@@ -46,4 +45,9 @@ public:
};
//----------------------------------------------------------------------
+namespace HttpUtil {
+ std::string http_error(int errcode, std::string errmsg);
+};
+//----------------------------------------------------------------------
+
#endif /* HTTP_H_ */
diff --git a/src/main.cpp b/src/main.cpp
index 9121be6..3749d06 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -31,9 +31,7 @@ using namespace std;
#define BUFFFER_SIZE (188 * 256)
void show_help();
-
void signal_handler(int sig_no);
-void do_exit(const char *message);
void *source_thread_main(void *params);
void *streaming_thread_main(void *params);
@@ -63,7 +61,20 @@ int main(int argc, char **argv)
std::string req = HttpHeader::read_request();
DEBUG("request head :\n%s", req.c_str());
- if (header.parse_request(req)) {
+
+ try {
+ if (req.find("\r\n\r\n") == std::string::npos) {
+ throw(http_trap("no found request done code.", 400, "Bad Request"));
+ }
+
+ if (header.parse_request(req) == false) {
+ throw(http_trap("request parse error.", 400, "Bad Request"));
+ }
+
+ if (header.method != "GET") {
+ throw(http_trap("not support request type.", 400, "Bad Request, not support request"));
+ }
+
Encoder encoder;
Source *source = 0;
ThreadParams thread_params = { 0, &encoder, &header };
@@ -81,8 +92,7 @@ int main(int argc, char **argv)
source = ts;
}
catch (const trap &e) {
- ERROR("fail to create source : %s", e.what());
- exit(-1);
+ throw(http_trap(e.what(), 404, "Not Found"));
}
break;
case HttpHeader::TRANSCODING_LIVE:
@@ -93,9 +103,8 @@ int main(int argc, char **argv)
audio_pid = dmx->audio_pid;
source = dmx;
}
- catch (const trap &e) {
- ERROR("fail to create source : %s", e.what());
- exit(-1);
+ catch (const http_trap &e) {
+ throw(e);
}
break;
case HttpHeader::M3U:
@@ -109,20 +118,18 @@ int main(int argc, char **argv)
}
exit(0);
default:
- ERROR("not support source type (type : %d)", header.type);
- exit(-1);
+ throw(http_trap(std::string("not support source type : ") + Util::ultostr(header.type), 400, "Bad Request"));
}
thread_params.source = source;
if (!encoder.retry_open(2, 3)) {
- exit(-1);
+ throw(http_trap("encoder open fail.", 503, "Service Unavailable"));
}
if (encoder.state == Encoder::ENCODER_STAT_OPENED) {
std::string response = header.build_response((Mpeg*) source);
if (response == "") {
- do_exit(0);
- return 0;
+ throw(http_trap("response build fail.", 503, "Service Unavailable"));
}
streaming_write(response.c_str(), response.length(), true);
@@ -132,44 +139,63 @@ int main(int argc, char **argv)
}
if (!encoder.ioctl(Encoder::IOCTL_SET_VPID, video_pid)) {
- do_exit("fail to set video pid.");
- exit(-1);
+ throw(http_trap("video pid setting fail.", 503, "Service Unavailable"));
}
if (!encoder.ioctl(Encoder::IOCTL_SET_APID, audio_pid)) {
- do_exit("fail to set audio pid.");
- exit(-1);
+ throw(http_trap("audio pid setting fail.", 503, "Service Unavailable"));
}
if (!encoder.ioctl(Encoder::IOCTL_SET_PMTPID, pmt_pid)) {
- do_exit("fail to set pmtid.");
- exit(-1);
+ throw(http_trap("pmt pid setting fail.", 503, "Service Unavailable"));
}
}
is_terminated = false;
source_thread_id = pthread_create(&source_thread_handle, 0, source_thread_main, (void *)&thread_params);
if (source_thread_id < 0) {
- do_exit("fail to create source thread.");
+ is_terminated = true;
+ throw(http_trap("souce thread create fail.", 503, "Service Unavailable"));
}
else {
pthread_detach(source_thread_handle);
sleep(1);
if (!encoder.ioctl(Encoder::IOCTL_START_TRANSCODING, 0)) {
- do_exit("fail to start transcoding.");
+ is_terminated = true;
+ throw(http_trap("start transcoding fail.", 503, "Service Unavailable"));
}
else {
stream_thread_id = pthread_create(&stream_thread_handle, 0, streaming_thread_main, (void *)&thread_params);
if (stream_thread_id < 0) {
- do_exit("fail to create stream thread.");
+ is_terminated = true;
+ throw(http_trap("stream thread create fail.", 503, "Service Unavailable"));
}
}
}
pthread_join(stream_thread_handle, 0);
+ is_terminated = true;
if (source != 0) {
delete source;
source = 0;
}
}
+ catch (const http_trap &e) {
+ ERROR("%s", e.message.c_str());
+ std::string error = "";
+ if (e.http_error == 401 && header.authorization.length() > 0) {
+ error = header.authorization;
+ }
+ else {
+ error = HttpUtil::http_error(e.http_error, e.http_header);
+ }
+ streaming_write(error.c_str(), error.length(), true);
+ exit(-1);
+ }
+ catch (...) {
+ ERROR("unknown exception...");
+ std::string error = HttpUtil::http_error(400, "Bad request");
+ streaming_write(error.c_str(), error.length(), true);
+ exit(-1);
+ }
return 0;
}
//----------------------------------------------------------------------
@@ -232,7 +258,7 @@ void *streaming_thread_main(void *params)
catch (const trap &e) {
ERROR("%s %s (%d)", e.what(), strerror(errno), errno);
}
- do_exit(0);
+ is_terminated = true;
INFO("streaming thread stop.");
if (encoder->state == Encoder::ENCODER_STAT_STARTED) {
@@ -324,19 +350,10 @@ int streaming_write(const char *buffer, size_t buffer_len, bool enable_log)
}
//----------------------------------------------------------------------
-void do_exit(const char *message)
-{
- is_terminated = true;
- if (message) {
- ERROR("%s", message);
- }
-}
-//----------------------------------------------------------------------
-
void signal_handler(int sig_no)
{
INFO("signal no : %d", sig_no);
- do_exit("signal detected..");
+ is_terminated = true;
}
//----------------------------------------------------------------------
@@ -347,6 +364,6 @@ void show_help()
printf(" * To active debug mode, input NUMBER on /tmp/debug_on file. (default : warning)\n");
printf(" NUMBER : error(1), warning(2), info(3), debug(4), log(5)\n");
printf("\n");
- printf(" ex > echo \"4\" > /tmp/debug_on\n");
+ printf(" ex > echo \"4\" > /tmp/.debug_on\n");
}
//----------------------------------------------------------------------