Skip to content

Commit

Permalink
feat(graphql): serve a favicon from GraphQL HTTP
Browse files Browse the repository at this point in the history
  • Loading branch information
calebmer committed Oct 9, 2016
1 parent da3acef commit 44692bb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
Binary file added resources/favicon.ico
Binary file not shown.
19 changes: 19 additions & 0 deletions src/graphql/http/__tests__/createGraphqlHTTPRequestHandler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,5 +336,24 @@ for (const [name, createServer] of serverCreators) {
.expect({ data: { greetings: 'Hello, Joe!' } })
)
})

test('will serve a favicon', async () => {
const server1 = createServer()
const server2 = createServer({ route: '/graphql' })
await (
request(server1)
.get('/favicon.ico')
.expect(200)
.expect('Cache-Control', 'public, max-age=86400')
.expect('Content-Type', 'image/x-icon')
)
await (
request(server2)
.get('/favicon.ico')
.expect(200)
.expect('Cache-Control', 'public, max-age=86400')
.expect('Content-Type', 'image/x-icon')
)
})
})
}
28 changes: 28 additions & 0 deletions src/graphql/http/createGraphqlHTTPRequestHandler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { resolve as resolvePath } from 'path'
import { readFile } from 'fs'
import { parse as parseQueryString } from 'querystring'
import { IncomingMessage, ServerResponse } from 'http'
const httpError = require('http-errors')
Expand All @@ -16,6 +17,13 @@ import {
import { Inventory } from '../../interface'
import createGraphqlSchema from '../schema/createGraphqlSchema'

const favicon = new Promise((resolve, reject) => {
readFile(resolvePath(__dirname, '../../../resources/favicon.ico'), (error, data) => {
if (error) reject(error)
else resolve(data)
})
})

// TODO: test `express`
// TODO: test `connect`
// TODO: test `koa`
Expand Down Expand Up @@ -53,6 +61,26 @@ export default function createGraphqlHTTPRequestHandler (inventory, options = {}
* @param {ServerResponse} res
*/
const requestHandler = async (req, res, next) => {
// If this is the favicon path and it has not yet been handled, let us
// serve our GraphQL favicon.
if (parseUrl(req).pathname === '/favicon.ico') {
// If this is the wrong method, we should let the client know.
if (!(req.method === 'GET' || req.method === 'HEAD')) {
res.statusCode = req.method === 'OPTIONS' ? 200 : 405
res.setHeader('Allow', 'GET, HEAD, OPTIONS')
res.end()
return
}

// Otherwise we are good and should pipe the favicon to the browser.
res.statusCode = 200
res.setHeader('Cache-Control', 'public, max-age=86400')
res.setHeader('Content-Type', 'image/x-icon')
res.end(await favicon)

return
}

// Don’t handle any requests if this is not the correct route.
if (parseUrl(req).pathname !== (options.route || '/'))
return next()
Expand Down

0 comments on commit 44692bb

Please sign in to comment.