bykof / cordova-plugin-webserver

A webserver plugin for cordova
Other
119 stars 51 forks source link

Point webserver to dataDirectory? #59

Open AEiosApp opened 4 years ago

AEiosApp commented 4 years ago

Dear @bykof , you have a great solution, I was able to integrate it into my app, but the only very valuable thing I can't handle is: I need to point webserver to device dataDirectory (e.g. cordova.file.dataDirectory), to be able put there several files (e.g. http://localhost:8084/myimage.png etc) and after call them within the app.

My I ask you a favor to implement this feature? Can I collaborate/donate your project in any way?

I saw that GCDWebServer has a method addGETHandlerForBasePath to do it https://stackoverflow.com/questions/30984084/gcdwebserver-static-files-from-documents Unfortunately I don't have enough skills to modify your plugin ((

AEiosApp commented 4 years ago

I recently found a solution !!!

Every time web server detects GET request it calls onRequest() method and returns in request path parameter, a part of request link following http://localhost:8080 e.g. requesting: http://localhost:8080/images/myimage.png onRequest() will return: path: ‘images/myimage.png’

sendResponse() method in the documentation example is inclosed into onRequest() method, so every time I’m requesting different file, I can overwrite parameter path in sendResponse() method

So, requesting file from my dataDirectory I have to:

1. Get dataDirectory path, for example with cordova file plugin I will receive:

for iOS:
    `file:///var/mobile/Containers…./Library/NoCloud/`
for Android:
    `file:///data/user/0…./files/`

2. Shrink ‘file://’ part for both iOS and Android, otherwise it won’t work, to get:

for iOS:
    `/var/mobile/Containers…./Library/NoCloud/`
for Android:
    `/data/user/0…./files/`

3. Shrink last character ‘/‘ , because path from onRequest() will already starts with ‘/’, to get:

for iOS:
    `/var/mobile/Containers…./Library/NoCloud`
for Android:
    `/data/user/0…./files`

4. Add path from onRequest() to the dataDirectory shrinked path, to get:

for iOS:
    `/var/mobile/Containers…./Library/NoCloud/images/myimage.png`
for Android:
    `/data/user/0…./files/images/myimage.png`

5. Pass the path that we got to the path parameter of sendResponse() method.

IMPORTANT NOTE!!! I enclosed sendResponse() method into 3 sec timeout, otherwise path parameter from onRequest() in the most of cases arrives later than fires sendRespose() and the target link isn’t updated. If anybody will offer some fancy way to make it with async or promise - will be great!

Here is my code (for my Vuejs app), that I’m calling once when the app launched to start a server:

var mydata = cordova.file.dataDirectory

startServer () {
      var me = this
      window.webserver.onRequest(
        function (request) {
          console.log('O MA GAWD! This is the request: ', JSON.stringify(request))
          var servRoot = me.mydata.substring(7, me.mydata.length)
          servRoot = servRoot.substring(0, servRoot.length - 1)
          servRoot = servRoot + request.path
          setTimeout(
            window.webserver.sendResponse(
              request.requestId,
              {
                status: 200,
                path: servRoot,
                headers: {
                }
              }
            ), 3000)
        }
      )
      window.webserver.start(
        function () {
        },
        function (error) {
          console.log('Error starting server ((' + error)
        },
        8080
      )
    }