Code Monkey home page Code Monkey logo

discuss's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

discuss's Issues

Socket.io sample

I've been trying to get socket.io going without any success. I found the hapi-socket plug-in, but that causes a crash, for which I've created an issue (jeltok/hapi-socket#1). Does anyone have a working sample with the latest version of Hapi?

Different way to calling callback in hapijs code stye guide

According to hapijs code style guide mentioned specific way to call callback

If a function takes a callback argument, it must be called on process.nextTick() . 
Otherwise, the argument name must be next to clearly declare that it may get
called on same tick

Which is different than usual way of calling callback. I looked around on internet but unable to find any solid reason for it. Why did hapijs choose to use this specific method to call callback ?

I am sorry if this issue is not belong to here ..

Testing Rules

Create a document that lays out the "rules" for lab test layouts for the hapijs universe. The current proposal is:

[...] function names but instead of '#name' use 'name()'
any non-func specific tests should be in the top describe
and groups should use lower case titles (e.g. 'vision' + 'multiple engines' + 'returns error on..')
testing for classes should use the class name in first char uppercase ('Response')
generic integration tests should just be in the top outside a describe

Thoughts? Concerns? Clarifications?

Consider adding a Hapi example to notejam?

I found a nice little repo showing different frameworks handling a very basic web application. I thought it would be good to have Hapi as an example as well.

Sample app to compare code complexity: expressjs vs python, php and ruby frameworks
https://github.com/komarserjio/notejam

I wouldn't mind doing this but I thought maybe someone who is part of the Hapi team might want to instead. I don't want to just port over the https://github.com/poeticninja/hapi-ninja/ boilerplate if that is not the way the Hapi people want the example to be.

Thoughts?

Odd Results from application/x-www-form-urlencoded payloads

Hi, I've got the following payload being submitted:

show[id]=55&show[title]=Black+Impulse&show[links][][kind]=twitter&show[links][][url]=https://twitter.com/blackimpulses&show[links][][title]=&show[links][][kind]=facebook&show[links][][url]=https://facebook.com/blackimpulses&show[links][][title]=&show[links][][kind]=website&show[links][][url]=http://blackimpulse.co.uk&show[links][][title]=blackimpulse.co.uk&show[links][][kind]=website&show[links][][url]=&show[links][][title]=

This is represented in our UI as:

screen shot 2014-11-12 at 7 22 02 pm

I'd expect the payload object to be parsed to something like:

{
  "show": {
    "id": "55",
    "title": "Black Impulse",
    "links": [
      {
        "kind": "twitter",
        "url": "https://twitter.com/blackimpulses",
        "title": ""
      },
      {
        "kind": "facebook",
        "url": "https://facebook.com/blackimpulses",
        "title": ""
      },
      {
        "kind": "website",
        "url": "http://blackimpulse.co.uk",
        "title": "blackimpulse.co.uk"
      },
      {
        "kind": "website",
        "url": "",
        "title": ""
      }
    ]
  }
}

Instead, I get:

{
  "show": {
    "id": "55",
    "title": "Black Impulse",
    "links": [
      {
        "kind": [
          "twitter",
          "facebook",
          "website",
          "website"
        ],
        "url": [
          "https://twitter.com/blackimpulses",
          "https://facebook.com/blackimpulses",
          "http://blackimpulse.co.uk",
          ""
        ],
        "title": [
          "",
          "",
          "blackimpulse.co.uk",
          ""
        ]
      }
    ]
  }
}

Is there a way I can get what I really want, without specifically numbering the fields in the form? Here's the HTML to the form: https://gist.github.com/miksago/0b6e344c94368169197e

At present, I'm working around it by doing an awful loop + zip thing, but it think what I'm wanting to get should be given by default.

Thoughts? Am I doing something wrong?

SPA app with html5 mode (window.history.pushState)

How to serve static directory, when html5 mode (window.history.pushState) is required by client app instead of hashbang mode?

I want to define routes, when to serve static directory. E.g.

  // It's OK
  plugin.route({
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: { path: 'public/build' }
    }
  });

  // It's OK
  plugin.route({
    method: 'GET',
    path: '/stories/{param*}',
    handler: {
      directory: { path: 'public/build' }
    }
  });

  // Problem is HERE, because this is not allowed
  plugin.route({
    method: 'GET',
    path: '/stories/{id}/{param*}',
    handler: {
      directory: { path: 'public/build' }
    }
  });

This is probably my misunderstanding of routing. So how to serve static directory when user comes to webpage and webpage uses html5 mode?

Thank you.

Authentication based on request path parameters

I would like one of my authentication scheme to be based on path parameter.

Here is what i'm trying to do for my API:

  • Every users belong to a group (at least one no more than one group)
  • Once authenticated users can only acces ressources based on his group
  • In my db : users:[{userId: 1, userName:" , userPwd:"secret", groupId:1}] groups:[{groupId:1, informations:"some infos"},{groupId:2, informations:"some other infos"}]
  • User1 GET /groups/1 return 200
  • User1 GET /groups/2 return 403

I am currently using the 'hapi-auth-basic' plugin which do not allow the validate function to look in the request. My ideas was either to :

  • create my custom authentication scheme (based on 'hapi-auth-basic') to add the request parameters as parameter of the validateFunc and first check if the name and password provided are ok and then check if the groupId in the path parameter correspond to the groupId in the db.
  • either to use 'hapi-auth-basic' normally without any change to check for password and name and return the groupId of the user in the credentials or artifact object to acces it later in the route handler and to then check between db groupId and request parameters.

Which solution do you think is better? Do you have any other ideas which could be better? Any authentication scheme which could better suit my need?

help with Views

Anyone have an example of a basic handlebars template that loads into a view?

From the hapi view tutorial, it sounds like the compiling happens on the server. So, I'm not sure what actually still needs to be in my index.html template if I'm serving it via hapi.

I'm new to both hapi and handlebars, so forgive me if this is the wrong spot to ask.

Thanks,
Don

Hapijs Multiparty function, method mapping

I read somewhere that Hapi.js had Multiparty "baked-in", I have read the Multiparty docs but I cant find any parallel in any Hapi.js file upload snippet I have seen.

  1. How does one listen for the "progress" or "part" events?
  2. How can I read the "form.bytesReceived" or "form.bytesExpected" properties?

Is there any official documentation? Thanks

Best way to forward multipart/form-data

Hi!

I have some multipart/form-data that gets posted to the webapp. I need some of the data in the webapp, but the rest should be forwarded to the API. Im currently using Wreck as my api-client.

Like this:

POST webapp/some_endpoint - { key1: "key1", key2 : "key2", "files": [file1, file2] }

POST api/{key1}/some_other_endpoint - { key1: "key1", key2 : "key2", "files": [file1, file2] }

Do I need to temp store the files etc? Do I need to create a new multipart/form-data body?

I cannot seem to find any good way todo this. Tips are welcome :)

Cannot configure Hapi view engine with an object

I am trying to configure the view engine for my server from a centralized JSON file. Below is a snippet of the part that I am using. The port setting works but the view engine part causes an error. Strangely, if I configure the server using the server instance, it works. Any idea what I'm doing wrong? Thanks

// Does not work 
development: {
        port: parseInt(process.env.PORT, 10) || 3000,
        hapi: {
            options: {
                views: {
                    path: rootPath + '/views/',
                    engines: {
                        html: require('swig')
                    }
                }
            }
        }
    },
// WORKS!
/* Configure view engine */
server.views({
    engines: {
        html: require('swig')
    },
    path: process.cwd + 'views'
});

The error:

Debug: hapi, internal, implementation, error 
    TypeError: Uncaught error: Object function (err, result) {

        return internals.wrap((err !== null && err !== undefined ? err : result), request, finalize);
    } has no method 'view'

API versioning

Are there docs on how to version APIs somewhere? Can someone point me to them? Thanks

What can we do to make this a more diverse community?

We want the hapi.js community to be the model of building and nurturing a diverse, open, and welcoming community. This can include how we name modules, what gender pronouns we use, to the makeup of the leadership, etc.

Please use this thread to highlight areas we should actively work on to improve, to list existing patterns that are offensive or discourage diversity, or to make other suggestions.

If you feel uncomfortable posting in public, please feel free to contact me directly [email protected].

And of course, this thread as all other threads must only include constructive and friendly discourse.

Many issues are open without description of it

I found many issues (specially labelled with bug) in hapijs projects without description. It is difficult to understand what exactly issue is. Please make sure that issue creator adds description to issue. This will be very helpful.

Help with a pre-handler check

Hi,

I'm looking to specify on a route config a permission that is required for a user to have to execute the route, in the config I would like to specify a string that is a permission string which a user must have, for example. 'this.permission.execute'

I would like to do a check against data i have retrieved from the database based on a session before the handler is executed. I know i could use the config.description field of the route and then get the value in a preHandler request using request.route.description and do my validation there, I just wanted to know if there was a cleaner and more efficient way of achieving what i'm trying to do

Thanks in advance.
Danny

Problems when replying with a generated file

I'm currently writing a Hapi based service for processing images with Graphicsmagick. My route handler looks something like this:

var gm      = require('gm').subClass({ imageMagick: true });
var handler = function (request, reply) {

    // Get target image size and type from parameters
    // ...

    gm(sourceImage)
        .resize(imageSize.width, imageSize.height)
        .gravity('Center')
        .stream(imageExtension, function (err, stdout, stderr) {
            if (err) { return reply(plugin.hapi.boom.badImplementation); }

            // Stream the converted image, set mime type according to file extension
            reply(stdout).type(contentTypes[fileExtension]);
        }
    );
};

This works great so far. However, I wrote a test with Lab to validate the image conversion and the streamed content is not be recognized as an image by Graphicsmagick (nor any similar image library):

var gm = require('gm').subClass({ imageMagick: true });

var server  = require('../');
var Lab = require('lab');
var lab = exports.lab = Lab.script();


lab.it('should resize the image correctly', function (done) {
    server.inject({
        url: '/my/image/300x300',
        header: { 'Accept-Encoding': 'identity' }
    }, function (res) {
        // Read the size (width and height) of the given image
        gm(res.rawPayload).size({bufferStream: true}, function (err, value) {
            // This breaks, because gm could not identify the image type based on the given stream
            Lab.expect( value.size ).to.equal('300x300');
            done();
        });
    });
});

Did I miss something while creating the stream response? I also noticed, that Hapi still sets Content-Encoding: gzip even for (already compressed) image binaries, regardless of the Accept-Encoding setting (normally, only text based files should be gzipped). Is there a way to disable this?

Stream results straight from the db

I'm trying to use hapi with node-mysql to create a rest api. I've not used streams in anger and am trying to work out where I'm going wrong. This is my route config:

    { 
        method: 'GET', 
        path: '/query/stream', 
        config: { auth: false }, 
        handler: function(request, reply) {
            var query = db.query('SELECT * FROM user LIMIT 5000');

            reply(query.stream());
        }
    }

db is a connection pool created using mysql.createPool().

This is the error:

Debug: hapi, internal, implementation, error
    TypeError: first argument must be a string or Buffer
    at ServerResponse.OutgoingMessage.write (http.js:851:11)

Any help would be much appreciated, thanks

Contributing in hapijs organization project

I am wiling to contribute in project from this organization. Where is great place to start contribution ? Can we have single place where contributor can check issue they can solve from various repository of organization ?

trying something out

I think the merits in this idea are there not sure on execution.

But based on the ideas of hapis server config been thinking it could be possible to pull together solutions faster using services.

https://github.com/dreamineering/the-bach

I've mainly been working on front end stuff but really want to get into services side of things and very keen to learn and hopefully teach some ideas around hapi so other developers can get up to speed quickly.

Support for multiple static folders?

Is there support for multiple static folders? I tried the following and it did not work, all the files in the second folder were not found. Thanks

server.route({
    method: 'GET',
    path: '/{path*}',
    handler: {
        directory: {
            path: 'bower_components',
            listing: false
        }
    }
});
server.route({
    method: 'GET',
    path: '/assets/{path*}',
    handler: {
        directory: {
            path: './../client/app',
            listing: false
        }
    }
});

Using prerequisites for almost everything?

How convenient is there to use prerequisites for most of the code? Or is this a bad way to use the prerequisites?

Example if you split it up like this:

  • Route prerequisites for validation (things that joi can't handle), getting data from the database, etc
  • Route handler to only create a json/view from the prerequisites results.

The handlers will be very lightweight and the prerequisites will be reusable.

Code example:

{
    method: 'POST',
    path: '/api/news',
    config: {
        handler: function(request, reply){
                       reply.redirect('news/' + request.pre.news.id);
                },
        pre : [
                 { method: 'validateSomeDataAgainsDatabase' },
                 { method: 'getUserFromDataBase', assign: 'user' },
                 { method: 'insertNewsIntoDatabase', assign: 'news' }
                ]
        }
}

Any great minds out there with some opinions? Thanks :)

registerPartials/registerHelpers server-side

Hapi has these paths
path: the directory that contains your main templates
partialsPath: the directory that contains your partials
helpersPath: the directory that contains your template helpers
http://hapijs.com/tutorials/views

If you have Handlebars partials on the server stored in partialsPath or if you have helpers stored in helpersPath, how do you register them in a template stored in path so that when you reply with the rendered view, it works?

Or is it automatic?
for example, would it automatically search the partialsPath for a person.html file and just use it?
{{#each people}}
{{> person}}
{{/each}}

Thanks.
Don

ES6 Generators

I noticed recently big excitement about Generators in Node > 0.11.2. Probably most noticeable is new framework koajs, which utilizes Generators instead of callbacks. Main goal is to create easier code to read, without callbacks.

I know that it still can take some time before 0.12 gets around and becomes production ready. Just wondering if you have considered utilizing Generators inside Hapi in future. For some reason frameworks which make async code look like sync are fairly popular (meteor, koajs).

Error handling on prerequisites.

What's the best way to handle errors on prerequisites without coupling HTTP to internal functionality? Let's assume that I want to validate if a given thing exists in a database, before something else, and then return a HTTP 404 error to the client if it does not. Should I deal with Boom instances directly on the server method used as prerequisite or on the handler?

getting 403 with crumb

this is my crumb setup

var crumb = {
    plugin: require('crumb'),
    options: {
        cookieOptions: {
            isSecure: false
        },
        size: 256,
        restful: true
    }
};

making a POST to

{
        path: '/test-route',
        method: 'POST',
        handler: webControllers.test
}

webControllers.test looks like

test: function(req, rep){
        console.log(req.headers);
        rep('taaddaaaa');
    },

I get a 403. Looking a the request parameters looks like the cookie with the crumb is getting passed. I am not sure what am I doing wrong. My apologies for my n00bness!

Help with dynamic routing

I'm building a stub service powered by MongoDB. Routes are added to the server on server start and when a new stub service is added to the DB. I need the ability to remove/unregister a route while the server is still running after a stub service is deleted from the DB.

Is this possible in Hapi?

Logging request and response payloads in Hapi.js using Good

I am using Hapi.js to implement RESTful API for my mobile application. I have integrated Good for logging requests, errors, and other events. It works very well for me. However it is not clear how to log request and response payloads (JSON objects) to console and file.

I would appreciate any help.

Creating a REST Api using hapi

Hi , I am new to Hapi and this is a very basic question.

We are planning to create a REST Api using Hapi.
Our Application has different features like Chat , Forums Quiz etc. Now my question is should I create separate plugins for these features or just follow the basic this ie, creating routes,handlers, validation etc.

Which is a better way for structuring the entire code?

(I had asked this query in hapijs/hapi#2204. Since this is the correct platform I am asking the question again here)

Calling reply.redirect from a plugin

Hello,

I have a scenario where I want to redirect to an URL from within a plugin, before the request is processed further down the request lifecycle.

I wrote a plugin that looks something like this:

plugin.ext('onRequest', function(request, reply)) {
  if(someCondition) {
    reply.redirect(somePath);
  } else {
    reply();
  }
}

It seems however that my redirect call is ignored, and the request follows trough as as normal. Am i missing something here?

Regards,
Daniel

Socket.io and Hapi-auth-cookie session management.

I have implemented cookie based authentication session for Hapi application using hapi-auth-cookie plugin. I want to use same session in socket.io.

I know I would have to use iron to validate the cookie. But I don't know how to use Iron directly, with the cookie configuration I have set for plugin.

io.set('authorization', function (handshakeData, accept) {
    var cookies;

    if (handshakeData.headers.cookie) {

        cookies = cookie.parse(handshakeData.headers.cookie);
        if (cookies['sid']) {
            // Code to verify cookie.
            return accept(null, true);
        }

    } else {
        return accept('No cookie transmitted.', false);
    } 

    accept(null, false);
});

I need help with writing // code to verify the cookie.

How to use HAPI to call back the interface

I am building a social network and there are a lot of times that I need to get the last activities, so I call using AJAX a rout, get the count of activities and how the user.

But I am not sure how I can call a HAPI route as a new activity happens, than I receive from the server the new count, without having to query again.

Keep the socket connection open, so that I can reply back to all that opnened this socket with the server.

Any examples or pointers of how to do it using HAPI would be great.

Authentication problem when using Yahoo Sports API

I'm using bell for yahoo authentication. I then am using wreck to make a call to the specific api. My best guess is that the api call itself needs the access token, but I don't see that token in the authentication data returned after logging in.

Authentication bit:

  server.route({
    method: ['GET', 'POST'], // Must handle both GET and POST
    path: '/login',          // The callback endpoint registered with the provider
    config: {
      auth: 'yahoo',
      plugins: {
        'hapi-auth-cookie': {
          redirectTo: false
        }
      },
      handler: function (request, reply) {
        var creds = {};
        creds.creds = request.auth.credentials;
        creds.token = request.query.oauth_token;
        request.auth.session.set(creds);
        return reply.redirect('/');
      }
    }
  });

Api call:

  server.route({
    method: 'GET',
    path: '/',
    config: {
      auth: 'session'
    },
    handler: function (request, reply) {

      var url = 'https://fantasysports.yahooapis.com/fantasy/v2/leagues;league_keys=328.l.5668/standings?format=json';

      Wreck.get(url, function (err, res, payload) {
        console.log(payload);
      });

      reply.view('index', { title: 'hello world' });
    }
  });

The payload in the wreck call is:

{"error":
  {
    "lang":"en-US",
    "description": "Please provide valid credentials. OAuth oauth_problem=\"unable_to_determine_oauth_type\",
    realm=\"yahooapis.com\""
  }
}

session_handle using bell

Hi,
I'm using bell to login with Yahoo. It provides the access token and secret once logged in, however it seems that it does not provide the session_handle, unless I've missed something. Is there a way to expose this property?

Thank you.

Preferred way to inject depenencies

What is the preferred way to inject dependencies? I have a few application settings that I would like to use in various parts of my application

Preferred way to create range routes in Hapi

Coming from Express. I could get resource ranges. for example, to get users 1 to 5

/api/v2/users/1..5

this.get(path + '/:a..:b.:format?', function(req, res) {
        var a = parseInt(req.params.a, 10);
        var b = parseInt(req.params.b, 10);
        var format = req.params.format;
        range(req, res, a, b, format);
    });

range: function(req, res, a, b, format) {    
        var range = profiles.slice(a, b + 1);
        switch (format) {
            case 'json':
                res.send(range);
                break;
            case 'html':
            default:
                var html = '<ul>' + range.map(function(user) {
                    return '<li>' + user.name + '</li>';
                }).join('\n') + '</ul>';
                res.send(html);
                break;
        }
    }

How can I achieve this using Hapi.js? Thanks

File upload with multipart/form-data and application/json

Following the issue at hapijs/hapi.

I'm trying to implement a small file upload module that would support either multipart/form-data and application/json.

One of the requirements is to be able to pipe the image to another server.
A test case can be seen here: https://gist.github.com/Couto/127ca8a6bd28ecc4a084

What would be best way to handle multiple types of uploads on the same endpoint, or how would you think it would be best solution to handle this?

Coding style/quality tooling

I think it would be good practice to have a bit more tooling around hapi development process.
What about creating a set of rules for jshint/eslint and jscs ?
Linting might spot a few bugs and jscs would help contributors about the strict styling enforced in the project.

Dynamic schema/validation of input

Hi! I want to pass a custom validation schema to validate input. A query parameter in the GET url will be used to retrieve an object from the database, which I will then use to build a validation schema based on the rules defined in that object. I then want to pass that schema to validate input parameters.

Is this possible / is there a recommended way to achieve this? Thanks

Use Strict

Can anyone list a conclusive negative reason against using "use strict" in the hapijs modules? There are documented cases where omitting "use strict" will prevent v8 optimization where adding "use strict" allows the code to be optimized.

It would also suss out bad practices and mistakes before PRs are even opened.

From what I've read, worse case scenario is "use strict" does nothing and is just a magic string at the top of a file.

Invoking a route from another route

I have 2 routes on my api, /album and /song and as such, I have 2 handler functions. What I want to do is when I call /album, the handler will sometimes want to gather information about the songs in one round trip to the server. Is there a pre-described way of calling a route handler from inside another route handler? I figured you could access the server route table and trigger the call manually but it feels really dirty.

deploying on boxes with multiple cores

what's everybody using for this? i was using pm2 for a bit but after this i've been messing around with liveswap.

it'd be cool to hear if someone's got a slick combo of a simple tool/the hapi cli/good logging figured out...

Add default scope to all routes?

I want to add an "internal" scope to all routes and then add additional scopes to certain routes that regular users and/or admins can access. Is there a way I can do this?

How to catch view rendering errors and replace the response

We want to have a good catch-all exception page for our application.

We have achieved this if we ever have errors triggered within our handlers using a onPreResponse event as described here: http://hapijs.com/api/#error-transformation.

However if there is an error triggered when the view is being rendered (due to bad data into the view context), how can we catch those errors and replace the response? It seems that the view rendering is being done after the onPreResponse event.

Creating a plugin for Superfeedr

I wanted to check out Hapi for a long time and I took a couple hours today to do so! This is great :)
In order to have a "real-world" example to play with, I decided to create a plugin to interract with Superfeedr from a Hapi app. One could create a simple feed reader with it for example, or a tool like IFTTT... etc.

Anyway, I cam up with this "stub":

var path = require('path');
var urlParser = require('url');
var http = require('http');
var https = require('https');
var querystring = require('querystring');


exports.register = function (plugin, options, next) {

  // Sends a request to Superfeedr. Do not use directly. Use the subscribe and unsubscribe methods rather!
  plugin._superfeedrRequest = function(mode, url, id, opts, cb) {
    var post_data = querystring.stringify({
      'hub.mode': mode,
      'hub.topic': url,
      'hub.callback': urlParser.format({
        'protocol': options.webhooks.scheme,
        'hostname': options.webhooks.host,
        'port': options.webhooks.port,
        'pathname': path.join(options.webhooks.base, id)
      })
    });

    if(opts.retrieve) {
      post_data['retrieve'] = true;
    }
    if(opts.format) {
      post_data['format'] = opts.format;
    }
    if(opts.secret) {
      post_data['hub.secret'] = opts.secret;
    }

    var post_options = {
      'host': 'push.superfeedr.com',
      'port': '443',
      'path': '/',
      'auth': [options.login, options.password].join(':'),
      'method': 'POST',
      'headers': {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': post_data.length
      }
    };

    var post_req = https.request(post_options, function(res) {
      var data = '';
      res.setEncoding('utf8');
      res.on('data', function (chunk) {
        data += chunk;
      });
      res.on('end', function() {
        if(res.statusCode == 204 || res.statusCode == 200) {
          cb(null, data);
        }
        else {
          cb(new Error(res.statusCode, data));
        }
      })
    });

    post_req.write(post_data);
    post_req.end();
  }

  // Subscribe is called from anywhere in the hapi app like this
  // Params
  // - url: url of the feed/topic to which you want to subscribe
  // - id: unique id of the feed/topic uou want to subscribe. This is important to identify unique notifications. You should use some kind of primary key.
  // - opts: 
  //      - retrieve: set to true if you want previous items from the feed
  //      - format: 'atom' or 'json'
  //      - secret: a unique secret used to compute an HMAC key for notifications. 
  // - the callback will be called with the result of the subscription. First param is error, second param is body if retrieve:true.
  plugin.subscribe = function(url, id, opts, cb) {
    plugin._superfeedrRequest('subscribe', url, id, opts, cb);
  }

  // Unsubscribe is called from anywhere in the hapi app like this
  // Params
  // - url: url of the feed/topic to which you want to subscribe
  // - id: unique id of the feed/topic that you used to subscribe
  // - the callback will be called with the result of the subscription. First param is error, second param is body if retrieve:true.
  plugin.unsubscribe = function(url, id, cb) {
    plugin._superfeedrRequest('unsubscribe', url, id, {}, cb);
  }


  plugin.route({
    method: 'POST',
    path: path.join(options.webhooks.base, '{feed_id?}'),
    handler: function(request, reply) {
      // The event is triggered so that anyone who listens to 'notification' on the superfeedr plugin (how do we do that?)
      // will recive the feed_id, the RAWBODY (if we are able to extract it), the topic/feed url and the request object
      // if they want to debug it.
      plugin.events.emit('notification', request.params.feed_id, RAWBODY, request.headers['x-pubsubhubbub-topic'], request);
      reply('Thanks Superfeedr');
    }
  });

  next();
}

exports.register.attributes = {
  multiple: false,
  name: 'Superfeedr',
  version: '1.0.0'
};

From there, there are several questions/problems that I have:

  • When getting notifications from a feed(RSS/Atom) our default is to send the payload as application/atom+xml. Hapi does not like this and serves a 415. Any idea why? Can we force Hapi to be a little bit more agnostic? If not, we can still force subsriptions to JSON.
  • Once the plugin is registered I believe people should be able to call something like server.plugins.superfeedr.subscribe('http://...', '123', {}, function() {...}); right? The problem is that server.plugins is desperately empty ({}) everywhere in my app. Any idea why?
  • On notifications, we need to be able to extract the raw body of the POST request. arv in the #hapi chatrooms seems to indicate that this is not possible. It's a HUGE bummer because that means we'll never be able to use Atom and WORSE, we can never compute an HMAC signature of the raw body to authenticate the sender. If anyone guesses the webhook url, they'll be able to forge requests. So, is the raw body never exposed?
  • The chatroom indicates as well that each plugin is an event emitter: awesome! so we assume people will be able to do something like server.plugins.events.on('notification', function(feed_id, body, url, request) {...}); but... server.plugins is still empty :(

Any help with any of these issues would be greatly appreciated!

hapi API doc a bit to ... list-y

I've just started playing with hapi, and so have been visiting the API doc a lot.

Awesome to see this level of detail in the doc - much thanks!

OTOH, I've found the various "object schema" there to be difficult to follow, as they often seem to become deeply nested <ul>'s. It seems like it could be improved, but not sure the best course of action.

Some thoughts:

  • make the ul's at a certain level (2nd?) expandable/collapsable via a button
  • describe each object at the top-level, with a name associated with it, and then refer to that structure by linked name as needed
  • deeper indentation (a few em's)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.