mirror of
https://git.code.sf.net/p/minidlna/git
synced 2025-03-30 04:08:05 +00:00
The idea is taken from the nginx web server, but much simplified and almost no copypaste left. This will allow minidlna to use different event dispatcher APIs, which would be defined at compile time. My personal goal is to convert minidlna to kqueue(2) on FreeBSD. This would later allow for kqueue based directory change notification, which won't conflict with select(2) like the current patch does. Other platforms will also benefit from the pluggability of the event system, Linux can switch to epoll(2) or at least to poll(2). Detailed list of changes: * event.h [New] Our internal API to unify different event dispatch systems. * select.c [New] Much simplified version of nginx's ngx_select_module.c. * minidlna.c - Split out listen socket event processing into separate function ProcessListen(), which matches event_process_t type. - Create and initialize struct event for the monitor socket, SSDP socket, HTTP socket and beacon socket. - Simplify and make more precise timeout calculation using helper timeval functions from utils.c. Treat gettimeofday() error as a fatal event. - Rip out all stuff related to select(2). Just call event_module.process(). * upnpevents.c - Embed struct event into upnp_event_notify. - Merge upnp_event_create_notify() with upnp_event_notify_connect(). Start connecting immediately after socket creation. Garbage collect now useless ECreated state. - Make upnp_event_process_notify() of event_process_t type, and use it as process callback for upnp_event_notify event. - Looks like we always create upnp_event_notify with existing subscriber, and never clear it later. Remove checks for obj->sub and assert that it is never NULL. Simplifies things. - When switching obj state, add/del it to event dispatcher accrodingly. - Garbage collect upnpevents_selectfds(). - Garbage collect select(2) related stuff from upnpevents_processfds(). Rename function to upnpevents_gc(), since the remaining functionality is garbage collecting, not file descriptor processing. Actually, this can be simplified even more. We can safely close sockets and free objects immediately, eliminating need for upnpevents_gc(). But this change would be beyond scope of this commit. * upnphttp.c, upnphttp.h Embed struct event into struct upnphttp. Adjust Process_upnphttp() to match event_process_t type. Add/del to event dispatcher once creating/closing a socket. * minissdp.c, minissdp.h Make ProcessSSDPRequest() of event_process_t type. * getifaddr.c, getifaddr.h Make ProcessMonitorEvent() of event_process_t type.
180 lines
5.3 KiB
C
180 lines
5.3 KiB
C
/* MiniDLNA project
|
|
*
|
|
* http://sourceforge.net/projects/minidlna/
|
|
*
|
|
* MiniDLNA media server
|
|
* Copyright (C) 2008-2012 Justin Maggard
|
|
*
|
|
* This file is part of MiniDLNA.
|
|
*
|
|
* MiniDLNA is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* MiniDLNA is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Portions of the code from the MiniUPnP project:
|
|
*
|
|
* Copyright (c) 2006-2007, Thomas Bernard
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#ifndef __UPNPHTTP_H__
|
|
#define __UPNPHTTP_H__
|
|
|
|
#include <netinet/in.h>
|
|
#include <sys/queue.h>
|
|
|
|
#include "minidlnatypes.h"
|
|
#include "config.h"
|
|
|
|
/* server: HTTP header returned in all HTTP responses : */
|
|
#define MINIDLNA_SERVER_STRING OS_VERSION " DLNADOC/1.50 UPnP/1.0 " SERVER_NAME "/" MINIDLNA_VERSION
|
|
|
|
/*
|
|
states :
|
|
0 - waiting for data to read
|
|
1 - waiting for HTTP Post Content.
|
|
...
|
|
>= 100 - to be deleted
|
|
*/
|
|
enum httpCommands {
|
|
EUnknown = 0,
|
|
EGet,
|
|
EPost,
|
|
EHead,
|
|
ESubscribe,
|
|
EUnSubscribe
|
|
};
|
|
|
|
struct upnphttp {
|
|
struct event ev;
|
|
struct in_addr clientaddr; /* client address */
|
|
int iface;
|
|
int state;
|
|
char HttpVer[16];
|
|
/* request */
|
|
char * req_buf;
|
|
int req_buflen;
|
|
int req_contentlen;
|
|
int req_contentoff; /* header length */
|
|
enum httpCommands req_command;
|
|
struct client_cache_s * req_client;
|
|
const char * req_soapAction;
|
|
int req_soapActionLen;
|
|
const char * req_Callback; /* For SUBSCRIBE */
|
|
int req_CallbackLen;
|
|
const char * req_NT;
|
|
int req_NTLen;
|
|
int req_Timeout;
|
|
const char * req_SID; /* For UNSUBSCRIBE */
|
|
int req_SIDLen;
|
|
off_t req_RangeStart;
|
|
off_t req_RangeEnd;
|
|
long int req_chunklen;
|
|
uint32_t reqflags;
|
|
/* response */
|
|
char * res_buf;
|
|
int res_buflen;
|
|
int res_buf_alloclen;
|
|
uint32_t respflags;
|
|
/*int res_contentlen;*/
|
|
/*int res_contentoff;*/ /* header length */
|
|
LIST_ENTRY(upnphttp) entries;
|
|
};
|
|
|
|
#define FLAG_TIMEOUT 0x00000001
|
|
#define FLAG_SID 0x00000002
|
|
#define FLAG_RANGE 0x00000004
|
|
#define FLAG_HOST 0x00000008
|
|
#define FLAG_LANGUAGE 0x00000010
|
|
|
|
#define FLAG_INVALID_REQ 0x00000040
|
|
#define FLAG_HTML 0x00000080
|
|
|
|
#define FLAG_CHUNKED 0x00000100
|
|
#define FLAG_TIMESEEK 0x00000200
|
|
#define FLAG_REALTIMEINFO 0x00000400
|
|
#define FLAG_PLAYSPEED 0x00000800
|
|
#define FLAG_XFERSTREAMING 0x00001000
|
|
#define FLAG_XFERINTERACTIVE 0x00002000
|
|
#define FLAG_XFERBACKGROUND 0x00004000
|
|
#define FLAG_CAPTION 0x00008000
|
|
|
|
#ifndef MSG_MORE
|
|
#define MSG_MORE 0
|
|
#endif
|
|
|
|
/* New_upnphttp() */
|
|
struct upnphttp *
|
|
New_upnphttp(int);
|
|
|
|
/* CloseSocket_upnphttp() */
|
|
void
|
|
CloseSocket_upnphttp(struct upnphttp *);
|
|
|
|
/* Delete_upnphttp() */
|
|
void
|
|
Delete_upnphttp(struct upnphttp *);
|
|
|
|
/* BuildHeader_upnphttp()
|
|
* build the header for the HTTP Response
|
|
* also allocate the buffer for body data */
|
|
void
|
|
BuildHeader_upnphttp(struct upnphttp * h, int respcode,
|
|
const char * respmsg,
|
|
int bodylen);
|
|
|
|
/* BuildResp_upnphttp()
|
|
* fill the res_buf buffer with the complete
|
|
* HTTP 200 OK response from the body passed as argument */
|
|
void
|
|
BuildResp_upnphttp(struct upnphttp *, const char *, int);
|
|
|
|
/* BuildResp2_upnphttp()
|
|
* same but with given response code/message */
|
|
void
|
|
BuildResp2_upnphttp(struct upnphttp * h, int respcode,
|
|
const char * respmsg,
|
|
const char * body, int bodylen);
|
|
|
|
/* Error messages */
|
|
void
|
|
Send500(struct upnphttp *);
|
|
void
|
|
Send501(struct upnphttp *);
|
|
|
|
/* SendResp_upnphttp() */
|
|
void
|
|
SendResp_upnphttp(struct upnphttp *);
|
|
|
|
#endif
|
|
|