diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2002-10-20 19:34:18 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2002-10-20 19:34:18 +0000 |
commit | cb8b0a5536924b35c1def29fb421edcc90664520 (patch) | |
tree | 25f35a40ea6c294df4f4fa89e5b13b5a4ba724a0 /src | |
parent | d092ab0aa226dbcf736c548b54f8b99a1adb9bec (diff) | |
download | xine-lib-cb8b0a5536924b35c1def29fb421edcc90664520.tar.gz xine-lib-cb8b0a5536924b35c1def29fb421edcc90664520.tar.bz2 |
http input plugin adapted to new api
CVS patchset: 2889
CVS date: 2002/10/20 19:34:18
Diffstat (limited to 'src')
-rw-r--r-- | src/input/Makefile.am | 7 | ||||
-rw-r--r-- | src/input/input_http.c | 533 |
2 files changed, 292 insertions, 248 deletions
diff --git a/src/input/Makefile.am b/src/input/Makefile.am index 358b16f6b..641bf135b 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -42,6 +42,7 @@ DEBUG_CFLAGS = @DEBUG_CFLAGS@ $(DVD_CFLAGS) lib_LTLIBRARIES = \ xineplug_inp_file.la \ + xineplug_inp_http.la \ xineplug_inp_mms.la #lib_LTLIBRARIES = \ @@ -84,9 +85,9 @@ xineplug_inp_mms_la_LDFLAGS = -avoid-version -module #xineplug_inp_rtp_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la #xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module -#xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c -#xineplug_inp_http_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la -#xineplug_inp_http_la_LDFLAGS = -avoid-version -module +xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c +xineplug_inp_http_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la +xineplug_inp_http_la_LDFLAGS = -avoid-version -module #xineplug_inp_cda_la_SOURCES = input_cda.c #xineplug_inp_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la diff --git a/src/input/input_http.c b/src/input/input_http.c index 1ebbf0f2f..a1975a0a0 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -55,11 +55,10 @@ extern int errno; typedef struct { input_plugin_t input_plugin; - xine_t *xine; + xine_stream_t *stream; int fh; char *mrl; - config_values_t *config; nbc_t *nbc; @@ -91,8 +90,17 @@ typedef struct { } http_input_plugin_t; +typedef struct { + + input_class_t input_class; + + xine_t *xine; + config_values_t *config; + +} http_input_class_t; -static int http_plugin_host_connect_attempt(struct in_addr ia, int port, xine_t *xine) { +static int http_plugin_host_connect_attempt (struct in_addr ia, int port, + xine_t *xine) { int s; struct sockaddr_in sin; @@ -117,7 +125,7 @@ static int http_plugin_host_connect_attempt(struct in_addr ia, int port, xine_t return s; } -static int http_plugin_host_connect(const char *host, int port, xine_t *xine) { +static int http_plugin_host_connect (const char *host, int port, xine_t *xine) { struct hostent *h; int i; int s; @@ -290,56 +298,235 @@ static int http_plugin_basicauth (const char *user, const char *password, static off_t http_plugin_read (input_plugin_t *this_gen, char *buf, off_t nlen) ; -static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { +static off_t http_plugin_read (input_plugin_t *this_gen, + char *buf, off_t nlen) { + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + off_t n, num_bytes; + + nbc_check_buffers (this->nbc); + + num_bytes = 0; + while (num_bytes < nlen) { + + if (this->preview_pos < this->preview_size) { + + n = this->preview_size - this->preview_pos; + if (n > (nlen - num_bytes)) + n = nlen - num_bytes; + +#ifdef LOG + printf ("input_http: %lld bytes from preview (which has %lld bytes)\n", + n, this->preview_size); +#endif + + memcpy (&buf[num_bytes], &this->preview[this->preview_pos], n); + + this->preview_pos += n; + + } else + n = read (this->fh, &buf[num_bytes], nlen - num_bytes); + + if (n <= 0) { + + switch (errno) { + case EAGAIN: + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: EAGAIN\n")); + continue; + default: + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error\n")); + return 0; + } + } + + num_bytes += n; + this->curpos += n; + } + return num_bytes; +} + +/* + * helper function to release buffer + * in case demux thread is cancelled + */ +static void pool_release_buffer (void *arg) { + buf_element_t *buf = (buf_element_t *) arg; + if( buf != NULL ) + buf->free_buffer(buf); +} + +static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { + + off_t total_bytes; + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + + nbc_check_buffers (this->nbc); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); + pthread_cleanup_push( pool_release_buffer, buf ); + + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + + total_bytes = http_plugin_read (this_gen, buf->content, todo); + + if (total_bytes != todo) { + buf->free_buffer (buf); + buf = NULL; + } + + if (buf != NULL) + buf->size = total_bytes; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); + pthread_cleanup_pop(0); + + return buf; +} + +static off_t http_plugin_get_length (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - char *proxy; - int done,len,linenum; + + return this->contentlength; +} + +static uint32_t http_plugin_get_capabilities (input_plugin_t *this_gen) { + + return INPUT_CAP_NOCAP; +} + +static uint32_t http_plugin_get_blocksize (input_plugin_t *this_gen) { + + return 0; +} + +static off_t http_plugin_get_current_pos (input_plugin_t *this_gen){ + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + + return this->curpos; +} + +static off_t http_plugin_seek(input_plugin_t *this_gen, + off_t offset, int origin) { + + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + /* dummy implementation: don't seek, just return current position */ + return this->curpos; +} + +static char *http_plugin_get_description (input_plugin_t *this_gen) { + return _("http network stream input plugin"); +} + +static char *http_plugin_get_identifier (input_plugin_t *this_gen) { + return "HTTP"; +} + +static char* http_plugin_get_mrl (input_plugin_t *this_gen) { + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + + return this->mrlbuf2; +} + +static int http_plugin_get_optional_data (input_plugin_t *this_gen, + void *data, int data_type) { + + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + + switch (data_type) { + case INPUT_OPTIONAL_DATA_PREVIEW: + + memcpy (data, this->preview, this->preview_size); + return this->preview_size; + + break; + } + + return INPUT_OPTIONAL_UNSUPPORTED; +} + +static void http_plugin_dispose (input_plugin_t *this_gen ) { + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + + close(this->fh); + this->fh = -1; + + if (this->nbc) { + nbc_close (this->nbc); + this->nbc = NULL; + } + + free (this_gen); +} + +static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, + const char *mrl) { + + /* http_input_class_t *cls = (http_input_class_t *) cls_gen;*/ + http_input_plugin_t *this; + char *proxy; + int done,len,linenum; + + this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t)); strncpy (this->mrlbuf, mrl, BUFSIZE); strncpy (this->mrlbuf2, mrl, BUFSIZE); this->mrl = this->mrlbuf2; - if (strncasecmp (this->mrlbuf, "http://", 7)) - return 0; + if (strncasecmp (this->mrlbuf, "http://", 7)) { + free (this); + return NULL; + } + + this->stream = stream; this->proxybuf[0] = '\0'; proxy = getenv("http_proxy"); - if (proxy != NULL) - { + if (proxy != NULL) { strncpy(this->proxybuf, proxy, BUFSIZE); if (http_plugin_parse_url (this->proxybuf, &this->proxyuser, - &this->proxypassword, &this->proxyhost, &this->proxyport, NULL)) - return 0; + &this->proxypassword, &this->proxyhost, + &this->proxyport, NULL)) { + free (this); + return NULL; + } if (this->proxyport == 0) this->proxyport = DEFAULT_HTTP_PORT; if (this->proxyuser != NULL) if (http_plugin_basicauth (this->proxyuser, this->proxypassword, - this->proxyauth, BUFSIZE)) - return 0; + this->proxyauth, BUFSIZE)) { + free (this); + return NULL; + } } - if(http_plugin_parse_url (this->mrlbuf, &this->user, &this->password, - &this->host, &this->port, &this->filename)) - return 0; + if (http_plugin_parse_url (this->mrlbuf, &this->user, &this->password, + &this->host, &this->port, &this->filename)) { + free (this); + return NULL; + } if(this->port == 0) this->port = DEFAULT_HTTP_PORT; if (this->user != NULL) - if (http_plugin_basicauth (this->user, this->password, this->auth, BUFSIZE)) - return 0; + if (http_plugin_basicauth (this->user, this->password, this->auth, BUFSIZE)) { + free (this); + return NULL; + } { char buf[256]; - sprintf(buf, _("input_http: opening >/%s< on host >%s<"), this->filename, this->host); + sprintf (buf, _("input_http: opening >/%s< on host >%s<"), + this->filename, this->host); - if(proxy != NULL) + if (proxy != NULL) sprintf(buf, _("%s via proxy >%s<"), buf, this->proxyhost); sprintf(buf, "%s\n", buf); @@ -350,51 +537,54 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { } if (proxy != NULL) - this->fh = http_plugin_host_connect (this->proxyhost, this->proxyport, this->xine); + this->fh = http_plugin_host_connect (this->proxyhost, this->proxyport, + this->stream->xine); else - this->fh = http_plugin_host_connect (this->host, this->port, this->xine); + this->fh = http_plugin_host_connect (this->host, this->port, this->stream->xine); this->curpos = 0; if (this->fh == -1) { - return 0; + free (this); + return NULL; } if (proxy != NULL) if (this->port != DEFAULT_HTTP_PORT) sprintf (this->buf, "GET http://%s:%d/%s HTTP/1.0\015\012", - this->host, this->port, this->filename); + this->host, this->port, this->filename); else sprintf (this->buf, "GET http://%s/%s HTTP/1.0\015\012", - this->host, this->filename); + this->host, this->filename); else sprintf (this->buf, "GET /%s HTTP/1.0\015\012", this->filename); if (this->port != DEFAULT_HTTP_PORT) sprintf (this->buf + strlen(this->buf), "Host: %s:%d\015\012", - this->host, this->port); + this->host, this->port); else sprintf (this->buf + strlen(this->buf), "Host: %s\015\012", - this->host); + this->host); if (this->proxyuser != NULL) sprintf (this->buf + strlen(this->buf), "Proxy-Authorization: Basic %s\015\012", - this->proxyauth); + this->proxyauth); if (this->user != NULL) sprintf (this->buf + strlen(this->buf), "Authorization: Basic %s\015\012", - this->auth); + this->auth); sprintf (this->buf + strlen(this->buf), "User-Agent: xine/%s\015\012", - VERSION); + VERSION); strcat (this->buf, "Accept: */*\015\012"); - + strcat (this->buf, "\015\012"); - + if (write (this->fh, this->buf, strlen(this->buf)) != strlen(this->buf)) { printf ("input_http: couldn't send request\n"); - return 0 ; + free (this); + return NULL ; } #ifdef LOG @@ -416,11 +606,12 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { switch (errno) { case EAGAIN: - xine_log (this->xine, XINE_LOG_MSG, _("input_http: EAGAIN\n")); + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: EAGAIN\n")); continue; default: - xine_log (this->xine, XINE_LOG_MSG, _("input_http: read error\n")); - return 0; + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error\n")); + free (this); + return NULL; } } @@ -440,8 +631,7 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { printf ("input_http: answer: >%s<\n", this->buf); #endif - if (linenum == 1) - { + if (linenum == 1) { int httpver, httpsub, httpcode; char httpstatus[BUFSIZE]; @@ -450,8 +640,10 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { /* icecast ? */ if (sscanf(this->buf, "ICY %d OK", &httpcode) != 1) { - xine_log (this->xine, XINE_LOG_MSG, _("input_http: invalid http answer\n")); - return 0; + xine_log (this->stream->xine, XINE_LOG_MSG, + _("input_http: invalid http answer\n")); + free (this); + return NULL; } else { this->mrlbuf2[0] = 'i'; this->mrlbuf2[1] = 'c'; @@ -461,29 +653,34 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { } if (httpcode >= 300 && httpcode < 400) { - xine_log (this->xine, XINE_LOG_MSG, _("input_http: 3xx redirection not implemented: >%d %s<\n"), - httpcode, httpstatus); - return 0; + xine_log (this->stream->xine, XINE_LOG_MSG, + _("input_http: 3xx redirection not implemented: >%d %s<\n"), + httpcode, httpstatus); + free (this); + return NULL; } if (httpcode < 200 || httpcode >= 300) { - xine_log (this->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), - httpcode, httpstatus); - return 0; + xine_log (this->stream->xine, XINE_LOG_MSG, + _("input_http: http status not 2xx: >%d %s<\n"), + httpcode, httpstatus); + free (this); + return NULL; } } else { if (this->contentlength == 0) { off_t contentlength; if (sscanf(this->buf, "Content-Length: %Ld", &contentlength) == 1) { - xine_log (this->xine, XINE_LOG_MSG, _("input_http: content length = %Ld bytes\n"), contentlength); + xine_log (this->stream->xine, XINE_LOG_MSG, + _("input_http: content length = %Ld bytes\n"), contentlength); this->contentlength = contentlength; } } - if (!strncasecmp(this->buf, "Location: ", 10)) - { - xine_log (this->xine, XINE_LOG_MSG, _("input_http: Location redirection not implemented\n")); - return 0; + if (!strncasecmp(this->buf, "Location: ", 10)) { + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: Location redirection not implemented\n")); + free (this); + return NULL; } } @@ -499,7 +696,7 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { printf ("input_http: end of headers\n"); #endif - this->nbc = nbc_init (this->xine); + this->nbc = nbc_init (this->stream); /* * fill preview buffer @@ -508,217 +705,63 @@ static int http_plugin_open (input_plugin_t *this_gen, const char *mrl) { this->preview_size = http_plugin_read (&this->input_plugin, this->preview, PREVIEW_SIZE); this->preview_pos = 0; + this->curpos = 0; - return 1; -} - -static off_t http_plugin_read (input_plugin_t *this_gen, - char *buf, off_t nlen) { - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - off_t n, num_bytes; - - nbc_check_buffers (this->nbc); - - num_bytes = 0; - - while (num_bytes < nlen) { - - if (this->preview_pos < this->preview_size) { - - n = this->preview_size - this->preview_pos; - if (n > (nlen - num_bytes)) - n = nlen - num_bytes; - -#ifdef LOG - printf ("input_http: %lld bytes from preview (which has %lld bytes)\n", - n, this->preview_size); -#endif - - memcpy (&buf[num_bytes], &this->preview[this->preview_pos], n); - - this->preview_pos += n; - - } else - n = read (this->fh, &buf[num_bytes], nlen - num_bytes); + this->input_plugin.get_capabilities = http_plugin_get_capabilities; + this->input_plugin.read = http_plugin_read; + this->input_plugin.read_block = http_plugin_read_block; + this->input_plugin.seek = http_plugin_seek; + this->input_plugin.get_current_pos = http_plugin_get_current_pos; + this->input_plugin.get_length = http_plugin_get_length; + this->input_plugin.get_blocksize = http_plugin_get_blocksize; + this->input_plugin.get_mrl = http_plugin_get_mrl; + this->input_plugin.dispose = http_plugin_dispose; + this->input_plugin.input_class = cls_gen; - if (n <= 0) { - - switch (errno) { - case EAGAIN: - xine_log (this->xine, XINE_LOG_MSG, _("input_http: EAGAIN\n")); - continue; - default: - xine_log (this->xine, XINE_LOG_MSG, _("input_http: read error\n")); - return 0; - } - } - - num_bytes += n; - this->curpos += n; - } - return num_bytes; + return &this->input_plugin; } /* - * helper function to release buffer - * in case demux thread is cancelled + * http input plugin class */ -static void pool_release_buffer (void *arg) { - buf_element_t *buf = (buf_element_t *) arg; - if( buf != NULL ) - buf->free_buffer(buf); -} - -static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { - - off_t total_bytes; - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - buf_element_t *buf = fifo->buffer_pool_alloc (fifo); - - nbc_check_buffers (this->nbc); - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); - pthread_cleanup_push( pool_release_buffer, buf ); - - buf->content = buf->mem; - buf->type = BUF_DEMUX_BLOCK; - - total_bytes = http_plugin_read (this_gen, buf->content, todo); - - if (total_bytes != todo) { - buf->free_buffer (buf); - buf = NULL; - } - - if (buf != NULL) - buf->size = total_bytes; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); - pthread_cleanup_pop(0); - - return buf; -} - -static off_t http_plugin_get_length (input_plugin_t *this_gen) { - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - - return this->contentlength; -} - -static uint32_t http_plugin_get_capabilities (input_plugin_t *this_gen) { - - return INPUT_CAP_NOCAP; -} - -static uint32_t http_plugin_get_blocksize (input_plugin_t *this_gen) { - - return 0; -} - -static off_t http_plugin_get_current_pos (input_plugin_t *this_gen){ - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - - return this->curpos; -} - -static off_t http_plugin_seek(input_plugin_t *this_gen, - off_t offset, int origin) { - - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - /* dummy implementation: don't seek, just return current position */ - return this->curpos; -} - -static int http_plugin_eject_media (input_plugin_t *this_gen) { - return 1; -} - -static void http_plugin_close (input_plugin_t *this_gen) { - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - - close(this->fh); - this->fh = -1; - - if (this->nbc) { - nbc_close (this->nbc); - this->nbc = NULL; - } -} - -static void http_plugin_stop (input_plugin_t *this_gen) { - http_plugin_close(this_gen); +static char *http_class_get_description (input_class_t *this_gen) { + return _("http input plugin"); } -static char *http_plugin_get_description (input_plugin_t *this_gen) { - return _("http network stream input plugin"); -} - -static char *http_plugin_get_identifier (input_plugin_t *this_gen) { - return "HTTP"; +static char *http_class_get_identifier (input_class_t *this_gen) { + return "http"; } -static char* http_plugin_get_mrl (input_plugin_t *this_gen) { - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; +static void http_class_dispose (input_class_t *this_gen) { + http_input_class_t *this = (http_input_class_t *) this_gen; - return this->mrlbuf2; + free (this); } -static int http_plugin_get_optional_data (input_plugin_t *this_gen, - void *data, int data_type) { - - http_input_plugin_t *this = (http_input_plugin_t *) this_gen; - - switch (data_type) { - case INPUT_OPTIONAL_DATA_PREVIEW: - - memcpy (data, this->preview, this->preview_size); - return this->preview_size; - - break; - } - - return INPUT_OPTIONAL_UNSUPPORTED; +static int http_plugin_eject_media (input_class_t *this_gen) { + return 1; /* doesn't make sense */ } -static void http_plugin_dispose (input_plugin_t *this_gen ) { - free (this_gen); -} +static void *init_class (xine_t *xine, void *data) { -static void *init_input_plugin (xine_t *xine, void *data) { + http_input_class_t *this; + config_values_t *config; - http_input_plugin_t *this; - config_values_t *config; + this = (http_input_class_t *) xine_xmalloc (sizeof (http_input_class_t)); - this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t)); - config = xine->config; - this->xine = xine; + this->xine = xine; + this->config = xine->config; + config = xine->config; - this->input_plugin.get_capabilities = http_plugin_get_capabilities; - this->input_plugin.open = http_plugin_open; - this->input_plugin.read = http_plugin_read; - this->input_plugin.read_block = http_plugin_read_block; - this->input_plugin.seek = http_plugin_seek; - this->input_plugin.get_current_pos = http_plugin_get_current_pos; - this->input_plugin.get_length = http_plugin_get_length; - this->input_plugin.get_blocksize = http_plugin_get_blocksize; - this->input_plugin.get_dir = NULL; - this->input_plugin.eject_media = http_plugin_eject_media; - this->input_plugin.get_mrl = http_plugin_get_mrl; - this->input_plugin.close = http_plugin_close; - this->input_plugin.stop = http_plugin_stop; - this->input_plugin.get_description = http_plugin_get_description; - this->input_plugin.get_identifier = http_plugin_get_identifier; - this->input_plugin.get_autoplay_list = NULL; - this->input_plugin.get_optional_data = http_plugin_get_optional_data; - this->input_plugin.dispose = http_plugin_dispose; - this->input_plugin.is_branch_possible= NULL; + this->input_class.open_plugin = open_plugin; + this->input_class.get_identifier = http_class_get_identifier; + this->input_class.get_description = http_class_get_description; + this->input_class.get_dir = NULL; + this->input_class.get_autoplay_list = NULL; + this->input_class.dispose = http_class_dispose; + this->input_class.eject_media = http_plugin_eject_media; - this->fh = -1; - this->config = config; - this->curpos = 0; - this->nbc = NULL; - return this; } @@ -728,7 +771,7 @@ static void *init_input_plugin (xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 8, "http", XINE_VERSION_CODE, NULL, init_input_plugin }, + { PLUGIN_INPUT, 9, "http", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |