Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sitecore-jss-proxy] [#CS0195052] changes to HEAD request handling #487

Merged
merged 4 commits into from
Nov 5, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 33 additions & 9 deletions packages/sitecore-jss-proxy/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IncomingMessage, ServerResponse } from 'http';
import { IncomingMessage, ServerResponse, ClientRequest } from 'http';
import proxy from 'http-proxy-middleware';
import HttpStatus from 'http-status-codes';
import setCookieParser from 'set-cookie-parser';
Expand Down Expand Up @@ -88,10 +88,7 @@ async function renderAppToResponse(
return true;
};

if (request.method === 'HEAD') {
completeProxyResponse(null, proxyResponse.statusCode || HttpStatus.OK)
return
}


async function extractLayoutServiceDataFromProxyResponse(): Promise<any> {
if (proxyResponse.statusCode === HttpStatus.OK || proxyResponse.statusCode === HttpStatus.NOT_FOUND) {
Expand Down Expand Up @@ -169,11 +166,19 @@ async function renderAppToResponse(
}

// we have to convert back to a buffer so that we can get the *byte count* (rather than character count) of the body
const content = Buffer.from(result.html);
let content = Buffer.from(result.html);

// setting the content-length header is not absolutely necessary, but is recommended
proxyResponse.headers['content-length'] = content.length.toString(10);

// if original request was a HEAD, we should not return a response body
if (request.method === 'HEAD') {
if (config.debug) {
console.log('DEBUG: Original request method was HEAD, clearing response body');
}
content = Buffer.from([]);
}

if (result.redirect) {
if (!result.status) {
result.status = 302;
Expand Down Expand Up @@ -381,7 +386,7 @@ function isUrlIgnored(originalUrl: string, config: ProxyConfig, noDebug: boolean
);

if (!noDebug && config.debug) {
if (result) {
if (!result) {
console.log(
`DEBUG: URL ${originalUrl} did not match the proxy exclude list, and will be treated as a layout service route to render. Excludes:`,
config.pathRewriteExcludeRoutes
Expand All @@ -401,7 +406,7 @@ function isUrlIgnored(originalUrl: string, config: ProxyConfig, noDebug: boolean
result = config.pathRewriteExcludePredicate(originalUrl);

if (!noDebug && config.debug) {
if (result) {
if (!result) {
console.log(
`DEBUG: URL ${originalUrl} did not match the proxy exclude function, and will be treated as a layout service route to render.`
);
Expand All @@ -418,6 +423,23 @@ function isUrlIgnored(originalUrl: string, config: ProxyConfig, noDebug: boolean
return false;
}

function handleProxyRequest(proxyReq: any, req: any, res: ServerResponse, config: ProxyConfig,
customOnProxyReq: ((proxyReq: ClientRequest, req: IncomingMessage, res: ServerResponse) => void) | undefined) {

// if a HEAD request, we still need to issue a GET so we can return accurate headers
// proxyReq defined as 'any' to allow us to mutate this
if (proxyReq.method === 'HEAD' && !isUrlIgnored(req.originalUrl, config, true)) {
if (config.debug) {
console.log('DEBUG: Rewriting HEAD request to GET to create accurate headers');
}
proxyReq.method = 'GET';
}
// invoke custom onProxyReq
if (customOnProxyReq) {
customOnProxyReq(proxyReq, req, res);
}
}

function createOptions(
renderer: AppRenderer,
config: ProxyConfig,
Expand All @@ -438,14 +460,16 @@ function createOptions(
console.log('DEBUG: Final proxy config', config);
}

const customOnProxyReq = config.proxyOptions?.onProxyReq;
return {
...config.proxyOptions,
target: config.apiHost,
changeOrigin: true, // required otherwise need to include CORS headers
ws: true,
pathRewrite: (reqPath, req) => rewriteRequestPath(reqPath, req, config, parseRouteUrl),
logLevel: config.debug ? 'debug' : 'info',
onProxyReq: (proxyReq, req, res) => handleProxyRequest(proxyReq, req, res, config, customOnProxyReq),
onProxyRes: (proxyRes, req, res) => handleProxyResponse(proxyRes, req, res, renderer, config),
...config.proxyOptions,
};
}

Expand Down