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

Azure Function Adapter: Cannot serve static image #87

Open
vaggelis-diatsigkos opened this issue Mar 3, 2023 · 2 comments
Open

Azure Function Adapter: Cannot serve static image #87

vaggelis-diatsigkos opened this issue Mar 3, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@vaggelis-diatsigkos
Copy link

Hello,

I was trying to serve a React SPA using NestJS + FastifyAdapter + Azure/HttpTriggerV4Adapter.

// main.ts
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { LazyFramework } from '@h4ad/serverless-adapter/lib/frameworks/lazy';
import { FastifyFramework } from '@h4ad/serverless-adapter/lib/frameworks/fastify';
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
import { AzureHandler } from '@h4ad/serverless-adapter/lib/handlers/azure';
import { PromiseResolver } from '@h4ad/serverless-adapter/lib/resolvers/promise';
import { AppModule } from './app/app.module';
import { HttpTriggerV4Adapter } from './temp/temp';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  await app.init();
  return app.getHttpAdapter().getInstance();
}

const fastifyFramework = new FastifyFramework();
const framework = new LazyFramework(fastifyFramework, bootstrap);

export const handler = ServerlessAdapter.new(null)
  .setFramework(framework)
  .setHandler(new AzureHandler({
    useContextLogWhenInternalLogger: false
  }))
  .setResolver(new PromiseResolver())
  .addAdapter(new HttpTriggerV4Adapter())
  .build();
// app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client', 'build')
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

While the index.html along with the .css and .js were served correctly, the images failed to load with the following errors:

  • http://localhost:7071/static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)
  • GET http://localhost:7071/favicon.ico net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)

I copied locally the azure/http-trigger-v4.adapter.ts in order to debug and I found that when the response content-type was image/... the body was base64 string.

If you convert the base64 body to Uint8Array then it works fine.
I added the following temporary change:

// azure/http-trigger-v4.adapter.ts
public getResponse({
        body,
        isBase64Encoded,
        statusCode,
        headers: originalHeaders,
    }: GetResponseAdapterProps<HttpRequest>): HttpResponseSimple {
        const headers = getFlattenedHeadersMap(originalHeaders, ',', true);
        const cookies = this.getAzureCookiesFromHeaders(originalHeaders);

        if (headers['set-cookie']) delete headers['set-cookie'];

        let test: any = body;
        if (headers['content-type'].startsWith('image')) {
            test = Uint8Array.from(atob(body), c => c.charCodeAt(0));
        }

        return {
            body: test,
            statusCode,
            headers,

            // I tried to understand this property with
            // https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/content-negotiation
            // but I don't know if it's worth implementing this guy as an option
            // I found out when this guy is set to true and the framework sets content-type, azure returns 500
            // So I'll leave it as is and hope no one has any problems.
            enableContentNegotiation: false,
            cookies,
        };
    }

It would be nice if there was a fix not only for images but also for other binary types.

@vaggelis-diatsigkos vaggelis-diatsigkos added the bug Something isn't working label Mar 3, 2023
@H4ad
Copy link
Owner

H4ad commented Mar 4, 2023

Hey, thanks for opening an issue, really strange that azure only accepts UIntArray instead of accepting buffer, but is nice that you could find a solution by yourself and implement it easily, that's the goal of this library.

When I have time, I will investigate this issue and probably implement your fix since it works for you, I just need to make sure that is not a particularity of Fastify.

@vaggelis-diatsigkos
Copy link
Author

Hey, thanks for opening an issue, really strange that azure only accepts UIntArray instead of accepting buffer, but is nice that you could find a solution by yourself and implement it easily, that's the goal of this library.

When I have time, I will investigate this issue and probably implement your fix since it works for you, I just need to make sure that is not a particularity of Fastify.

Take us must time as needed. Anyway really good abstraction library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants