Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
SAT>IP server: initial RTSP code
  • Loading branch information
perexg committed Mar 11, 2015
1 parent 1c3f608 commit fd1bc1c
Show file tree
Hide file tree
Showing 6 changed files with 930 additions and 40 deletions.
3 changes: 2 additions & 1 deletion Makefile
Expand Up @@ -161,7 +161,8 @@ SRCS-${CONFIG_UPNP} += \

# SATIP Server
SRCS-${CONFIG_SATIP_SERVER} += \
src/satip/server.c
src/satip/server.c \
src/satip/rtsp.c

SRCS += \
src/api.c \
Expand Down
105 changes: 77 additions & 28 deletions src/http.c
Expand Up @@ -61,8 +61,6 @@ static struct strtab HTTP_versiontab[] = {
{ "RTSP/1.0", RTSP_VERSION_1_0 },
};

static void http_parse_get_args(http_connection_t *hc, char *args);

/**
*
*/
Expand Down Expand Up @@ -185,13 +183,16 @@ http_rc2str(int code)
switch(code) {
case HTTP_STATUS_OK: return "OK";
case HTTP_STATUS_PARTIAL_CONTENT: return "Partial Content";
case HTTP_STATUS_NOT_FOUND: return "Not found";
case HTTP_STATUS_UNAUTHORIZED: return "Unauthorized";
case HTTP_STATUS_BAD_REQUEST: return "Bad request";
case HTTP_STATUS_FOUND: return "Found";
case HTTP_STATUS_HTTP_VERSION: return "HTTP Version Not Supported";
case HTTP_STATUS_BAD_REQUEST: return "Bad Request";
case HTTP_STATUS_UNAUTHORIZED: return "Unauthorized";
case HTTP_STATUS_NOT_FOUND: return "Not Found";
case HTTP_STATUS_UNSUPPORTED: return "Unsupported Media Type";
case HTTP_STATUS_BANDWIDTH: return "Not Enough Bandwidth";
case HTTP_STATUS_BAD_SESSION: return "Session Not Found";
case HTTP_STATUS_HTTP_VERSION: return "HTTP/RTSP Version Not Supported";
default:
return "Unknown returncode";
return "Unknown Code";
break;
}
}
Expand All @@ -213,10 +214,12 @@ http_send_header(http_connection_t *hc, int rc, const char *content,
int64_t contentlen,
const char *encoding, const char *location,
int maxage, const char *range,
const char *disposition)
const char *disposition,
http_arg_list_t *args)
{
struct tm tm0, *tm;
htsbuf_queue_t hdrs;
http_arg_t *ra;
time_t t;

htsbuf_queue_init(&hdrs, 0);
Expand All @@ -229,7 +232,8 @@ http_send_header(http_connection_t *hc, int rc, const char *content,
htsbuf_qprintf(&hdrs, "Server: HTS/tvheadend\r\n");

if(maxage == 0) {
htsbuf_qprintf(&hdrs, "Cache-Control: no-cache\r\n");
if (hc->hc_version != RTSP_VERSION_1_0)
htsbuf_qprintf(&hdrs, "Cache-Control: no-cache\r\n");
} else {
time(&t);

Expand Down Expand Up @@ -289,6 +293,13 @@ http_send_header(http_connection_t *hc, int rc, const char *content,
if (++hc->hc_cseq == 0)
hc->hc_cseq = 1;
}
if(hc->hc_session)
htsbuf_qprintf(&hdrs, "Session: %s\r\n", hc->hc_session);

if (args) {
TAILQ_FOREACH(ra, args, link)
htsbuf_qprintf(&hdrs, "%s: %s\r\n", ra->key, ra->val);
}

htsbuf_qprintf(&hdrs, "\r\n");

Expand All @@ -305,7 +316,7 @@ http_send_reply(http_connection_t *hc, int rc, const char *content,
const char *encoding, const char *location, int maxage)
{
http_send_header(hc, rc, content, hc->hc_reply.hq_size,
encoding, location, maxage, 0, NULL);
encoding, location, maxage, 0, NULL, NULL);

if(hc->hc_no_output)
return;
Expand All @@ -328,25 +339,29 @@ http_error(http_connection_t *hc, int error)
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrstr, 50);

if (error != HTTP_STATUS_FOUND && error != HTTP_STATUS_MOVED)
tvhlog(error < 400 ? LOG_INFO : LOG_ERR, "HTTP", "%s: %s -- %d",
tvhlog(error < 400 ? LOG_INFO : LOG_ERR, "http", "%s: %s -- %d",
addrstr, hc->hc_url, error);

htsbuf_queue_flush(&hc->hc_reply);
if (hc->hc_version != RTSP_VERSION_1_0) {
htsbuf_queue_flush(&hc->hc_reply);

htsbuf_qprintf(&hc->hc_reply,
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
"<HTML><HEAD>\r\n"
"<TITLE>%d %s</TITLE>\r\n"
"</HEAD><BODY>\r\n"
"<H1>%d %s</H1>\r\n",
error, errtxt, error, errtxt);
htsbuf_qprintf(&hc->hc_reply,
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
"<HTML><HEAD>\r\n"
"<TITLE>%d %s</TITLE>\r\n"
"</HEAD><BODY>\r\n"
"<H1>%d %s</H1>\r\n",
error, errtxt, error, errtxt);

if (error == HTTP_STATUS_UNAUTHORIZED)
htsbuf_qprintf(&hc->hc_reply, "<P><A HREF=\"/\">Default Login</A></P>");
if (error == HTTP_STATUS_UNAUTHORIZED)
htsbuf_qprintf(&hc->hc_reply, "<P><A HREF=\"/\">Default Login</A></P>");

htsbuf_qprintf(&hc->hc_reply, "</BODY></HTML>\r\n");
htsbuf_qprintf(&hc->hc_reply, "</BODY></HTML>\r\n");

http_send_reply(hc, error, "text/html", NULL, NULL, 0);
http_send_reply(hc, error, "text/html", NULL, NULL, 0);
} else {
http_send_reply(hc, error, NULL, NULL, NULL, 0);
}
}


Expand Down Expand Up @@ -430,7 +445,7 @@ http_access_verify_ticket(http_connection_t *hc)
return;
char addrstr[50];
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrstr, 50);
tvhlog(LOG_INFO, "HTTP", "%s: using ticket %s for %s",
tvhlog(LOG_INFO, "http", "%s: using ticket %s for %s",
addrstr, ticket_id, hc->hc_url);
}

Expand Down Expand Up @@ -666,6 +681,20 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
switch(hc->hc_version) {
case RTSP_VERSION_1_0:
hc->hc_keep_alive = 1;
/* Extract CSeq */
if((v = http_arg_get(&hc->hc_args, "CSeq")) != NULL)
hc->hc_cseq = strtoll(v, NULL, 10);
else
hc->hc_cseq = 0;
free(hc->hc_session);
if ((v = http_arg_get(&hc->hc_args, "Session")) != NULL)
hc->hc_session = strdup(v);
else
hc->hc_session = NULL;
if(hc->hc_cseq == 0) {
http_error(hc, HTTP_STATUS_BAD_REQUEST);
return -1;
}
break;

case HTTP_VERSION_1_0:
Expand Down Expand Up @@ -707,7 +736,7 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
if (hc->hc_cseq)
rval = hc->hc_process(hc, spill);
else
rval = -1;
http_error(hc, HTTP_STATUS_HTTP_VERSION);
break;

case HTTP_VERSION_1_0:
Expand All @@ -719,6 +748,7 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
break;
}
free(hc->hc_representative);
free(hc->hc_session);
return rval;
}

Expand Down Expand Up @@ -753,6 +783,25 @@ http_arg_get(struct http_arg_list *list, const char *name)
return NULL;
}

/**
* Find an argument associated with a connection and remove it
*/
char *
http_arg_get_remove(struct http_arg_list *list, const char *name)
{
static char __thread buf[128];
http_arg_t *ra;
TAILQ_FOREACH(ra, list, link)
if(!strcasecmp(ra->key, name)) {
TAILQ_REMOVE(list, ra, link);
strncpy(buf, ra->val, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
return buf;
}
buf[0] = '\0';
return buf;
}


/**
* Set an argument associated with a connection
Expand Down Expand Up @@ -887,7 +936,7 @@ http_deescape(char *s)
/**
* Parse arguments of a HTTP GET url, not perfect, but works for us
*/
static void
void
http_parse_get_args(http_connection_t *hc, char *args)
{
char *k, *v;
Expand Down Expand Up @@ -1011,7 +1060,7 @@ http_serve(int fd, void **opaque, struct sockaddr_storage *peer,
{
http_connection_t hc;

// Note: global_lock held on entry */
/* Note: global_lock held on entry */
pthread_mutex_unlock(&global_lock);
memset(&hc, 0, sizeof(http_connection_t));
*opaque = &hc;
Expand All @@ -1031,7 +1080,7 @@ http_serve(int fd, void **opaque, struct sockaddr_storage *peer,
*opaque = NULL;
}

static void
void
http_cancel( void *opaque )
{
http_connection_t *hc = opaque;
Expand Down
13 changes: 11 additions & 2 deletions src/http.h
Expand Up @@ -22,7 +22,7 @@
#include "htsbuf.h"
#include "url.h"
#include "tvhpoll.h"
#include "access.h"
#include "access.h"

struct channel;
struct http_path;
Expand Down Expand Up @@ -74,12 +74,15 @@ typedef struct http_arg {
#define HTTP_STATUS_UNSUPPORTED 415
#define HTTP_STATUS_BAD_RANGE 417
#define HTTP_STATUS_EXPECTATION 418
#define HTTP_STATUS_BANDWIDTH 453
#define HTTP_STATUS_BAD_SESSION 454
#define HTTP_STATUS_INTERNAL 500
#define HTTP_STATUS_NOT_IMPLEMENTED 501
#define HTTP_STATUS_BAD_GATEWAY 502
#define HTTP_STATUS_SERVICE 503
#define HTTP_STATUS_GATEWAY_TIMEOUT 504
#define HTTP_STATUS_HTTP_VERSION 505
#define HTTP_STATUS_OP_NOT_SUPPRT 551

typedef enum http_state {
HTTP_CON_WAIT_REQUEST,
Expand Down Expand Up @@ -145,6 +148,7 @@ typedef struct http_connection {
int hc_logout_cookie;
int hc_shutdown;
uint64_t hc_cseq;
char *hc_session;

/* Support for HTTP POST */

Expand All @@ -168,6 +172,7 @@ static inline void http_arg_init(struct http_arg_list *list)
void http_arg_flush(struct http_arg_list *list);

char *http_arg_get(struct http_arg_list *list, const char *name);
char *http_arg_get_remove(struct http_arg_list *list, const char *name);

void http_arg_set(struct http_arg_list *list, const char *key, const char *val);

Expand All @@ -185,10 +190,12 @@ void http_redirect(http_connection_t *hc, const char *location,
void http_send_header(http_connection_t *hc, int rc, const char *content,
int64_t contentlen, const char *encoding,
const char *location, int maxage, const char *range,
const char *disposition);
const char *disposition, http_arg_list_t *args);

void http_serve_requests(http_connection_t *hc);

void http_cancel(void *opaque);

typedef int (http_callback_t)(http_connection_t *hc,
const char *remain, void *opaque);

Expand Down Expand Up @@ -223,6 +230,8 @@ int http_access_verify_channel(http_connection_t *hc, int mask,

void http_deescape(char *s);

void http_parse_get_args(http_connection_t *hc, char *args);

/*
* HTTP/RTSP Client
*/
Expand Down

0 comments on commit fd1bc1c

Please sign in to comment.