Menu Close

Server-Side Development with Hapi.js — Content-Type and Crypto

Hapi.js is a small Node framework for developing back end web apps.

In this article, we’ll look at how to create back end apps with Hapi.js.

Parsing Content-Type Header

We can parse the Content-Type request header by using the @hapi/content module.

For instance, we can do this by writing:

const Hapi = require('@hapi/hapi');
const Content = require('@hapi/content');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      const type = Content.type('application/json; some=property; and="another"');
      return type
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

We call Content.type with the Content-Type request header string to parse it.

Then we get:

{"mime":"application/json"}

as the value of type .

Parse Content-Disposition Header

Also, we can use the Content.disposition method to generate an object from the Content-Disposition request header value.

To do this, we write:

const Hapi = require('@hapi/hapi');
const Content = require('@hapi/content');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      const disp = Content.disposition('form-data; name="file"; filename=file.jpg');
      return disp
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

Then we get:

{"name":"file","filename":"file.jpg"}

as the value of disp .

CSRF Crumb Generation and Validation

We can generate the CSRF crumb and validate it with the @hapi/crumb module.

For example, we can use it by writing:

const Hapi = require('@hapi/hapi');
const Crumb = require('@hapi/crumb');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });

  await server.register({
    plugin: Crumb,
    options: {}
  });

  server.route({
    path: '/login',
    method: 'GET',
    options: {
      plugins: {
        crumb: {}
      },
      handler(request, h) {
        return 'success'
      }
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

We register the plugin with the server.register method.

Then we add a /login route that sets the crumbn property to accept the crumb.

Crypto

We can create random strings to use with our Hapi app with the @hapi/cryptiles module.

For instance, we can write:

const Hapi = require('@hapi/hapi');
const cryptiles = require('@hapi/cryptiles');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });
  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return cryptiles.randomString(10)
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

to return a random string response.

We generate the random string with the length 10 with cryptiles.randomString(10) .

Also, we can generate an alphanumeric string with cryptiles.randomAlphanumString:

const Hapi = require('@hapi/hapi');
const cryptiles = require('@hapi/cryptiles');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });
  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return cryptiles.randomAlphanumString(10)
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

And we can generate a random number with cryptiles.randomDigits:

const Hapi = require('@hapi/hapi');
const cryptiles = require('@hapi/cryptiles');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });
  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return cryptiles.randomDigits(10)
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

Conclusion

We can parse the Content-Type and Content-Disposition header with the @hapi/content module.

And we can create random strings with the @hapi/cryptiles module.

Posted in Hapi