skip to Main Content

I’m trying to work with the eBay APIs. It’s a small personal project that just needs to run locally, and although I know C#, I’m much more comfortable with Javascript so I’m looking for ways to get this done in JS.

I found this promising looking eBay Node API with browser support. Browser support is something I’m looking for, but it also says that

A Proxy server is required to use the API in the Browser.

They give an example file for a proxy server that is a Cloudflare worker.

I’m trying to translate that into something I can run in Node locally using the basic Node HTTP server. I’ve been following through it and am doing OK so far, figured out the different ways to access the headers and check them, etc., but now I’m at the point where the proxy server is making the proxy request to the eBay APIs. The way the example file is set up, it seems as though the Cloudflare worker intercepts the HTTP request and by default treats it as a Fetch Request. So then when it goes to pass on the request, it just kind of clones it (but is replacing the headers with "cleaned" headers):

// "recHeaders" is an object that is _most_ of the original
// request headers, with a few cleaned out, and "fetchUrl"
// is the true intended URL to query at eBay

const newReq = new Request(event.request, {
    "headers": recHeaders
});

const response = await fetch(encodeURI(fetchUrl), newReq);

The problem is that I don’t have a Fetch Request to clone – since I’m running a Node HTTP server, what is event.request in the example code is for me a http.IncomingMessage.

So how can I turn that into a Fetch Request? I’m guessing at the very least there’s stuff in the message body that needs to get passed along, if not other properties I’m not even aware of…

I don’t mind doing the work, i.e. reading the stream to pull out the body, and then putting that into the Request object somehow (or do I even need to do that? Can I just pipe the stream from the IncomingMessage directly into a Request somehow?), but what else besides the body do I need to make sure I get from the IncomingMessage to put into the Request?

How do I turn a Node http.IncomingMessage into a Fetch Request and be sure to include all relevant parts?

2

Answers


  1. I’ve made a simple function to convert.

    const convertIncomingMessageToRequest = (req: ExpressRequest): Request => {
      var headers = new Headers();
      for (var key in req.headers) {
        if (req.headers[key]) headers.append(key, req.headers[key] as string);
      }
      let request = new Request(req.url, {
        method: req.method,
        body: req.method === 'POST' ? req.body : null,
        headers,
      })
      return request
    }
    
    Login or Signup to reply.
  2. /**
     * Take a nodejs http IncomingMessage and convert it to an web standard Fetch API Request object
     */
    async function incoming_message_to_request(req: IncomingMessage, url: URL): Promise<Request> {
        const headers = new Headers();
        for (const [key, value] of Object.entries(req.headers)) {
            if (Array.isArray(value)) {
                value.forEach((v) => headers.append(key, v));
            } else if (value !== undefined) {
                headers.set(key, value);
            }
        }
        // Convert body to Buffer if applicable
        const body = req.method !== 'GET' && req.method !== 'HEAD' ? await get_request_body(req) : null;
        return new Request(url, {
            method: req.method,
            headers: headers,
            body: body,
        });
    }
    
    function get_request_body(req: IncomingMessage): Promise<Buffer> {
        return new Promise<Buffer>((resolve, reject) => {
            const chunks: Buffer[] = [];
            req.on('data', (chunk: Buffer) => {
                chunks.push(chunk);
            });
            req.on('end', () => {
                resolve(Buffer.concat(chunks));
            });
            req.on('error', (err) => {
                reject(err);
            });
        });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search