⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upnphosting.java

📁 国外的j2me播放器软件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                        System.out.println("Request is UNSUBSCRIBE");
                        req.requestMethod = REQUEST_METHOD_UNSUBSCRIBE;
                        response = handleUnsubscribeRequest(req);
*/                    
                    } else {
                        time = System.currentTimeMillis();
                        System.out.println("[" + Thread.currentThread()+ "][" + time +"] Unknown request method");

                        StringBuffer responseBuf = new StringBuffer(2048);
                        responseBuf.append("HTTP/1.1 501 Not Implemented\r\n");
                        responseBuf.append("Connection: close\r\n");
                        responseBuf.append("Content-Length: 0\r\n");
                        responseBuf.append("\r\n");
                        response = responseBuf.toString().getBytes();
                    }
                }
                
                /* XXX Should use exceptions for error conditions instead
                if (response == null) {
                    StringBuffer responseBuf = new StringBuffer(2048);
                    responseBuf.append(
                        "HTTP/1.1 500 Internal Server Error\r\n");
                    responseBuf.append("Content-Length: 0\r\n");
                    responseBuf.append("Date: ");
                    responseBuf.append(Utilities.getRfcDateString(
                        Calendar.getInstance(TimeZone.getTimeZone("GMT"))));
                    responseBuf.append("\r\n");
                    responseBuf.append("\r\n");
                    response = responseBuf.toString().getBytes();
                }
                */

                if (response != null) {
                    OutputStream os = sc.openOutputStream();
                    os.write(response);
                    os.close();
                }
            } catch (Exception e) {
                long time = System.currentTimeMillis();
                System.out.println("[" + Thread.currentThread()+ "][" + time +"] Exception occured in UPnPHosting::ConnectionHandler");
                LOG.warn(e);
                e.printStackTrace();
            } finally {
                try { 
                    sc.close();
                } catch (Exception e) {
                    LOG.debug("[" + Thread.currentThread()+ "] Error closing this connection");
                }
                
                decrementNumRequestsHandling();

                long time = System.currentTimeMillis();
                System.out.println("[" + Thread.currentThread()+ "][" + time +"] Finished handling the request");
            }
        }

        /**
         * Creates a hashtable with the headers from the request.
         *
         * @return Hashtable with key=header-name and value=header-value
         */
        private void setRequestHeaders(String request, HttpRequest req) {
            //    
            // Create a hashtable of the headers
            // XXX Could try to rewrite the while-loop to use the request 
            //     instead, so this step won't be required.
            //     1) Must start at request.indexOf("\r\n") + 2
            //     2) Must end before "\r\n\r\n"
            String headersText = request.substring(
                request.indexOf("\r\n") + 2, 
                request.indexOf("\r\n\r\n") + 1);

            int prevPos = 0, pos = 0;
            while ((pos = headersText.indexOf(':', prevPos)) >= 0) {
                String header = headersText.substring(prevPos, pos).trim();
                prevPos = pos;
                pos = headersText.indexOf('\r', pos);
                String headerValue = headersText.substring(prevPos + 1, pos).trim();
                req.setHeader(header, headerValue);
                prevPos = pos;
            }
        }
    }

    /**
     * Register a handler for GET requests for a specific namespace.
     *
     * This method makes it possible to have a namespace, such as /device or 
     * /content, be controlled by different handler objects which knows how 
     * to handle requests to this namespace.
     *
     * @param namespace Which namespace to handle by this handler
     * 
     * @param handler Object which will handle requests to this namespace.
     *
     * @return If this namespace was not handled earlier then null, otherwise 
     *         the object of the old handler.
     */
    public HttpRequestHandler registerHttpHandler(
        String namespace, 
        HttpRequestHandler handler) 
    {
        return (HttpRequestHandler)httpRequestHandlers.put(namespace, handler);
    }

    /**
     * Is a namespace handled by someone?
     */
    public boolean isNamespaceHandled(String namespace) {
        return httpRequestHandlers.containsKey(namespace);
    }

    /**
     * Get namespace handler.
     */
    public HttpRequestHandler getHttpRequestHandlerForNamespace(String namespace) {
        return (HttpRequestHandler)httpRequestHandlers.get(namespace);
    }

    /**
     * Remove HTTP Request handler.
     *
     * @param namespace Namespace of the HTTP request handler to remove.
     *
     * @return HTTP Request handler of this namespace.
     */
    public HttpRequestHandler removeHttpRequestHandler(String namespace) {
        return (HttpRequestHandler)httpRequestHandlers.remove(namespace);
    }

    /**
     * Generates description documents.
     *
     * Will create a device description document and one service description 
     * document for each service offered by the device.
     */
    public void registerDevice(UPnPHostingDevice device) {
        try {
            int recordId = -1;

/* XXX Unfortunately get ArrayIndexOutOfBoundsException due to enumerating the 
       cache here :/
                   
            // 
            // Check if device desc is already cached
            //
            if (descriptionDocumentCache.getNumRecords() > 0) {
                RecordEnumeration re = descriptionDocumentCache.enumerateRecords(
                    new DeviceFilter(device.udn()), 
                    null, 
                    true);
                System.out.println("RecordEnumeration created");
                
                /*
                  Can not use the following code until the port number is static, 
                  because the device description contains the URL Base which 
                  contains IP address + port number
                if (!re.hasNextElement()) {
                    System.out.println(
                        "Device description does not exist yet. Generating it now.");
                    String devDesc = generateDeviceDescription(device);
                    byte[] desc = devDesc.getBytes();
                    recordId = descriptionDocumentCache.addRecord(desc, 0, desc.length);
                } else {
                    System.out.println("Number of records found: " + re.numRecords());
                    recordId = re.nextRecordId();
                }
                *x/

                //
                // Delete the cache if it already exists
                //
                if (re.hasNextElement()) {
                    System.out.println("Seems like the device already exists in the cache");
                    descriptionDocumentCache.deleteRecord(re.nextRecordId());
                    System.out.println("Device deleted from record store");
                }
                
                re.destroy();
            }
*/            

            String devDesc = generateDeviceDescription(device);
            byte[] desc = devDesc.getBytes();
            recordId = descriptionDocumentCache.addRecord(desc, 0, desc.length);
    
            //
            // Generate service description documents
            for (Enumeration e = device.serviceTable().elements(); 
                 e.hasMoreElements(); ) 
            {
                UPnPHostingService service = (UPnPHostingService)e.nextElement();
                desc = generateServiceDescription(service).getBytes();
                int serviceRecordId = descriptionDocumentCache.addRecord(
                    desc, 
                    0, 
                    desc.length);
                entities.put(
                    service.serviceId().replace(':', '_'), 
                    new HostingCacheContainer(
                        serviceRecordId,
                        service));
            }
    
            entities.put(
                    device.udn().replace(':', '_'), 
                    new HostingCacheContainer(recordId, device));

            // 
            // Schedule a timer to send notifications about the device + 
            // services.
            // 
            notificationTimer.schedule(new DeviceNotificationTask(device), 0, notifyPeriod * 1000);
        } catch (RecordStoreNotOpenException rsnoe) {
            LOG.fatal(rsnoe);
        } catch (RecordStoreException rse) {
            LOG.fatal(rse);
        }
    }

    private final class DeviceFilter implements RecordFilter {
        private String udn;
        
        public DeviceFilter(String udn) {
            System.out.println("DeviceFilter ctor: " + udn);
            this.udn = udn;
        }
            
        public boolean matches(byte[] candidate) {
            System.out.println("Check if candidate matches device UDN(" + udn + ")");
            String desc = new String(candidate);

            return (desc.indexOf(udn) != -1) ? true : false;
        }
    }

    /**
     * Sends a ssdp:alive message for the device associated with this 
     * instance.
     */
    private final class DeviceNotificationTask extends TimerTask {
        private UPnPHostingDevice device;

        public DeviceNotificationTask(UPnPHostingDevice device) {
            this.device = device;
        }
        
        public void run() {
            /*
                When a device is added to the network, it multicasts discovery 
                messages to advertise its root device, to advertise any 
                embedded devices, and to advertise its services.
                
                To advertise its capabilities, a device multicasts a number of discovery messages. 
                Specifically, a root device must multicast: 

                    Three discovery messages for the root device.   
                        1 root device UUID **               root device UUID 
                        2 device type : device version      root device UUID and :: 
                                                            and device type : device version 
                        3 upnp:rootdevice                   root device UUID and :: and 
                                                            upnp:rootdevice 

                    Two discovery messages for each embedded device.
                        1 embedded device UUID **           embedded device UUID 
                        2 device type : device version      embedded device UUID and :: and device 
                                                            type : device version 

                    Once for each service.
                        1 service type : service version    enclosing device UUID and :: and service 
                                                            type : service version 
            */

            try {
                Hashtable serviceTable = device.serviceTable();
                
                // Calculate the amount of packets to send
                //
                int numMsgsNeeded = 3 + serviceTable.size(); // Drop embedded devices
                
                String[][] headerPairsNtAndUsn = new String[numMsgsNeeded][2];
    
                //
                // NT = root device UUID
                headerPairsNtAndUsn[0] = new String[]{
                    device.udn(),
                    device.udn()};
    
                //
                // NT = device type : device version
                headerPairsNtAndUsn[1] = new String[]{
                    device.deviceType(),
                    device.udn() + "::" + device.deviceType()};
    
                //
                // NT = upnp:rootdevice

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -